一、定位失效
蘋果新增加了一項NSLocationAlwaysAndWhenInUseUsageDescription隱私權限,原有的 NSLocationAlwaysUsageDescription 被降級為 NSLocationWhenInUseUsageDescription。
解決方案:在infoplist文件里里增加NSLocationAlwaysAndWhenInUseUsageDescription 和 NSLocationWhenInUseUsageDescription兩個,如果需要支持iOS10的話,增加NSLocationAlwaysUsageDescription
二、相冊權限
ios11使用相機功能,原有項目crash。
ios11之后蘋果對相冊的隱私權限作了調整,原來的NSPhotoLibraryUsageDescription 調整成了NSPhotoLibraryAddUsageDescription
解決方案:在infoplist文件里添加NSPhotoLibraryAddUsageDescription
三、ScrollView相關控件,比如tableview、webView、collectionView等控件頂部會有一定距離的偏移。
webview.frame=CGRectMake(0, 0, 375, 667);
[self.view addSubview:webview];
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]];
運行后如圖:未充滿屏幕下移了20

原因是:iOS 11中Controller的automaticallyAdjustsScrollViewInsets屬性被廢棄了,決定scrollview的內容與邊緣距離的是adjustedContentInset屬性,而不再是contentInset。當視圖被狀態(tài)欄導航條被覆蓋,系統(tǒng)會自系統(tǒng)自動調整了SafeAreaInsets值,進而影響adjustedContentInset值,會對adjustedContentInset值進行了調整,所以導致tableView的內容到邊緣的距離發(fā)生了變化,導致下移了20pt。
解決方案:關閉系統(tǒng)的自動調整計算
webview.scrollView.contentInsetAdjustmentBehavior=UIScrollViewContentInsetAdjustmentNever
四、tableview相關
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor=[UIColor redColor];
self.view.backgroundColor=[UIColor redColor];
UITableView *tableview=[[UITableView alloc]initWithFrame:CGRectMake(0, 0, 375, 667) style:UITableViewStyleGrouped];
tableview.delegate=self;
tableview.dataSource=self;
[self.view addSubview:tableview];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{//設置每組里有多少行
return 1;
}
//去除頭部的默認間距
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 0.01;
}
//去除尾部的默認間距
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return 0.01;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString * chongzu =@"Cell";//重用機制標識
UITableViewCell* cell =[tableView dequeueReusableCellWithIdentifier:chongzu];//根據重用標r識,到重用池找對應的cell
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:chongzu];//創(chuàng)建一個cell,設置其樣式以及其標識
}
cell.backgroundColor=[UIColor redColor];
cell.textLabel.text=[NSString stringWithFormat:@"%li",(long)indexPath.row];
return cell;//將設置好的cell返回
}
@end
老鐵們應該都知道默認tableView開頭和結尾是有間距的,在開發(fā)中不需要這樣的間距,我們通常會返回0.01這樣很小的頭部和尾部視圖高度,在ios11之前是沒問題的,然我們在ios11運行一下發(fā)現(xiàn)并沒卵用。
原因分析:
ios11后estimatedSectionHeaderHeight ,estimatedSectionFooterHeight
這些估算高度默認值都是UITableViewAutomaticDimension,估算機制處于開啟狀態(tài),代碼中我們只返回高度卻沒有返回對應的視圖,這兩個返回高度的代理方法是不會執(zhí)行的。只要返回對應的視圖就好了。
解決方案:
方案一 :返回對應的視圖
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
return nil;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
return nil;
}
方案二:關閉估算機制
tableview.estimatedSectionHeaderHeight=0;
tableview.estimatedSectionFooterHeight=0;
有時你也會發(fā)現(xiàn)cell莫名其妙的自適應高度了,那是因為ios11后tableview的行高默認不在是44了而是UITableViewAutomaticDimension是自動計算的,如果你需要自適應只需要重設rowheight的值就行了。
五、關于自定義返回按鈕
- 替換系統(tǒng)返回按鈕圖片并隱藏返回按鈕文字
+(void)initialize{
UIImage *backButtonImage = [[UIImage imageNamed:@"back"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 18, 0, 0)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage
forState:UIControlStateNormal
barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60)
forBarMetrics:UIBarMetricsDefault];
}
ios11以下運行正常顯示:

而ios11以上運行返回圖片不居中

原因分析:iOS 11 中setBackButtonTitlePositionAdjustment:UIOffsetMake沒法把按鈕移出navigation bar。
解決方法是設置navigationController的backIndicatorImage和backIndicatorTransitionMaskImage
+(void)initialize{
UIImage *backButtonImage = [[UIImage imageNamed:@"back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[UINavigationBar appearance].backIndicatorImage = backButtonImage;
[UINavigationBar appearance].backIndicatorTransitionMaskImage = backButtonImage;
//將返回文字去掉
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal];
}
或者這樣
+(void)initialize{
UIImage *backButtonImage = [[UIImage imageNamed:@"back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[UINavigationBar appearance].backIndicatorImage = backButtonImage;
[UINavigationBar appearance].backIndicatorTransitionMaskImage = backButtonImage;
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(-300, 0) forBarMetrics:UIBarMetricsDefault];
}
- 2.自定義UIBarButtonItem
在iOS7之后,我們在設置UINavigationItem的leftBarButtonItem,rightBarButtonItem的時候都會造成位置的偏移,雖然不大,但是跟UI的設計或者國人的習慣有點區(qū)別,通常我們添加一個寬度為負值的UIBarButtonItem
UIButton *btn=[[UIButton alloc]init];
btn.frame=CGRectMake(0, 0, 60, 40);
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn setTitle:@"設置" forState:UIControlStateNormal];
UIBarButtonItem *item=[[UIBarButtonItem alloc]initWithCustomView:btn];
UIBarButtonItem *fixedSpace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
fixedSpace.width =-20;
self.navigationItem.rightBarButtonItems=@[fixedSpace, item];
但是這些在iOS 11中都無效了!,在ios11后改動相當大的就是導航欄的部分,在原來的已經復雜的不要的圖層中又新增了新的圖層.那么我這里解決方案是
方法一:自定義個NavigationBar。參考:http://www.itdecent.cn/p/5ec6e0cc5036
@implementation HLTNavigationBar
- (void)layoutSubviews{
[super layoutSubviews];
NSLog(@"%@",self.subviews);
for (UIView *view in self.subviews) {//適配ios11
if ([NSStringFromClass(view.class) containsString:@"ContentView"]) {
view.layoutMargins = UIEdgeInsetsZero;//可修正iOS11之后的偏移
NSLog(@"%@",view.subviews);
}else{//適配iosios10
if ([view isKindOfClass:[Backbutton class]]) {
CGRect frame = view.frame;
frame.origin.x=0;
view.frame=frame;
}
}
}
}
方法二:重寫alignmentRectInsets 參考:http://www.itdecent.cn/p/af27e08a0515
@interface UINagavationItemView : UIButton
@property(nonatomic,assign)UIEdgeInsets alignmentNewRectInsets;
@end
@implementation UINagavationItemView
- (UIEdgeInsets)alignmentRectInsets{
return self.alignmentNewRectInsets;
}
@end
itemView =[[UINagavationItemView alloc]init];
itemView.backgroundColor = [UIColor redColor];
itemView.translatesAutoresizingMaskIntoConstraints = NO;
[[itemView.widthAnchor constraintEqualToConstant:200]setActive:YES];
[[itemView.heightAnchor constraintEqualToConstant:40]setActive:YES];
[itemView addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc]initWithCustomView:itemView];
UIBarButtonItem *negativeSpace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
negativeSpace.width = -20;
self.navigationItem.leftBarButtonItems = @[negativeSpace, buttonItem];
if (@available(iOS 11.0, *)) {
itemView.alignmentNewRectInsets = UIEdgeInsetsMake(0, 20, 0, -20);
}
六、ios11的滑動刪除
IOS11新增了兩個代理方法,可以給這些按鈕添加圖片了。如果實現(xiàn)了新增的Swipe actions的代理方法將會取代(tableView: editActionsForRowAtIndexPath:)
1.向左滑動在右邊顯示(常用的左滑刪除)
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath{
/* UIContextualActionStyle有兩種類型:
UIContextualActionStyleNormal,//置頂、刪除、已讀都可以使用該類型
UIContextualActionStyleDestructive//刪除類型可使用,從左到右一直滑cell,不用點擊刪除按鈕就可以直接執(zhí)行刪除操作
*/
//1.創(chuàng)建UIContextualAction對象
UIContextualAction *deleteRowAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleDestructive title:@"delete" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
//[self.titleArr removeObjectAtIndex:indexPath.row];
completionHandler (YES);
}];
//2.給滑動按鈕添加背景、圖片
deleteRowAction.image = [UIImage imageNamed:@"icon_del"];
deleteRowAction.backgroundColor = [UIColor blueColor];
//3.返回滑動按鈕
UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[deleteRowAction]];
return config;
}
2、左、右都可以滑
左滑是系統(tǒng)刪除按鈕,右滑可以是自定義的滑動按鈕
- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath{
UIContextualAction *deleteRowAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal title:@"取消" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
//[self.titleArr removeObjectAtIndex:indexPath.row];
completionHandler (YES);
}];
deleteRowAction.image = [UIImage imageNamed:@"icon_del"];
deleteRowAction.backgroundColor = [UIColor blueColor];
UIContextualAction *RowAction1 = [UIContextualAction contextualActionWithStyle: UIContextualActionStyleNormal title:@"關注" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
//[self.titleArr removeObjectAtIndex:indexPath.row];
completionHandler (YES);
}];
RowAction1.image = [UIImage imageNamed:@"icon_del"];
RowAction1.backgroundColor = [UIColor greenColor];
UISwipeActionsConfiguration *config = [UISwipeActionsConfiguration configurationWithActions:@[deleteRowAction,RowAction1]];
return config;
}
七、iPhone X適配
iPhone X 和 iPhone 8 的寬度一致,在垂直方向上多了145pt,狀態(tài)欄不再是20而是44,沒有了 Home 鍵,iPhone X 的底部預留給系統(tǒng)功能的一個區(qū)域 - Home Indicator,這部分的高度是34pt。首先看以下代碼感受下:
- 一、簡單感受適配
UILabel *lable=[[UILabel alloc]init];
lable.backgroundColor=[UIColor redColor];
[self.view addSubview:lable];
lable.text=@"12344444444";
lable.textAlignment=NSTextAlignmentCenter;
lable.frame=CGRectMake(0, 20, self.view.frame.size.width, 30);
iphone8的運行效果:

iphone X的運行效果:

很明顯iPhone X的y值不能寫死20了,我們也需要考慮下44高度狀態(tài)欄的iphone X了,下面像這樣簡單適配下就好了:
- frame的方式
// UIScreen width.
#define ScreenWidth [UIScreen mainScreen].bounds.size.width
// UIScreen height.
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
// iPhone X
#define iPhoneX (ScreenWidth == 375.f && ScreenHeight == 812.f ? YES : NO)
// Status bar height.
#define StatusBarHeight (iPhoneX ? 44.f : 20.f)
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *lable=[[UILabel alloc]init];
lable.backgroundColor=[UIColor redColor];
[self.view addSubview:lable];
lable.text=@"12344444444";
lable.textAlignment=NSTextAlignmentCenter;
lable.frame=CGRectMake(0, StatusBarHeight , self.view.frame.size.width, 30);
NSLog(@"%f",[UIScreen mainScreen].bounds.size.height);
}
- Autolayout的方式
Autolayout 視圖的 top 和 bottom 一般參照的是 Top Layout Guide 和 Bottom Layout Guide. iOS11 廢棄了改用安全區(qū)域(SafeArea)做參考來做適配.
適配前的代碼:
[lable mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view);
make.height.equalTo(@30);
make.top.equalTo(self.view).offset(20);
}];
適配后的代碼:
[lable mas_makeConstraints:^(MASConstraintMaker *make) {
//以安全區(qū)域的頂部為參考作約束
make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop);
//哈哈,運行下就不用判斷是20還是44了
make.left.right.equalTo(self.view);
make.height.equalTo(@30);
}];
3.注意iphoneX底部系統(tǒng)功能區(qū)域34的高度不要被控件遮擋了:
例如你這樣
self.view.backgroundColor=[UIColor redColor];
UILabel *lable=[[UILabel alloc]init];
lable.backgroundColor=[UIColor greenColor];
[self.view addSubview:lable];
lable.text=@"12344444444";
lable.textAlignment=NSTextAlignmentCenter;
lable.frame=CGRectMake(0,ScreenHeight-30, self.view.frame.size.width, 30);

因此適配就還需要個宏了。
適配如下:
#import "ViewController.h"
// UIScreen width.
#define ScreenWidth [UIScreen mainScreen].bounds.size.width
// UIScreen height.
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
// iPhone X
#define iPhoneX (ScreenWidth == 375.f && ScreenHeight == 812.f ? YES : NO)
// Status bar height.
#define StatusBarHeight (iPhoneX ? 44.f : 20.f)
// safe bottom margin.
#define SafeBottomMargin (iPhoneX ? 34.f : 0.f)
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor=[UIColor redColor];
UILabel *lable=[[UILabel alloc]init];
lable.backgroundColor=[UIColor greenColor];
[self.view addSubview:lable];
lable.text=@"12344444444";
lable.textAlignment=NSTextAlignmentCenter;
lable.frame=CGRectMake(0,ScreenHeight-30-SafeBottomMargin, self.view.frame.size.width, 30);
}
或者你這樣(哈哈,我就喜歡這樣)
#import "ViewController.h"
#import "Masonry.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor=[UIColor redColor];
UILabel *lable=[[UILabel alloc]init];
lable.backgroundColor=[UIColor greenColor];
[self.view addSubview:lable];
lable.text=@"12344444444";
lable.textAlignment=NSTextAlignmentCenter;
[lable mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view);
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
make.height.equalTo(@30);
}];
}
- 二、適配
待續(xù)................