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

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  
#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 
    #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))