10分鐘適配 iOS 11 & iPhone X

臭碼農發表於2017-12-14

適配中的問題及解決辦法

1. 滾動條高度跳動、上下拉重新整理問題:

self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0;
self.tableView.estimatedSectionFooterHeight = 0;
複製程式碼

2. 列表/頁面偏移

設定工程中的UITableViewUICollectionViewUIScrollViewcontentInsetAdjustmentBehavior屬性,如下:

if (@available(iOS 11.0, *)){
        _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }
複製程式碼

總的來說所有繼承與Scrollview 及其子類都需要設定 contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever ,每個設定很麻煩,沒關係。由於UIView及其子類都遵循UIAppearance協議,我們可以進行全域性配置:

// AppDelegate 進行全域性設定
    if (@available(iOS 11.0, *)){
        [[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
    }
複製程式碼

3. 導航欄按鈕位置問題

iOS 11重新調整了導航欄的元素,強制將leftButtonsrightButtons位置往螢幕中央靠了一些,在這之前通過新增一個UIBarButtonSystemItemFixedSpace 把寬度設為負數以調整按鈕的邊距

    //調整按鈕邊距
//    UIBarButtonItem* spaceItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
//    //將寬度設為負值
//    spaceItem.width= -5;
//    [items addObject:spaceItem];
複製程式碼

iOS 11如上設定是無效的 如果你無法接受系統給設定的位置,可以試試下面的方法

#pragma mark  導航欄 新增文字按鈕
- (NSMutableArray<UIButton *> *)addNavigationItemWithTitles:(NSArray *)titles isLeft:(BOOL)isLeft target:(id)target action:(SEL)action tags:(NSArray *)tags
{
    
    NSMutableArray * items = [[NSMutableArray alloc] init];
    
    //調整按鈕位置
//    UIBarButtonItem* spaceItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
//    //將寬度設為負值
//    spaceItem.width= -5;
//    [items addObject:spaceItem];
    
    NSMutableArray * buttonArray = [NSMutableArray array];
    NSInteger i = 0;
    for (NSString * title in titles) {
        UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
        btn.frame = CGRectMake(0, 0, 30, 30);
        [btn setTitle:title forState:UIControlStateNormal];
        [btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
        btn.titleLabel.font = SYSTEMFONT(16);
        [btn setTitleColor:KWhiteColor forState:UIControlStateNormal];
        btn.tag = [tags[i++] integerValue];
        [btn sizeToFit];
        
        //設定偏移
        if (isLeft) {
            [btn setContentEdgeInsets:UIEdgeInsetsMake(0, -10, 0, 10)];
        }else{
            [btn setContentEdgeInsets:UIEdgeInsetsMake(0, 10, 0, -10)];
        }
        
        UIBarButtonItem * item = [[UIBarButtonItem alloc] initWithCustomView:btn];
        [items addObject:item];
        [buttonArray addObject:btn];
    }
    if (isLeft) {
        self.navigationItem.leftBarButtonItems = items;
    } else {
        self.navigationItem.rightBarButtonItems = items;
    }
    return buttonArray;
}
複製程式碼

此法實屬障眼法,並不完美,通過設定內容偏移,讓按鈕視覺上看起來位置改變了,實際位置並沒有發生變化,這可能導致按鈕部分割槽域響應點選事件。 若追求完美,可以試著自定義UIButton重寫hitTest方法嘗試改變點選區域。 若有其他完美的辦法請聯絡我更新。

4. 位置許可權

在IOS11,原有的NSLocationAlwaysUsageDeion被降級為NSLocationWhenInUseUsageDeion。因此,在原來專案中使用requestAlwaysAuthorization獲取定位許可權,而未在plist檔案中配置NSLocationAlwaysAndWhenInUseUsageDeion,系統框不會彈出。建議新舊key值都在plist裡配置,反正我試下來是沒有問題,唯一的區別是使用requestAlwaysAuthorization獲取許可權 IOS11系統彈框會把幾種許可權級別全部列出,供使用者選擇,顯然更人性化了。 快去更新你的info.plist

    <!-- 位置 -->
    <key>NSLocationUsageDescription</key>
    <string>獲取地理位置,精準推送服務</string>
    <!-- 在使用期間訪問位置 -->
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>獲取地理位置,精準推送服務</string>
    <!-- 始終訪問位置 -->
    <key>NSLocationAlwaysUsageDescription</key>
    <string>App需要您的同意,才能始終訪問位置</string>
    <!-- iOS 11訪問位置 -->
    <key>NSLocationAlwaysAndWhenInUseUsageDeion</key>
    <string>App需要您的同意,才能始終訪問位置</string>
複製程式碼

5. iPhone X 適配

iPhone X 變化最大的是頭部 & 底部 非iPhone X : StatusBar 高20px,NavigationBar 高44px,底部TabBar高49px iPhone X: StatusBar 高44px,NavigationBar 高44px,底部TabBar高83px 所以,之前專案裡寫死的 ±49 ±64 都要出問題,如果你之前抽離出來使用的是巨集,那問題不大,如果不是,開始搬磚吧少年。 送你幾個巨集,來日好好擼,莫偷懶

#define kStatusBarHeight [[UIApplication sharedApplication] statusBarFrame].size.height
#define kNavBarHeight 44.0
//注意:請直接獲取系統的tabbar高度,若沒有用系統tabbar,建議判斷螢幕高度;之前判斷狀態列高度的方法不妥,如果正在通話狀態列會變高,導致判斷異常,下面只是一個例子,請勿直接使用!
#define kTabBarHeight kAppDelegate.mainTabBar.tabBar.frame.size.height
#define kTopHeight (kStatusBarHeight + kNavBarHeight)
複製程式碼

替換 64px →kTopHeight 替換 49px →kTabBarHeight

##6. iPhone X push的時候TabBar上移 答案在這:適配iPhone X Push過程中TabBar位置上移

這樣可以解決大部分因位置導致的適配問題

請關注點❤️,持續更新……
iOS 超級碼農交流群:538549344 技術大牛在等你來提問

以上屬於臭碼農原創,若有雷同屬巧合,如有錯誤望指正,轉載請標明來源和作者。 by:臭碼農

相關文章