iOS 11下,UITableView的估算高度的属性,默认值从iOS11之前的 0.f 改变为UITableViewAutomaticDimension:(非0.f)。若tableView未使用estimated属性,tableView的组头和组尾视图高度则会显示异常。
修正这个错误的方式很简单,只需要在创建tableView后,设置其估算高度为0.f即可。
if(@available(iOS11.0,*)) {
tableView.estimatedRowHeight=0.f;
tableView.estimatedSectionHeaderHeight=0.f;
tableView.estimatedSectionFooterHeight=0.f;
}
为了解决项目内所有tableView或collectionView的该问题,可以使用比较简单的方法。
if (@available(iOS 11.0, *)) {
[UITableView appearance].estimatedRowHeight = 0;
[UITableView appearance].estimatedSectionHeaderHeight = 0;
[UITableView appearance].estimatedSectionFooterHeight = 0;
[[UIScrollView appearance]
setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
}
[UITableView appearance].estimatedSectionHeaderHeight = 0;
[UITableView appearance].estimatedSectionFooterHeight = 0;
另外,也可以使用runtime对tableview的初始方法进行hook,在创建完tableView后,统一为其设置estimated相关属性。代码如下。
@implementationUITableView (Extention)
+ (void)load {
staticdispatch_once_tonceToken;
dispatch_once(&onceToken, ^{
[HookUtility swizzlingInClass: [self class] originalSelector:@selector(initWithFrame:style:) swizzledSelector:@selector(swizz_initWithFrame:style:)];
});
}
- (__kindof UITableView*)swizz_initWithFrame:(CGRect)frame style:(UITableViewStyle)style {
__kindof UITableView * tableView = [self org_initWithFrame:framestyle:style];
if(@available(iOS11.0,*)) {
tableView.estimatedRowHeight=0.f;
tableView.estimatedSectionHeaderHeight=0.f;
tableView.estimatedSectionFooterHeight=0.f;
}
returntableView;
}
@end
其中,swizzlingInClass: originalSelector:swizzledSelector:方法的实现如下:
+ (void)swizzlingInClass:(Class)cls originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector {
Classclass = cls;
Method originalMethod =class_getInstanceMethod(class, originalSelector);
Method swizzledMethod =class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if(didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
如果需要设置iOS 11下scrollView的contentInsetAdjustmentBehavior属性值为UIScrollViewContentInsetAdjustmentNever的话,可以在设置估算高度的地方加上下面这行代码。
tableView.contentInsetAdjustmentBehavior=UIScrollViewContentInsetAdjustmentNeve;
不过这种hook的方式,在项目中还是尽量少用。