美文网首页
iOS11下调试发现的几个注意事项(Update)

iOS11下调试发现的几个注意事项(Update)

作者: Saylor_Lone | 来源:发表于2017-08-02 16:31 被阅读701次

    UITableView 布局,默认启用了预估值。

    /*
      iOS11下API的相关变化 Default
    */
    @property (nonatomic) CGFloat rowHeight;             // default is UITableViewAutomaticDimension
    @property (nonatomic) CGFloat sectionHeaderHeight;   // default is UITableViewAutomaticDimension
    @property (nonatomic) CGFloat sectionFooterHeight;   // default is UITableViewAutomaticDimension
    @property (nonatomic) CGFloat estimatedRowHeight NS_AVAILABLE_IOS(7_0); // default is UITableViewAutomaticDimension, set to 0 to disable
    @property (nonatomic) CGFloat estimatedSectionHeaderHeight NS_AVAILABLE_IOS(7_0); // default is UITableViewAutomaticDimension, set to 0 to disable
    @property (nonatomic) CGFloat estimatedSectionFooterHeight NS_AVAILABLE_IOS(7_0); // default is UITableViewAutomaticDimension, set to 0 to disable
    
    /*
    如果不注意的话,这一变化可能会引起以下代理方法不会得到执行。
    */
    - (CGFloat)tableView:(UITableView*)tableView heightForHeaderInSection:(NSInteger)section
    {
        return 0.0001;
    }
    
    - (CGFloat)tableView:(UITableView*)tableView heightForFooterInSection:(NSInteger)section
    {
        return 12;
    }
    
    /*
    解决方案:在UITableView 的构造方法中初始化以上参数为0
    eg:
    self.estimatedSectionHeaderHeight = 0.f;
    self.estimatedSectionFooterHeight = 0.f;
    */
    
    
    

    iOS11模拟器库文件的变化

    LDNetDiagnoService_IOS

    /*
    在调试一个网络测试工具时发现,在iOS11下会编译报错。原因是模拟器库文件中不再有net/route.h文件,分析这一变动可能还会涉及其他文件。
    */
    
    #if TARGET_IPHONE_SIMULATOR
    #include <net/route.h> 
    #else
    #include "Route.h"
    #endif /*the very same from google-code*/
    
    /*
    解决方案
    */
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
    //xcode baseSDK为11.0或者以上
    #include "Route.h"
    #else
        //xcode baseSDK为11.0以下的
        #if TARGET_IPHONE_SIMULATOR
        #include <net/route.h>
        #else
        #include "Route.h"
        #endif
    #endif
    
    

    UIScrollView 的相关属性变化

    *在之前布局时相信很多人遇到过,UIScrollView 的ContentOffset被系统进行了自动调整。
    iOS10以前的做法通常是设置,UIViewController的automaticallyAdjustsScrollViewInsets这一属性。
    重点来了!!!
    iOS11以后苹果提供了新的解决方案,将这一问题的处理移交给了UIScrollView。

    /* Configure the behavior of adjustedContentInset.
     Default is UIScrollViewContentInsetAdjustmentAutomatic.
     */
    @property(nonatomic) UIScrollViewContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior API_AVAILABLE(ios(11.0),tvos(11.0));
    
    
    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:这种需要处理警告
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored"-Wundeclared-selector"
            if ([self respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {
                [self performSelector:@selector(setContentInsetAdjustmentBehavior:) withObject:@2];
            }
    #pragma clang diagnostic pop
    
    ///解决方案2:
    #ifdef __IPHONE_11_0
            if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 11.0) { 
               self.contentInsetAdjustmentBehavior = @2;
           }
    #endif
    ///解决方案3:
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
            if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 11.0) { 
               self.contentInsetAdjustmentBehavior = @2;
           }
    #endif
    
    

    *关于UITableView某些情况下无法滚动的问题:

    UIScrollViewdelaysContentTouches
    UIScrollView有一个BOOL类型的tracking属性,用来返回用户是否已经触及内容并打算开始滚动
    当手指触摸到UIScrollView内容的一瞬间,会产生下面的动作:
    拦截触摸事件
    tracking属性变为YES
    一个内置的计时器开始生效,用来监控在极短的事件间隔内是否发生了手指移动
    case1:当检测到时间间隔内手指发生了移动,UIScrollView自己触发滚动,tracking属性变为NO,手指触摸下即使有(可以响应触摸事件的)内部控件也不会再响应触摸事件。
    case2:当检测到时间间隔内手指没有移动,tracking属性保持YES,手指触摸下如果有(可以响应触摸事件的)内部控件,则将触摸事件传递给控件进行处理。
    上面的工作原理其实有一个属性开关来控制:delaysContentTouches。默认值为YES;如果设置为NO,则无论手指移动的多么快,始终都会将触摸事件传递给内部控件;设置为NO可能会影响到UIScrollView的滚动功能。
    以上内容 引用来源

    这种影响在iOS10下看来是无害的,但在iOS11下就凸显出来了。

    判断网络状态的相关代码(iPhoneX相关)

    应该能够很轻易的搜索到如下代码
    NSArray *subviews = [[[[UIApplication sharedApplication] valueForKey:@"statusBar"] valueForKey:@"foregroundView"]subviews];
    但是很可惜,这样写会在iPhoneX上崩溃。
    代码摘自 LDNetDiagnoService_IOS
    解决方案如下:
    目前使用YYKitYYReachability来解决~~~

    今天看到了这篇文章,里面的思路不错。使用了Runtime 去查看状态栏的相关变化,之前在Xcode上看层级的方式太傻了...
    其解决方式为:

    // 因此可见iPhone X的状态栏是多嵌套了一层,多取一次即可,最终适配代码为:
    NSArray *children;
    // 不能用 [[self deviceVersion] isEqualToString:@"iPhone X"] 来判断,因为iPhone X 的模拟器不会返回 iPhone X
        if ([[application valueForKeyPath:@"_statusBar"] isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) {
            children = [[[[application valueForKeyPath:@"_statusBar"] valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
        } else {
            children = [[[application valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
        }
    

    但也许是我的打开方式不对,在iPhone X 上运行一直返回nil。依旧使用了YYReachability~~~

    相关文章

      网友评论

          本文标题:iOS11下调试发现的几个注意事项(Update)

          本文链接:https://www.haomeiwen.com/subject/cxhylxtx.html