关于ios11和iphoneX ScrollView的适配

1.由于tableView 头部视图和尾部视图出现一块留白问题

有两种办法去掉留白:

1)tableViewstyle: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 

@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 

@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;
}

你可能感兴趣的:(关于ios11和iphoneX ScrollView的适配)