目录 问题列表html
1.适配iPhoneX 屏幕原则web
2.适配过程一些常量的设置json
3..iPhone X 上运行有黑色区域问题数组
4.iOS11导航栏适配 xcode
5.出现UIScrollview 漂移问题(基本都是iPhoneX上)安全
6.UITableView 出现的遮挡显示问题(三行代码解决,放到基类)bash
7.iOS11 UICollectionview 的scroll indicator等被组视图遮挡的问题markdown
8.一些关于iPhone X底部的设计示范网络
9.关于iPhoneX的home条(HomeIndicator)的显隐app
10.有些致使iPhoneX获取网络状态崩溃的问题
11.关于iOS11权限的变化
12.XCode9添加资源文件不能获取路径问题
13.iOS11 没法弹出键盘问题
14.iOS11 数组语法糖🍬替换方法的改变
设计原则:让那行可操做、不可阻挡的控件或视图显示在图五、图6的蓝色区域(安全区域safeArea)。
顶部危险区距离:44
底部危险区距离:34
#define IS_iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO) //状态栏高度 #define kStatusBarHeight (CGFloat)(IS_iPhoneX?(44):(20)) // iPhoneX的状态栏高度差值 #define kTopBarDifHeight (CGFloat)(IS_iPhoneX?(24):(0)) // 顶部安全区域远离高度 #define kTopBarSafeHeight (CGFloat)(IS_iPhoneX?(44):(0)) // 状态栏和导航栏总高度 #define kNavBarHAbove (CGFloat)(IS_iPhoneX?(88):(64)) // TabBar高度 #define kTabBarHeight (CGFloat)(IS_iPhoneX?(49+34):(49)) // 底部安全区域远离高度 #define kBottomSafeHeight (CGFloat)(IS_iPhoneX?(34):(0))
启动图问题,使用LaunchScreen来作启动图 或者 修改Assets中的LaunchImage,添加iPhoneX的Launch图1125*2436(px) 竖屏模式。
.
经过LaunchScreen.storyboard方式启动
若是使用的是Assets中的LaunchImage, 在增长了iPhone X尺寸的图片配置后.
LaunchScreen.storyboard方式不用多说, 这里说一下如何在LaunchImage中增长iPhone X尺寸的图片配置.
方法一:
准备一张尺寸:1125 * 2436的 3x启动图片, 移动到LaunchImage的Finder目录中, 并在LaunchImage中的Contents.json文件中增长 (注意Json格式):
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "2436h",
"filename" : "图片名.png",
"minimum-system-version" : "11.0",
"orientation" : "portrait",
"scale" : "3x"
}
方法二:
因为iPhone X高度发生变化,图片铺满整个屏幕时候形成图片拉伸,如今须要UI切一个1125*2436的3x图片和之前作iPhone X机型判断1124*2001图片,而且对图片contentMode属性进行设置
if (IS_iPhoneX) {
coverImageNames = [NSArray arrayWithObjects:@"img_big_1_ipx.jpg", @"img_big_2_ipx.jpg",@"img_big_3_ipx.jpg", @"img_big_4_ipx.jpg",nil];
}else{
coverImageNames = [NSArray arrayWithObjects:@"img_big_1.jpg", @"img_big_2.jpg",@"img_big_3.jpg", @"img_big_4.jpg",nil];
}
imageView.clipsToBounds = YES;//超出区域裁剪
imageView.contentMode = UIViewContentModeScaleAspectFill;//图片等比例拉伸,会填充整个区域,可是会有一部分过大而超出整个区域
4.1在解释导航栏变化以前先解释一个iOS 11的新特性:设置大标题,经过BOOL类型的prefersLargeTitles属性来设置。默认设置是不开启
//显示大标题“设置” self.navigationController.navigationBar.prefersLargeTitles = YES; self.navigationItem.title = @"设置"; //经过navigationItem的largeTitleDisplayMode属性来设置: self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAutomatic; //其中LargeTitle还有三种样式能够选择: UINavigationItemLargeTitleDisplayModeNever//老是显示小标题 UINavigationItemLargeTitleDisplayModeAlways//老是显示大标题 UINavigationItemLargeTitleDisplayModeAutomatic//自动显示大标题或小标题。即初始时是大标题,滑动时大标题隐藏、显示小标题。
4.2. iOS11 系统导航栏上自定义view的显示问题
以前代码设置导航栏:
self.navigationItem.titleView = customView;
会出现这样的问题,以下图3,
界面出乱的缘由是由于iOS11调整了导航栏图层结构。快速简便的修改方式,直接上代码,
self.navigationItem.hidesBackButton = YES;
[self.navigationController.navigationBaraddSubview:YourCustomView];
可是需在控制器的dealloc里移除你的自定义view,
[YourCustomView removeFromSuperview];
下图4为修改好的自定义视图
(1)在iPhone X中导航栏高度变成88,项目中自定义导航栏高度64,须要对导航栏高度进行判断
_navigationBar = [[MCCustomNavigationBar alloc]initWithFrame:CGRectMake(0, 0, SCREENW, 64) andType:CustomBarType_Home];
_navigationBar = [[MCCustomNavigationBar alloc]initWithFrame:CGRectMake(0, 0, SCREENW, kStatusBarAndNavigationBarHeight) andType:CustomBarType_Home];
(2)搜索框和左右两边按钮高度有问题,由于iPhone X中状态栏高度由20增长24变成44,因此搜索框和左右两边按钮高度在iPhone X上距顶部高度加上24高度,
#define itemTopOffset (IS_iPhoneX ? (26+24) : 26)
[self.leftBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.offset(itemHorOffset);
make.height.equalTo(@(itemHeight));
make.width.equalTo(@(itemHeight));
make.top.offset(itemTopOffset);
}];
(3)iOS11上searchBar高度明显变大,
系统的searchBar
UISearchBar的中子控件及其布局
UIView(直接子控件) frame 等于 searchBar的bounds,view的子控件及其布局
UISearchBarBackground(间接子控件) frame 等于searchBar的bounds
UISearchBarTextField(间接子控件) frame.origin等于(8.0, 6.0),即不等于searchBar的bounds
改变searchBar的frame只会影响其中搜索框的宽度,不会影响其高度,缘由以下:
系统searchBar中的UISearchBarTextField的高度默认固定为28
左右边距固定为8,上下边距是父控件view的高度减去28除以2
改变UISearchBar的高度
方案
重写UISearchBar的子类(MCSearchBar),从新布局UISearchBar子控件的布局
增长成员属性contentInset,控制UISearchBarTextField距离父控件的边距
若用户没有设置contentInset,则计算出默认的contentInset
若用户设置了contentInset,则根据最新的contentInset布局UISearchBarTextField
新建UISearchBar的子类,增长成员属性contentInset,用来调整UISearchBarTextField距离父控件的边距。contentInset的setter方法
#pragma mark - setter method
- (void)setContentInset:(UIEdgeInsets)contentInset {
_contentInset.top = contentInset.top;
_contentInset.bottom = contentInset.bottom;
_contentInset.left = contentInset.left;
_contentInset.right = contentInset.right;
self.isChangeFrame = YES;
[self layoutSubviews];
}
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subView in self.subviews[0].subviews) {
if ([subView isKindOfClass:[UIImageView class]]) {
//移除UISearchBarBackground
[subView removeFromSuperview];
}
if ([subView isKindOfClass:[UITextField class]]) {
CGFloat height = self.bounds.size.height;
CGFloat width = self.bounds.size.width;
if (_isChangeFrame) {
//说明contentInset已经被赋值
// 根据contentInset改变UISearchBarTextField的布局
subView.frame = CGRectMake(_contentInset.left, _contentInset.top, width - 2 * _contentInset.left, height - 2 * _contentInset.top);
} else {
// contentSet未被赋值
// 设置UISearchBar中UISearchBarTextField的默认边距
CGFloat top = (height - 28.0) / 2.0;
CGFloat bottom = top;
CGFloat left = 8.0;
CGFloat right = left;
_contentInset = UIEdgeInsetsMake(top, left, bottom, right);
subView.frame = CGRectMake(_contentInset.left, _contentInset.top, width - 2 * _contentInset.left, height - 2 * _contentInset.top);
}
}
}
}
在项目中使用自定义的MCSearchBar,SearchBar的高度能够改变
(4)iOS11中UISearchBar没有居中居左显示,而且icon和placeholder间距太窄
如今实现居中显示
@property(nonatomic,assign)CGFloatwidth;
//判断版本
if(@available(iOS11.0, *)){
UITextField *textField = [self.searchBar valueForKey:@"searchField"];
[textField sizeToFit];
//记录一下这个时候的宽度
_width= textField.frame.size.width;
[_searchBar setPositionAdjustment:UIOffsetMake((_searchBar.width-_width)/2.0,0)forSearchBarIcon:UISearchBarIconSearch];
}
而后在代理方法 searchBarTextDidBeginEditing:(UISearchBar*)searchBar 调整位置
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
if (@available(iOS 11.0, *)) {
if(!_searchBar.text.length) {
[_searchBar setPositionAdjustment:UIOffsetMake(0,0)forSearchBarIcon:UISearchBarIconSearch];
}
}
}
结束的方法 searchBarTextDidEndEditing:(UISearchBar*)searchBar 判断是否有内容
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{
if (@available(iOS 11.0, *)) {
if(!_searchBar.text.length) {
[_searchBar setPositionAdjustment:UIOffsetMake((_searchBar.width-self.width)/2.0,0) forSearchBarIcon:UISearchBarIconSearch];
}
}
}
若是有占位文字后台返的,UITextField在搜索框默认文字大小17,能够根据文字个数和大小算出占位文字宽度,而后算出搜索图标的偏移量.
(5)搜索页面导航栏中搜索框距离返回按钮太近
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, testView.width - (SCREENW > 320 ? 90: 100)*SCREEN_Proportion, testView.height)];
因为搜索框距离左边距离致使的,如今须要定义一个宏作判断
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(marginLeft, 0, testView.width - (SCREENW > 320 ? 90: 100)*SCREEN_Proportion, testView.height)];
如果UIScrollview的frame和contentSize高度或者宽度一致却还致使了漂移问题,可用如下一行代码搞定。
if(@available(iOS11,*)) {_scrollView.contentInsetAdjustmentBehavior=UIScrollViewContentInsetAdjustmentNever;}
同时,若是在push进入webview页面时,底部会有黑边一闪而过,也可用此方法解决。
若嫌麻烦,每一个scrollview及其子类都要去设置的话,也可使用如下方法
// AppDelegate 里进行全局设置 if(@available(iOS 11.0, *)){[[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
iOS11表格用MJRefresh框架下拉刷新的时候界面会闪,显示紊乱,
缘由是iOS11弃用了automaticallyAdjustsScrollViewInsets属性,新增contentInsetAdjustmentBehavior来替代它
tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
//声明tableView的位置 添加下面代码
if (@available(iOS 11.0, *)) {
_tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
_tableView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0);
_tableView.scrollIndicatorInsets = _tableView.contentInset;
}
在iPhone X中底部工具栏须要为home indicator留出34pt边距,iPhone X之前机型TarBar高度49,iPhone X中Tarbar高度加上34变成83.因为项目中Tabbar是用自定义的,须要对Tabbar的高度作适配,用到宏#define kTabbarHeight (IS_iPhoneX ? (49.f+34.f) : 49.f)
适配前代码
_customBarView = [[UIView alloc] initWithFrame:CGRectMake(0, SCREENH - 49,SCREENW, 49)];
适配后的代码_customBarView = [[UIView alloc] initWithFrame:CGRectMake(0, SCREENH - kTabbarHeight,SCREENW, kTabbarHeight)];
图标和文字和其余机型相比偏下,如今须要对图标和文字高度进行调整,作iPhone X和非iPhone X机型适配
(1)购物车View适配,涉及页面商品详情页,搜索页面,购物车页面
(2)自定义数字键盘适配
适配底部用的一个宏#define kTabbarSafeBottomMargin (IS_iPhoneX ? 34.f : 0.f)用于计算距离屏幕顶部高度,若是iPhone X,留出距离屏幕底部34安全距离,控件不能显示34安全距离上
适配前代码
适配后代码
(3)筛选views适配
适配前
适配后
九.自定义分割线处理
iOS 11中有的自定义分割线颜色莫名奇妙变深,很难看,以下图所示,不符合设计规范,尝试其余方法没有解决这个问题,最后经过改变分割线的透明度来解决
适配前
适配后
// 这些界面如下使用代理方法来设置,发现并无生效
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
// 这样的原理是由于以前只是实现了高度的代理方法,却没有实现View的代理方法,iOS10及之前这么写是没问题的,iOS11开启了行高估算机制引发的bug,所以有如下几种解决方法:
// 解决方法一:添加实现View的代理方法,只有实现下面两个方法,方法 (CGFloat)tableView: heightForFooterInSection: 才会生效
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return nil;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return nil;
}
// 解决方法二:直接使用tableView属性进行设置,修复该UI错乱
self.tableView.sectionHeaderHeight = 0;
self.tableView.sectionFooterHeight = 5;
[_optionTableView setContentInset:UIEdgeInsetsMake(-35, 0, 0, 0)];
// 解决方法三:添加如下代码关闭估算行高
self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
直接上代码,无需经过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;
}
先看下图7,
这样的体验实际上是很差的(还怎么用英文撩妹?),因此为了以防这样的问题出现,苹果其实提供了隐藏HomeIndicator的方法,以下,
- (BOOL)prefersHomeIndicatorAutoHidden {
return YES;
}
在VC 里边重写 prefersHomeIndicatorAutoHidden 返回 YES(默认是NO),Home指示条就能自动隐藏了,此方法是在屏幕若无交互事件响应时,延迟2秒左右会回调此方法。
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以前的版本。
问题以下图8红框区域,
致使这个的缘由是由于组视图的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
XCode9调用[[NSBundle mainBundle] pathForResource:resourceNameofType:nil];方法来获取文件路径,返回为nil. 添加正确方式以下图1,
可是XCode9 却埋了一道坑,以下图2, 点击资源文件,找到文件选项
红框区域未默认勾选, 只要把这个复选框勾选便可解决. 具体缘由是:xcode9 添加文件使用addfile 拖拽的文件不会自动添加到Compile Sources 和 Copy Bundle Resources 下.
问题描述: 在某些时候你会发现调用becomeFirstResponder方法时,并未响应键盘,系统键盘没法弹出.
问题发现: 若是在调用以前使用了UIAlertView弹出对话框,就会致使系统键盘没法弹出,猜想是由于UIAlertView在消失遍历window窗口时存在windowLevel 大于 levelNormal 的window把他做为keywindow
问题解决: 若是你的项目里面还在使用UIAlertView(2_0,9_0), 建议用UIAlertController替换掉.
在iOS11 以前,
array[i] 语法糖的替换方法是[array objectAtIndex:i]
在iOS11 以后,
array[i] 语法糖的替换方法是[array objectAtIndexedSubscript:i]
用到动态交换方法的童鞋须要注意
free(properties);
}