iOS開發系列--iPhone X和IOS11適配的那些坑!

首先貢獻幾個宏定義,下文也有用到!ios

//動態獲取設備寬度
#define IPHONE_WIDTH [UIScreen mainScreen].bounds.size.width
#define IPHONE_HEIGHT [UIScreen mainScreen].bounds.size.height
//iPhone X判斷
#define IPHONE_X    ([UIScreen mainScreen].bounds.size.width == 375 && [UIScreen mainScreen].bounds.size.height == 812)
//狀態欄高度
#define StatusBar_Height    ([UIApplication sharedApplication].statusBarFrame.size.height + 44)
//底部Tabbar高度
#define Tabbar_Height       (IPHONE_X ? (49 + 34) : 49)
//iPhone X底部高度
#define Tabbar_Bottom_Margin  (IPHONE_X ? 34 : 0)

1.首先iPhone X的屏幕尺寸是375X812,啓動頁的圖片分辨率是1125X2436。

正常來講不適配的話iPhone X的上下邊會有黑邊,好比這樣的:
json

固然這張圖是我後期截的,底部的Tabbar會有白邊,若是沒有作過處理,正常來講是不會有的。
解決辦法,在項目設置裏面直接用LaunchScreen.xib或者LaunchScreen.storyboard進行配置啓動圖,或者改變LaunchImage.launchimage裏的Contents.json配置app

{
"extent":"full-screen",
"idiom":"iphone",
"subtype":"2436h",
"filename":"iPhone_5.8.png",
"minimum-system-version":"11.0",
"orientation":"portrait",
"scale":"3x"
}

這樣項目就會完整顯示了。以下圖less

2. iPhone X最直觀的改變是頂部多了一個"劉海",致使狀態欄欄高度由原來的44+20,變成了44+44。底部的Home鍵取消,致使Tabbar底部多出34高度的白邊,以前用代碼設置Frame的界面可能會被擋住。

相似這樣:
iphone

3. 狀態欄高度的變化可能致使自定義狀態欄背景圖片未徹底鋪滿。

好比像這樣:

解決辦法:經過重繪圖片高度達到鋪滿效果ide

//設置全局屬性
UINavigationBar *appearance = [UINavigationBar appearance];
UIImage *image = [UIImage imageNamed:@"nav_bg"];
if (IPHONE_X) image = [image scaleToSize:CGSizeMake(IPHONE_WIDTH, StatusBar_Height)];
[appearance setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
[appearance setShadowImage:[[UIImage alloc] init]];
- (UIImage *)scaleToSize:(CGSize)size
{
    UIGraphicsBeginImageContext(size);
    [self drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}

重繪後的效果以下:
image.png動畫

4.push操做致使的tabbar跳動上移的問題。

Untitled.gif
注意看底部tabbar的跳動。
解決辦法:新建一個繼承UINavigationController的類,而後重寫spa

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [super pushViewController:viewController animated:animated];
    if (IPHONE_X) {
        // 修改tabBra的frame
        CGRect frame = self.tabBarController.tabBar.frame;
        frame.origin.y = [UIScreen mainScreen].bounds.size.height - frame.size.height;
        self.tabBarController.tabBar.frame = frame;
    }
}

5.push和pop時UIScrollView的子類可能會發生一個偏移動畫

Untitled.gif
注意看導航欄下的UITableView有一個往上偏移的動畫。code

緣由:automaticallyAdjustsScrollViewInsets 這個屬性在iOS11中已經被棄用,咱們須要使用UIScrollViewcontentInsetAdjustmentBehavior屬性來替代它。blog

typedef NS_ENUM(NSInteger, UIScrollViewContentInsetAdjustmentBehavior) {
    UIScrollViewContentInsetAdjustmentAutomatic, // Similar to .scrollableAxes, but for backward compatibility will also adjust the top & bottom contentInset when the scroll view is owned by a view controller with automaticallyAdjustsScrollViewInsets = YES inside a navigation controller, regardless of whether the scroll view is scrollable
    UIScrollViewContentInsetAdjustmentScrollableAxes, // Edges for scrollable axes are adjusted (i.e., contentSize.width/height > frame.size.width/height or alwaysBounceHorizontal/Vertical = YES)
    UIScrollViewContentInsetAdjustmentNever, // contentInset is not adjusted
    UIScrollViewContentInsetAdjustmentAlways, // contentInset is always adjusted by the scroll view's safeAreaInsets
} API_AVAILABLE(ios(11.0),tvos(11.0));

UIScrollViewContentInsetAdjustmentBehavior 是一個枚舉類型,值有如下幾種:
UIScrollViewContentInsetAdjustmentAutomatic 和UIScrollViewContentInsetAdjustmentScrollableAxes同樣,scrollView會自動計算和適應頂部和底部的內邊距而且在scrollView 不可滾動時,也會設置內邊距.
UIScrollViewContentInsetAdjustmentScrollableAxes 自動計算內邊距.
UIScrollViewContentInsetAdjustmentNever不計算內邊距
UIScrollViewContentInsetAdjustmentAlways 根據safeAreaInsets 計算內邊距
很顯然,咱們這裏要設置爲 UIScrollViewContentInsetAdjustmentNever

我在MainNavigationController類的initialize方法中去設置UIScrollView全局屬性。固然,也能夠在合適的地方去添加屬性設置。

UIScrollView類的上下留有滾動邊距(頂部留有49,底部留有34)的問題,一樣也可經過此方法解決。
+ (void)initialize
{
    //兼容ios11,修復push和pop時UIScrollView的子類會發生一個偏移動畫
    if (@available(iOS 11.0, *)) {
        [UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }
}

6. ios11的權限變動問題

可能升級到ios11後,你發現有的APP沒法使用定位,並且連定位權限申請的彈窗都不會出現。那是由於ios的定位權限中新增了一個NSLocationAlwaysAndWhenInUseUsageDescription字段,須要在info.plist中添加相應的代碼。

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>定位權限描述,本身能夠根據需求修改</string>

相應的彈窗也發生了變化
定位.png

暫時想到的只有這些了,後續想到再補充吧!

相關文章
相關標籤/搜索