1.由于tableView 头部视图和尾部视图出现一块留白问题
有两种办法去掉留白:
1)tableView
的style:UITableViewStyleGrouped
类型,默认tableView
开头和结尾是有间距的,不需要这个间距的话,可以通过实现heightForHeaderInSection
方法(返回一个较小值:0.1)和viewForHeaderInSection
(返回一个view)来去除头部的留白,底部同理。
2)iOS 11上发生tableView
顶部有留白,原因是代码中只实现了heightForHeaderInSection
方法,而没有实现viewForHeaderInSection
方法。iOS 11之后应该是由于开启了估算行高机制引起了bug。添加上viewForHeaderInSection
方法后,问题就解决了。或者添加以下代码关闭估算行高,问题也得到解决。
可以在使用tableView的地方添上下面的代码。
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
在我们的项目中由于项目工程量比较大,所以我们为了偷懒,给TableView写了一个分类:
#import "UITableView+YCEstimatedRowHeight.h"
#import <objc/runtime.h>
@implementation UITableView (YCEstimatedRowHeight)
+ (void)load {
// 编译时判断SDK
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL selectors[] = {
@selector(initWithFrame:style:),
};
for (NSUInteger index = 0; index < sizeof(selectors) / sizeof(SEL); ++index) {
SEL originalSelector = selectors[index];
SEL swizzledSelector = NSSelectorFromString([@"yc_" stringByAppendingString:NSStringFromSelector(originalSelector)]);
Method originalMethod = class_getInstanceMethod(self, originalSelector);
Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
BOOL addedSuccess = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (addedSuccess) {
class_replaceMethod(self, swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
});
#endif
}
- (instancetype)yc_initWithFrame:(CGRect)frame style:(UITableViewStyle)style {
if ([self yc_initWithFrame:frame style:style]) {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
self.estimatedRowHeight = 0;
self.estimatedSectionFooterHeight = 0;
self.estimatedSectionHeaderHeight = 0;
#endif
if (iPhoneX) { // 加这句话的目的是防止在iphoneX上,底部的那条黑线挡住内容
self.contentInset = UIEdgeInsetsMake(0, 0, 20, 0);
}
}
return self;
}
2.修改ios11上automaticallyAdjustsScrollViewInsets失效的问题
ios11给UIScrollView加了一个新的属性 contentInsetAdjustmentBehavior ,可以通过设置这个属性值来解决。下面这种方式比较粗暴,因为对于有的页面不需要 automaticallyAdjustsScrollViewInsets 设置这个属性,所以选择性使用。
#import "UIScrollView+YCContentInset.h"
#import <objc/runtime.h>
@implementation UIScrollView (YCContentInset)
+ (void)load {
// 编译时判断SDK
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL selectors[] = {
@selector(initWithFrame:),
};
for (NSUInteger index = 0; index < sizeof(selectors) / sizeof(SEL); ++index) {
SEL originalSelector = selectors[index];
SEL swizzledSelector = NSSelectorFromString([@"yc_" stringByAppendingString:NSStringFromSelector(originalSelector)]);
Method originalMethod = class_getInstanceMethod(self, originalSelector);
Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
BOOL addedSuccess = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (addedSuccess) {
class_replaceMethod(self, swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
});
#endif
}
- (instancetype)yc_initWithFrame:(CGRect)frame {
if ([self yc_initWithFrame:frame]) {
if (IOS11) {
self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
}
return self;
}