iOS開發筆記— Xcode、UITabbar、特殊機型問題分析

收藏待读

前言

本文分享iOS開發中遇到的問題,和相關的一些思考。

正文

一、Xcode10.1 import頭文件無法索引

【問題表現】如圖,當import頭文件的時候,索引無效,無法聯想出正確的文件;

iOS開發筆記— Xcode、UITabbar、特殊機型問題分析

【問題分析】通過多個文件嘗試,發現並非完全不能索引頭文件,而是只能索引和當前文件在同級目錄的頭文件;

有點猜測是Xcode10.1的原因,但是在升級完的半年多時間裏,都沒有出現過索引。

從已有的知識來分析,很可能是Xcode的頭文件搜索路徑有問題,於是嘗試把工程文件下的路徑設置遞歸搜索,結果又出現以下問題:

iOS開發筆記— Xcode、UITabbar、特殊機型問題分析

【問題解決】在多次嘗試無效之後,最終還是靠Google解決該問題。

如下路徑,修改設置

Xcode –> File –> Workspace Settings –> Build System –> Legacy Build System

iOS開發筆記— Xcode、UITabbar、特殊機型問題分析

二、NSAssert的斷點和symbolic 斷點

【問題表現】NSAssert是常見的斷言,可以在debug階段快速暴露問題,但是在觸發的時候無法保持上下文;

【問題分析】NSAssert的本質就是拋出一個異常,可以通過Xcode添加一個Exception Breakpoint:

iOS開發筆記— Xcode、UITabbar、特殊機型問題分析

如下,便可以NSAssert觸發時捕獲現場。

iOS開發筆記— Xcode、UITabbar、特殊機型問題分析

同理,在Exception Breakpoint,還有Smybolic Breakpoint較為常用。

以cookie設置接口為例,以下為一段設置cookies的代碼

[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies];

但是有時候設置cookies的地方可能較多,此時可以添加一個Smybolic Breakpoint並設置符號為cookies。

如下,可以看到所有設置cookies的接口:

iOS開發筆記— Xcode、UITabbar、特殊機型問題分析

三、.m文件改成.mm文件後編譯失敗

【問題表現】Pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified)

出錯代碼行: typedef void(^SSDataCallback)(NSError *error, id obj);

手動給參數添加 nullable的聲明並無法解決。

【問題分析】

首先確定的是,這個編譯失敗實際上是一個warning,只是因為工程設置了把warning識別為error;

其次.m文件可以正常編譯,並且.m文件也是開啟了warning as error的設置;而從改成.mm就報錯的表現和提示log來看,仍然是因為參數為空的原因導致。

【問題解決】

經過對比正常編譯的.mm文件,找到一個解決方案:

1,添加NS_ASSUME_NONNULL_BEGIN在代碼最前面,NS_ASSUME_NONNULL_END在代碼最後面;

2、手動添加_Nullable到函數的參數;

typedef void(^SSDataCallback)(NSError * _Nullable error, id _Nullable obj);

四、UITabbar疑難雜症

問題1、batItem的染色異常問題

【問題表現】添加UITabBarItem到tabbar上,但是圖片會被染成藍色;

【問題分析】tabbar默認會幫我們染色,所以我們創建的UITabBarItem默認會被tinkColor染色的影響。

解決辦法就是添加參數imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal,這樣UITabBarItem的圖片變不會受到tinkColor影響。

        UITabBarItem *item1 = [[UITabBarItem alloc] initWithTitle:@"商城" image:[UIImage imageNamed:@"tabbar_item_store"] selectedImage:[[UIImage imageNamed:@"tabbar_item_store_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];

問題2、tabbar的背景色問題

【問題表現】設置tabbar的背景色是0xFFFFFF的白色,但是實際的效果確是灰白色,並不是全白色;

【問題分析】tabbar默認是透明的(屬性translucent),會對tabbar下面的視圖進行高斯模糊,然後再與背景色混合。

【問題解決】

1、自由做法,addSubview:一個view到tabbar上,接下來自己繪製4個按鈕;(可操作性強,缺點是tabbar的邏輯需要自己再實現一遍)

2、改變tabbar透明度做法,設置translucent=YES,再修改背景色;(引入一個巨大的坑,導致UITabbarViewController上面的子VC的self.view屬性高度會變化!)

3、空白圖做法,把背景圖都用一張空白的圖片替代,如下:(最終採納的做法)

    self.tabBar.backgroundImage = [[UIImage alloc] init];
    self.tabBar.backgroundColor = [UIColor whiteColor];

問題3、tabbar頂部的線條問題

【問題表現】UITabbar默認在tabbar的頂部會有一條灰色的線,但是並沒有一個屬性可以修改其顏色。

【問題分析】從Xcode的工具來看,這條線是一個UIImageView:

iOS開發筆記— Xcode、UITabbar、特殊機型問題分析

再從UITabbar的頭文件來看,這條線的圖片可能是shadowImage。

【問題解決】將shadowImage用一張空白的圖片替代,然後自己再添加想要的線條大小和顏色。

    self.tabBar.shadowImage = [[UIImage alloc] init];
    UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tabBar.width, 0.5)];
    lineView.backgroundColor = [UIColor colorWithHexString:@"e8e8e8"];
    [self.tabBar addSubview:lineView];

五、特殊機型出現的異常現象

1、iOS 11.4 充電時無法正常獲取電量

【問題表現】在某個場景需要獲取電池,於是通過以下addObserverForName:UIDeviceBatteryLevelDidChangeNotification的方式監聽電量的變化,在iOS 12的機型表現正常,但是在iOS 11.4的機型上會出現無法獲取電量的原因。

    void (^block)(NSNotification *notification) = ^(NSNotification *notification) {
        SS_STRONG_SELF(self);
        NSLog(@"%@", self);
        self.batteryView.width = (self.batteryImageView.width - Padding_battery_width) * [UIDevice currentDevice].batteryLevel;
    };
    //監視電池剩餘電量
    [[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceBatteryLevelDidChangeNotification
                                                      object:nil
                                                       queue:[NSOperationQueue mainQueue]
                                                  usingBlock:block];

【問題分析】從電量獲取的api開始入手分析,在獲取電量之前,需要顯式調用接口

[UIDevice currentDevice].batteryMonitoringEnabled = YES;

於是點擊batteryMonitoringEnabled屬性進入UIDevice.h,發現有個batteryState屬性,裏面有一個狀態是充電UIDeviceBatteryStateCharging,但是對問題並無幫助;

點擊UIDeviceBatteryLevelDidChangeNotification發現還有一個通知是UIDeviceBatteryStateDidChangeNotification,猜測可能是充電狀態下的回調有所不同;

【問題解決】最終通過添加新通知的監聽解決。該問題並不太難,但是養成多看.h文件相關屬性的習慣,還是會有好處。

    [[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceBatteryStateDidChangeNotification
                                                      object:nil
                                                       queue:[NSOperationQueue mainQueue]
                                                  usingBlock:block];

2、iOS 10.3的UILabel富文本排版異常

【問題表現】有一段文本的顯示需要設置首行縮進,所以用的富文本添加段落屬性的方式;但是在iOS 10.3的6p機型上出現異常現象,如下:

測試文本:[email protected]”一年佛山電腦放山東難道是防空洞念佛”

如下,最後的字符沒有顯示完全。

實現方式是計算得到富文本,然後賦值給UILabel,再調用-sizeToFit的接口。

iOS開發筆記— Xcode、UITabbar、特殊機型問題分析

以上的問題僅在一行的時候出現異常,兩行又恢復正常。

iOS開發筆記— Xcode、UITabbar、特殊機型問題分析

【問題分析】

從表現來看,是sizeToFit的時候寬度結算出錯;通過多次嘗試,發現是少計算了大概兩個空格的距離,也即是首行縮進的距離。

【問題解決】

方法1、去除首行縮進,每行增加兩個空格;

方法2、一行的時候,把寬度設置到最大;

如何判斷1行的情況,可以用以下的代碼簡短判斷

    if (self.contentLabel.height < self.contentLabel.font.lineHeight * 2) { // 一行的情況
        self.contentLabel.width = self.width - 40;
    }

總結

日常開發遇到的問題,如果解決過程超過10分鐘,我都會記錄下來。

這些問題有的很簡單,僅僅是改個配置(如第一個Xcode索引問題),但是在解決過程中還是走了一些彎路,因為完全沒想過可能會去改Workspace setting,都是在Build setting修改進行嘗試。

還有些問題純粹是特定現象,比如說特殊機型問題,只是做一個備忘和提醒。

作者:落影loyinglin

鏈接:https://www.jianshu.com/p/6c964411fc03

原文 : CocoaChina

相關閱讀

免责声明:本文内容来源于CocoaChina,已注明原文出处和链接,文章观点不代表立场,如若侵犯到您的权益,或涉不实谣言,敬请向我们提出检举。