ios11適配

一、定位失效

蘋果新增加了一項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


WechatIMG5.jpeg

原因是: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的值就行了。
五、關于自定義返回按鈕

    1. 替換系統(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以下運行正常顯示:

BA95CE00-E9EA-4ECD-996D-6E29D71AE818.png

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


9C5D58E3-853D-4456-A7D2-94AE25BEF98F.png

原因分析: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的運行效果:


B567F8E0-F918-4D64-A9C2-2B1A725E3CEA.png

iphone X的運行效果:

6BBDDAB2-5CE3-4368-992E-79DF59B69E0C.png

很明顯iPhone X的y值不能寫死20了,我們也需要考慮下44高度狀態(tài)欄的iphone X了,下面像這樣簡單適配下就好了:

  1. 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);
}
  1. 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);
974D1DF1-0220-44D0-ADE6-5FCAB4FBF894.png

因此適配就還需要個宏了。
適配如下:

#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ù)................
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容