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某些情况下无法滚动的问题:
UIScrollView
的delaysContentTouches
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
解决方案如下:
目前使用YYKit
中YYReachability
来解决~~~
今天看到了这篇文章,里面的思路不错。使用了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
~~~