iOS 11适配和iPhone X的适配
这两天对自己负责的项目进行iOS 11和iPhone X的适配,网上的博客很多,也看了很多别人的记录博客,这里把自己遇到的问题记录下,当然有些不仅仅是iOS 11和iPhone X的适配,还包括自己遇到的问题和解决方法。
1> iOS Assertion failure in -[UITableView _classicHeightForRowAtIndexPath:]:
这问题是由于cell高度负数导致,去看看:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { }
2> iOS 11使用第三方侧滑Cell-MSCMoreOptionTableViewCell,不能出现多个按钮:
https://github.com/scheinem/MSCMoreOptionTableViewCell/issues/37
https://forums.developer.apple.com/thread/86009
具体代码如下:
-(id)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath { return [self getRowActions:tableView indexPath:indexPath]; } -(id)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { return [self getRowActions:tableView indexPath:indexPath]; } -(id)getRowActions:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath { if (@available(iOS 11, *)) { UIContextualAction *delete = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"删除" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) { completionHandler(YES); }]; delete.backgroundColor = [UIColor redColor]; UIContextualAction *modify = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"修改" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) { completionHandler(YES); }]; modify.backgroundColor = [UIColor redColor]; UISwipeActionsConfiguration *swipeActionConfig = [UISwipeActionsConfiguration configurationWithActions:@[delete, modify]]; swipeActionConfig.performsFirstActionWithFullSwipe = NO; return swipeActionConfig; } return nil; }
当然你可以使用iOS 8自带的侧滑Cell出现多个按钮,这里因为之前项目适配iOS 7,懒得改了,代码如下:
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath { // 添加一个删除按钮 UITableViewRowAction *deleteRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"删除"handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { [self tableView:tableView moreOptionButtonPressedInRowAtIndexPath:indexPath]; }]; // 添加一个修改按钮 UITableViewRowAction *modifyRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleNormal title:@"修改"handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) { [self tableView:tableView moreOptionButtonPressedInRowAtIndexPath:indexPath]; }]; modifyRowAction.backgroundEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]; return @[modifyRowAction, deleteRowAction]; }
3> iOS 11TableView的sectionHeader高度变大:实现返回View的代理即可。
#pragma mark - talbeView delegate - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 21.f; } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return 0.1f; } // 解决iOS 11 sectionHeader高度变高的问题 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { return [UIView new]; } - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { return [UIView new]; }
4> 添加下面的代码,会造成系统选择相册顶部偏移:
// //解决iOS11,仅实现heightForHeaderInSection,没有实现viewForHeaderInSection方法时,section间距大的问题 // [UITableView appearance].estimatedRowHeight = 0; // [UITableView appearance].estimatedSectionHeaderHeight = 0; // [UITableView appearance].estimatedSectionFooterHeight = 0; // // //iOS11 解决SafeArea的问题,同时能解决pop时上级页面scrollView抖动的问题 // if (@available(iOS 11, *)) { // [UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; //iOS11 解决SafeArea的问题,同时能解决pop时上级页面scrollView抖动的问题 // }
5> iOS 11 SearchBar的高度变化:
#define iOS(version) ([[UIDevice currentDevice].systemVersion doubleValue] >= version) #define K_SEARCH_BAR_HEIGHT (iOS(11)?56.f:44.f)
有博客说可以这样:我好像试了没什么效果
// 强制高度: [self.searchBar.heightAnchor constraintLessThanOrEqualToConstant:44].active = YES;
6> iOS 11 新增的两个保存相册权限:
<key>NSPhotoLibraryUsageDescription</key> <string>App需要您的同意,才能访问相册</string> <key>NSPhotoLibraryAddUsageDescription</key> <string>App需要您的同意,才能访问相册</string>
7> 跳转到AppStore:
-(void)goToAppStore { NSString *itunesurl = @"itms-apps://itunes.apple.com/cn/app/idXXXXXX?mt=8&action=write-review"; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:itunesurl]]; } 注意:把里面的XXX替换成你自己的APP ID。
8>iOS 11返回按钮点击不灵敏:
参考博客: http://m.blog.csdn.net/wenmingzheng/article/details/78081342
iPhone X的适配:
1> 启动图:添加1125 * 2436的图片即可;
2> 安全区域上下不遮挡:
这里注意:思思一直以为所有页面都需要距离底部34的安全距离,其实没有必要,如果你的tableview是像模拟器里“设置”页面一样的话 就不用减34p ,如果tableview底部还有其他按钮的 就要减34啦!都说官方没有一定的强制要求。
参见系统设置界面:
我居然不知道参考系统的页面,还在一直的纠结要不要减去34,该打,哈哈😄
参考宏定义:
// 10.31修改 适配iPhone X机型 #define K_STATUS_BAR_HEIGHT ([[UIApplication sharedApplication] statusBarFrame].size.height) #define K_NAVIGATION_BAR_HEIGHT (44.f) #define K_STATUS_BAR_AND_NAVI_BAR_HEIGHT (K_STATUS_BAR_HEIGHT + K_NAVIGATION_BAR_HEIGHT) #define K_SEGMENTED_CONTROL_HEIGHT (29.f) #define K_TOOL_BAR_HEIGHT (44.f) #define iOS(version) ([[UIDevice currentDevice].systemVersion doubleValue] >= version) //#define K_SEARCH_BAR_HEIGHT (44.f) #define K_SEARCH_BAR_HEIGHT (iOS(11)?56.f:44.f) #define K_TEXT_FIELD_HEIGHT (30.f) #define K_SWITCH_HEIGHT (31.f) #define K_ACTIVITY_INDICATOR_WH (20.f) #define K_STEPPER_HEIGHT (29.f) #define K_AD_BANNER_HEIGHT (66.f) // 10.31添加 适配iPhone X机型 #define kSafeAreaBottomHeight (K_SCREEN_HEIGHT == 812.0 ? 34 : 0) #define kSafeAreaTopHeight (K_SCREEN_HEIGHT == 812.0 ? 44 : 0) #define K_TAB_BAR_HEIGHT ([[UIApplication sharedApplication] statusBarFrame].size.height>20?83:49) #define K_BottomView_HEIGHT 49 /// 高度系数 812.0 是iPhoneX的高度尺寸,667.0表示是iPhone 8 的高度 #define kHeightCoefficient (K_SCREEN_HEIGHT == 812.0 ? 667.0/667.0 : K_SCREEN_HEIGHT/667.0) // 是否是IPHONE_X机型 #define IS_IPHONE_X (K_SCREEN_HEIGHT == 812) #define ViewSafeAreInsets(view) ({UIEdgeInsets insets; if(@available(iOS 11.0, *)) {insets = view.safeAreaInsets;} else {insets = UIEdgeInsetsZero;} insets;})
适配如下:
[tableView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.top.right.equalTo(self.view); make.bottom.mas_equalTo(self.view).offset(-kSafeAreaBottomHeight); }];
3> 使用第三方RESideMenu push回来导致导航栏按钮不能点击:
https://github.com/romaonthego/RESideMenu/issues/306#issuecomment-340685077
不过这里我不是这问题,我的问题是因为我在导航栏添加了手势导致的,这里原因我也不知道为什么,只在iOS 11有这个问题。
这里我看到Github的issue,一直以为就是它的第三方的问题,还是太天真了
经过别人提醒,学习到了一种调试程序和代码的最笨的一种方法,但是很实用,哈哈:
一个一个方法隐藏看问题,找出出问题的代码即可。
所有的问题只要找到原因就好解决,最大的感触,你有木有觉得啊,哈哈😄
解决如下:
if (@available(iOS 11.0, *)) { return; } else { UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapClick:)]; [self.navigationController.navigationBar addGestureRecognizer:tapGR]; }
4> 适配iPhoneX Push过程中TabBar位置上移, 修改tabBra的frame:
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { if (self.viewControllers.count) { viewController.hidesBottomBarWhenPushed = YES; // default back button item UIBarButtonItem *item = [UIBarButtonItem barButtonItemWithImage:[UIImage imageNamed:@"return_icon"] highLightedImage:nil target:self action:@selector(backItemDidClicked:) forControlEvents:UIControlEventTouchUpInside]; viewController.navigationItem.leftBarButtonItem = item; } self.interactivePopGestureRecognizer.enabled = NO; [super pushViewController:viewController animated:animated]; // 适配iPhoneX Push过程中TabBar位置上移, 修改tabBra的frame CGRect frame = self.tabBarController.tabBar.frame; frame.origin.y = [UIScreen mainScreen].bounds.size.height - frame.size.height; self.tabBarController.tabBar.frame = frame; }
集成最新的友盟统计:
集成文档: http://dev.umeng.com/sdk_integate/ios-integrate-guide/common
注意: 下面添加库文件点+找不到,可以直接从左边文件拖过来即可。这里思思可是被坑了很久哇。。。
打包:
和之前的没啥区别,下面直接Next即可,不用选择和勾选。