1. 程式人生 > >「 iOS知識小集 」2018 · 第 42 期

「 iOS知識小集 」2018 · 第 42 期

原文連結

上週公眾號釋出的以下文章:

本期知識小集的主要內容包括:

  • 使用 Named UIColor
  • Diff:/Podfile.lock NO such file or directory
  • iOS 中的 GZIP 壓縮
  • 使用 CaseIterable 獲取列舉的所有 case
  • 不可或缺的背景色

使用 Named UIColor

從 XCode 9 開始,我們可以在工程中建立 named color,並在程式碼或 Storyboard 中使用。要建立 named color,只需要進入 Assets.xcassets 中,點選右鍵,出現圖 1 的選單,選擇 New Color Set,

然後編輯 named color 的名稱和色值等資訊,如圖 2 所示。

在程式碼中,我們可以直接使用 UIColor(name: "Test")來使用,如圖 3 所示。

Diff:/Podfile.lock NO such file or directory

作者: Lefe_x

Pod install 後,執行專案後發現報錯,錯誤提示如圖所示。按提示看了下 Podfile.lock 是存在的。試了各種辦法,都沒有解決(刪除 pods 資料夾,重新安裝,都不好使)。無奈之下,看了下檔案的路徑。發現檔案路徑錯了,XXX/Pods/Pods/Target Support Files/xxx

,發現檔案路徑多了個 Pods。這個路徑我並沒有設定,是 Pod 自己管理的。最後發現在下圖的位置中可以配置路徑,把這個路徑修改成正確的地址就可以了:

iOS 中的 GZIP 壓縮

作者:這個湯圓沒有餡

當專案中與後端介面互動涉及到大量資料資訊的時候,為了提升響應速度需要對傳輸的資料進行壓縮,壓縮成功後將 data 轉化為 string 傳給伺服器。

關於 iOS 端的 GZIP 壓縮,這是我目前在 github 上找到的 star 數最多的一個:t.cn/RUBP1Le

GZIP 支援 cocoapods,如果手動匯入的話,記得在 Targets--Build Phases--Link Binary With Libraries

中新增 libz.1.2.5.tbd。

模擬一萬條簡單的資料,看看壓縮前後資料大小變化。如下圖。

經過 GZIP 壓縮後,位元組量縮小幅度很大。但是壓縮後的 data 是無法通過 - (nullable instancetype)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding; 這個方法得到string的。

這個時候我們再來看 java 中對於壓縮的資料是如何解壓縮的,java 程式碼如下圖。

其中有一行程式碼為

byte[] compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr);
複製程式碼

說明 java 是對 base64 的string 進行解壓縮的,也就是說我們在進行 data 壓縮後,需要傳 base64 的string 給伺服器。那麼只需要加一行程式碼

[zipData base64EncodedStringWithOptions:0];
複製程式碼

使用 CaseIterable 獲取列舉的所有 case

在寫 Swift 程式碼時,可能需要獲取列舉的所有 case,在之前的版本中,我們可能需要自己來實現一個靜態方法 allCases,如下程式碼所示:

enum CompassDirection {
    case north, south, east, west

    static let allCases = [north, south, east, west]
}
複製程式碼

而在 Swift 4.2 中,標準庫為我們提供了 CaseIterable 協議,可以實現這個需求,如下程式碼所示:

enum CompassDirection: CaseIterable {
    case north, south, east, west
}

print("There are \(CompassDirection.allCases.count) directions.")
// Prints "There are 4 directions."
let caseList = CompassDirection.allCases
                               .map({ "\($0)" })
                               .joined(separator: ", ")
// caseList == "north, south, east, west"
複製程式碼

實現 CaseIterable 的列舉在編譯器會自動合成 allCases 方法,且 allCases 陣列中的元素按 case 宣告的順序。不過如果列舉中的關聯值或者 @available 屬性,則需要自己重寫 allCases,如下程式碼所示:

enum CompassDirection: CaseIterable {

    case north, south, east
    case west(Int)

    static var allCases: [CompassDirection] {
        return [north, south, east, west(0)]
    }
}

print("There are \(CompassDirection.allCases.count) directions.")
// Prints "There are 4 directions."
let caseList = CompassDirection.allCases
    .map({ "\($0)" })
    .joined(separator: ", ")
// caseList == "north, south, east, west(0)"
複製程式碼

不可或缺的背景色

作者:Vong_HUST

最近遇到兩個和背景色有關的坑,和大家一起分享下。第一個頁面 A push到頁面 B 時,會莫名卡頓。一開始還以為是程式碼裡有耗時操作,然後就一行行遮蔽,遮蔽到什麼程式碼都沒有了,還是會卡頓,現在大概就如下圖所示。

覺得不可思議,因為 push 到其它頁面都不會發生這種情況,最後比對程式碼發現,其它頁面比 B 頁面唯一多的一個操作就是設定了 vc.view.background,只要設定了背景色不為 nil 且不為 [UIColor clearColor],就不會出現圖中的卡頓感。

另外一種情況就是,如果 collectionView 和 vc.view 背景色都是 nil 或者 clearColor,會出現一種現象就是 collectionView 只能響應有內容區域的點選事件,比如一個 (0, 0, 100, 100) 的 cell 上有一個 (0, 0, 20, 100)的 button,則只有按鈕區域是能點選響應事件,其它空白區域(20, 0, 80, 100)的區域點選是不會觸發 didSelect 回撥的,一旦設定了 vc.view 的背景色,就會恢復正常。

以上兩種現象都是由於背景色沒有處理妥當,導致頁面卡頓或無法響應事件,只要設定了背景色,即可恢復。具體原因還不清楚,有知道的老哥們可以在評論中指點一波~

注:提拉拉拉就是技術宅 大大對此的解釋是:不是卡頓,動畫本來就是這樣子的,後面的vc只推過去一點點。我曾經做過一個app,背景是spritekit的特效,然後整個app 所有vc 都是模態視窗蓋在特效上面,背景顏色全部都是clear ,push的動畫本身就是這個樣子的。

關注我們

歡迎關注我們的公眾號:iOS-Tips,也歡迎加入我們的群組討論問題。可以公眾號留言 iosflutter 等關鍵詞獲取入群方式。