前言:最近更新XCode9,出现了一些问题,写篇文章来记录一下,也方便大家排坑.
无奈(nao chou)就给(yao)了两天时间做适配,时间紧任务重,一些细节的小问题就不一一举例了
笔锋一转,进入主题。
目录 问题列表
1.XCode9添加资源文件不能获取路径问题
2.iOS11 系统导航栏上自定义view的显示问题
3.UITableView 出现的遮挡显示问题(三行代码解决,放到基类)
4.适配iPhoneX 屏幕原则
5.适配过程一些常量的设置
6.出现UIScrollview 漂移问题(基本都是iPhoneX上)
7.iPhone X 上运行有黑色区域问题
8.有些导致iPhoneX获取网络状态崩溃的问题
9.一些关于iPhone X底部的设计示范
10.关于iPhoneX的home条(HomeIndicator)的显隐
11.关于iOS11权限的变化
12.iOS11 UICollectionview 的scroll indicator等被组视图遮挡的问题
13.iOS11 无法弹出键盘问题
14.iOS11 数组语法糖🍬替换方法的改变
1. XCode9添加资源文件不能获取路径问题
XCode9调用[[NSBundle mainBundle] pathForResource:resourceNameofType:nil];方法来获取文件路径,返回为nil. 添加正确方式如下图1,
图1 添加资源选项
但是XCode9 却埋了一道坑,如下图2, 点击资源文件,找到文件选项
图2 资源文件选项
红框区域未默认勾选, 只要把这个复选框勾选即可解决. 具体原因是:xcode9 添加文件使用addfile 拖拽的文件不会自动添加到Compile Sources 和 Copy Bundle Resources 下.
这招太辣眼睛
2. iOS11 系统导航栏上自定义view的显示问题
之前代码设置导航栏:
self.navigationItem.titleView = customView;
会出现这样的问题,如下图3,
图3 导航栏出错
界面出乱的原因是因为iOS11调整了导航栏图层结构。快速简便的修改方式,直接上代码,
self.navigationItem.hidesBackButton = YES;
[self.navigationController.navigationBaraddSubview:YourCustomView];
但是需在控制器的dealloc里移除你的自定义view,
[YourCustomView removeFromSuperview];
下图4为修改好的自定义视图
图4
3. UITableView 出现的遮挡显示问题(三行代码解决,放到基类)
// iOS11适配
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
4. 适配iPhoneX 屏幕原则
图5 iphoneX 竖屏
图6 iPhoneX 横屏
设计原则:让那行可操作、不可阻挡的控件或视图显示在图5、图6的蓝色区域(安全区域safeArea)。
顶部危险区距离:44
底部危险区距离:34
5. 适配过程一些常量的设置
#define YYISiPhoneX [[UIScreen mainScreen] bounds].size.width >=375.0f && [[UIScreen mainScreen] bounds].size.height >=812.0f&& YYIS_IPHONE
#define YYIS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
//状态栏高度
#define kStatusBarHeight (CGFloat)(YYISiPhoneX?(44):(20))
// 导航栏高度
#define kNavBarHBelow7 (44)
// 状态栏和导航栏总高度
#define kNavBarHAbove7 (CGFloat)(YYISiPhoneX?(88):(64))
// TabBar高度
#define kTabBarHeight (CGFloat)(YYISiPhoneX?(49+34):(49))
// 顶部安全区域远离高度
#define kTopBarSafeHeight (CGFloat)(YYISiPhoneX?(44):(0))
// 底部安全区域远离高度
#define kBottomSafeHeight (CGFloat)(YYISiPhoneX?(34):(0))
// iPhoneX的状态栏高度差值
#define kTopBarDifHeight (CGFloat)(YYISiPhoneX?(24):(0))
整个服务器都在瑟瑟发抖
6. 出现UIScrollview 漂移问题(基本都是iPhoneX上)
若是UIScrollview的frame和contentSize高度或者宽度一致却还导致了漂移问题,可用以下一行代码搞定。
if(@available(iOS11,*)) {_scrollView.contentInsetAdjustmentBehavior=UIScrollViewContentInsetAdjustmentNever;}
同时,如果在push进入webview页面时,底部会有黑边一闪而过,也可用此方法解决。再加个同时,如果发现pop界面的时候tableview会出现下滑的漂移,也可用此方法解决。
若嫌麻烦,每个scrollview及其子类都要去设置的话,也可以使用以下方法
// AppDelegate 里进行全局设置
if(@available(iOS 11.0, *)){[[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
7. iPhone X 上运行有黑色区域问题
启动图问题,使用LaunchScreen来做启动图 或者 修改Assets中的LaunchImage,添加iPhoneX的Launch图1125*2436(px) 竖屏模式。
8.有些导致iPhoneX获取网络状态崩溃的问题
直接上代码,无需通过KVC得到图层名获取网络状态,一劳永逸!(因还不熟悉markdown语法,以下代码需自行缩进
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
+ (NSString *)getNetWorkInfo {
NSString *strNetworkInfo = @"No Network";
struct sockaddr_storage zeroAddress;
bzero(&zeroAddress,sizeof(zeroAddress));
zeroAddress.ss_len = sizeof(zeroAddress);
zeroAddress.ss_family = AF_INET;
// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL,(struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFlags flags;
//获得连接的标志
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability,&flags);
CFRelease(defaultRouteReachability);
//如果不能获取连接标志,则不能连接网络,直接返回
if(!didRetrieveFlags){ return strNetworkInfo;} BOOL isReachable = ((flags & kSCNetworkFlagsReachable)!=0); BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired)!=0); if(!isReachable || needsConnection) {return strNetworkInfo;}// 网络类型判断
if((flags & kSCNetworkReachabilityFlagsConnectionRequired)== 0){strNetworkInfo = @"WIFI";}
if(((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0) { if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0){strNetworkInfo = @"WIFI";}}
if ((flags & kSCNetworkReachabilityFlagsIsWWAN) ==kSCNetworkReachabilityFlagsIsWWAN) {if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {CTTelephonyNetworkInfo * info = [[CTTelephonyNetworkInfo alloc] init];NSString *currentRadioAccessTechnology = info.currentRadioAccessTechnology;if (currentRadioAccessTechnology) {if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {strNetworkInfo = @"4G";} else if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge] || [currentRadioAccessTechnologyisEqualToString:CTRadioAccessTechnologyGPRS]) {strNetworkInfo = @"2G";} else {strNetworkInfo = @"3G";}}} else {if((flags & kSCNetworkReachabilityFlagsReachable) == kSCNetworkReachabilityFlagsReachable) {if ((flags & kSCNetworkReachabilityFlagsTransientConnection) == kSCNetworkReachabilityFlagsTransientConnection) {if((flags & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired) {strNetworkInfo = @"2G";} else {strNetworkInfo = @"3G";}}}}}
// if ([strNetworkInfo isEqualToString: @"No Network"]) {strNetworkInfo = @"WWAN";}
return strNetworkInfo;
}
9.一些关于iPhone X底部的设计示范
示范图一
示范图二
示范图三
10. 关于iPhoneX的home条(HomeIndicator)的显隐
先看下图7,
图7 横屏看撩妹视频时
这样的体验其实是不好的(还怎么用英文撩妹?),所以为了以防这样的问题出现,苹果其实提供了隐藏HomeIndicator的方法,如下,
- (BOOL)prefersHomeIndicatorAutoHidden {
return YES;
}
在VC 里边重写 prefersHomeIndicatorAutoHidden 返回 YES(默认是NO),Home指示条就能自动隐藏了,此方法是在控制器push之后就会回调,屏幕若无交互事件响应时,延迟2秒左右会自动隐藏。
11. 关于iOS11权限的变化
1.定位问题:无法定位,第一次使用时没有弹出定位请求对话框。
原因:由于iOS11的定位权限的key做了更改,在以前iOS11之前的始终允许定位NSLocationAlwaysUsageDescription基础上添加NSLocationWhenInUseUsageDescription和NSLocationAlwaysAndWhenInUsageDescription。具体参考博客:http://blog.csdn.net/dangyalingengjia/article/details/77965029
2.相册权限问题:iOS11上读写相册的照片时发生崩溃。
原因:由于iOS11相册相关权限的key发生了变化。用户在没有权限的情况下,访问相册导致崩溃。
iOS11之前对应的key是NSPhotoLibraryUsageDescription,而iOS11的Key变为NSPhotoLibraryAddUsageDescription。同定位的Key一样,由于key没有兼容性,所以需要保留原key以兼容iOS11之前的版本。
12. iOS11 UICollectionview 的scroll indicator等被组视图遮挡的问题
问题如下图8红框区域,
图8 UICollectionview bug图
导致这个的原因是因为组视图的z坐标出现了问题, 有以下两种解决办法
第一种: 在该类中重写layoutSubviews方法<适用于小规模>
- (void)layoutSubviews {
[super layoutSubviews];
self.layer.zPosition = 0;
}
第二种: 自定义一个layer, 重写其zPosition的get方法。然后对组视图类添加分类方法,重写layerClass方法即可。
自定义layer:
@implementation YYZPositionZeroLayer
- (CGFloat)zPosition {
return 0;
}
@end
添加分类重写组视图layerClass方法:
@implementationUICollectionReusableView (ZPositionZero)
+ (Class)layerClass {
return[YYZPositionZeroLayer class];
}
@end
13. iOS11 无法弹出键盘问题
问题描述: 在某些时候你会发现调用becomeFirstResponder方法时,并未响应键盘,系统键盘无法弹出.
问题发现: 如果在调用之前使用了UIAlertView弹出对话框,就会导致系统键盘无法弹出,猜测是因为UIAlertView在消失遍历window窗口时存在windowLevel 大于 levelNormal 的window把他作为keywindow
问题解决: 如果你的项目里面还在使用UIAlertView(2_0,9_0), 建议用UIAlertController替换掉.
14.iOS11 数组语法糖🍬替换方法的改变
在iOS11 之前,
array[i] 语法糖的替换方法是[array objectAtIndex:i]
在iOS11 之后,
array[i] 语法糖的替换方法是[array objectAtIndexedSubscript:i]
用到动态交换方法的童鞋需要注意了.









网友评论
11.2 解析有问题,原文:
NSPhotoLibraryAddUsageDescription
NSPhotoLibraryAddUsageDescription (String - iOS) This key lets you describe the reason your app seeks write-only access to the user’s photo library. When the system prompts the user to allow access, this string is displayed as part of the alert.
Important: To protect user privacy, an iOS app linked on or after iOS 10.0, and that accesses the user’s photo library, must statically declare the intent to do so. Include the NSPhotoLibraryAddUsageDescription key (in apps that link on or after iOS 11) or NSPhotoLibraryUsageDescription key in your app’s Info.plist file and provide a purpose string for the key. If your app attempts to access the user’s photo library without a corresponding purpose string, your app exits.
This key is supported in iOS 11.0 and later.
NSPhotoLibraryUsageDescription
NSPhotoLibraryUsageDescription (String - iOS) This key lets you describe the reason your app accesses the user’s photo library. When the system prompts the user to allow access, this string is displayed as part of the alert.
Although this keys governs read and write access to the user’s photo library, it’s best to use NSPhotoLibraryAddUsageDescription if your app needs only to add assets to the library and does not need to read any assets.
Important: To protect user privacy, an iOS app linked on or after iOS 10.0, and that accesses the user’s photo library, must statically declare the intent to do so. Include the NSPhotoLibraryUsageDescription key in your app’s Info.plist file and provide a purpose string for this key. If your app attempts to access the user’s photo library without a corresponding purpose string, your app exits.
This key is supported in iOS 6.0 and later.