iOS11 UITableView顶部多出一片空白区域

苹果向来都是出个bug让开发者填坑,这不弄了个iPhone X的异形屏幕,既要考虑顶部的齐刘海,又要考虑底部的home条。现在不光是iPhone X的屏幕问题,iOS 11的SDK也有好多改变,其中影响最大的莫过于UITableView的改动。

很多开发者发现了,用iOS 11的SDK运行程序后tableView变得自己都不认识了。

首先是在iOS 11中,tableView关于footer的两个代理方法必须成对出现,不然就会有问题。这里以footer为例,header同理。

1
2
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section

这两个方法只要出现一个,另一个就必须写上。不然footer的高度就无法控制了。。

其次,很多人发现自己的tableView下移了64个像素。

在iOS11之前,如果想要scrollView不偏移64p,则需设置automaticallyAdjustsScrollViewInsets=NO,但是这个属性在iOS11直接被遗弃了。。

多出了一个新属性contentInsetAdjustmentBehavior,类型是UIScrollViewContentInsetAdjustmentBehavior。看起来这和iOS11搞的safeArea有关,这个先放一边,看看怎么适配(一种简单方案):

1
2
3
4
5
6
if (@available(iOS 11.0, *)) {
tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
// Fallback on earlier versions
self.automaticallyAdjustsScrollViewInsets = NO;
}

我们来看一下这个新的属性:

1
2
3
4
5
6
typedef NS_ENUM(NSInteger, UIScrollViewContentInsetAdjustmentBehavior) {
UIScrollViewContentInsetAdjustmentAutomatic, // Similar to .scrollableAxes, but will also adjust the top & bottom contentInset when the scroll view is owned by a view controller with automaticallyAdjustsScrollViewContentInset = YES inside a navigation controller, regardless of whether the scroll view is scrollable
UIScrollViewContentInsetAdjustmentScrollableAxes, // Edges for scrollable axes are adjusted (i.e., contentSize.width/height > frame.size.width/height or alwaysBounceHorizontal/Vertical = YES)
UIScrollViewContentInsetAdjustmentNever, // contentInset is not adjusted
UIScrollViewContentInsetAdjustmentAlways, // contentInset is always adjusted by the scroll view's safeAreaInsets
} API_AVAILABLE(ios(11.0),tvos(11.0));

关于这个属性我会在另一篇文章中详细解释一下。

下面是一种大神的解决方案,是从网上找的:

1
2
3
4
5
6
7
8
9
10
11
#define  adjustsScrollViewInsets_NO(scrollView,vc)\
do { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \
if ([UIScrollView instancesRespondToSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:")]) {\
[scrollView performSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:") withObject:@(2)];\
} else {\
vc.automaticallyAdjustsScrollViewInsets = NO;\
}\
_Pragma("clang diagnostic pop") \
} while (0)

这种方法是利用了宏定义。但是在iOS 11的SDK中,我发现有的时候宏定义或者全局变量的值并不是我所期望的值,使用NSLog打印的值跟通过计算后得到的值匹配不上。我不确定这是Xcode9的bug还是其他什么原因,特别是计算frame的时候,明明单独打印这几个宏定义的值都对,但是把这几个宏定义进行计算,得到的结果却是错误的。。如果有人遇到了同样的问题,麻烦私信我一下。。一起探讨探讨。

最后希望所有的产品经理都紧跟苹果步伐。抛弃旧的系统。。

文章目录
|