最近需要實現微信的毛玻璃導航欄效果,嘗試了各種方式後還是有點差別,這在追求完美的設計師眼裡是絕不能忍的,於是只好“看看”原作是怎麼實現的。在逆向分析了微信的實現後,發現微信的實現十分特殊,文末會告訴大家答案:)
環境準備
- 一臺越獄裝置
- OpenSSH 外掛
- Cycript 外掛
盤古支援 9.3.3 以下版本的越獄,越獄過程十分快速方便。越獄完成後還要在 Cydia 裡搜尋安裝 OpenSSH 和 Cycript 外掛。OpenSSH 用以電腦遠端登入 iPhone,Cycript 用來執行時鉤住應用程式。Cycript 允許開發者動態檢視和修改正在執行的應用程式,更多介紹請檢視官網。
環境準備完畢後,我們就可以開始逆向了。我手裡的是 iOS 9.2.1 版本的越獄裝置,以下都是用這個裝置進行演示。
越獄有風險,建議使用備用機進行越獄,並且越獄前先備份資料
實際操作
首先開啟電腦的命令列工具,執行 ssh
遠端登入到 iPhone 手機上,預設連線密碼是 alpine,建議連上後修改預設密碼,修改命令是 passwd
,連上後的介面如下圖所示,
下面我們可以用 ps
命令檢視微信程式,執行
1 |
ps -e|grep WeChat |
結果如下圖,
這裡我們能夠獲取到微信的沙盒路徑,進入到這個目錄後我們能看到如下的內容,主要是一些靜態圖片資源,如下圖:
Cycript
前面已經介紹了 Cycript,我們分析導航欄的實現就是需要藉助這個工具,官網裡有更多詳細說明。
首先在越獄手機上開啟微信,然後使用 ps
命令獲取到微信的程式id,然後再輸入
1 |
cycript -p xxx |
當我們看到命令列介面出現 cy#
就說明我們已成功 hook 住微信程式,這個過程如下圖所示,
上面這張圖裡的資訊很豐富,展示了我是如何一步一步獲取到 ContactsViewController
。在最下方我列印出了UINavigationBar
的檢視層級關係,我們能看到控制導航欄樣式的檢視有兩個,一個是view1,一個是view2,其中view2應該是系統自帶的毛玻璃效果。
為了驗證這個想法,我們來做一些設定。首先將 view1 的 alpha 設定為0,結果如下圖,
左邊的是 view1.alpha = 0,右邊的是原來的樣式。我們能看到導航欄的顏色變淺了,頁面滑動時的毛玻璃穿透效果很明顯。我在自己的 App 裡也實現了一樣的效果,做法是將 barStyle 設定成 UIBarStyleBlack。
列印出微信的導航欄型別屬性,發現也是 UIBarStyleBlack
至此,我們基本能確定微信就是在系統提供的黑色風格導航欄上做了一些處理。那到底是做了什麼處理呢?我們繼續往下看。
將 view1 的 alpha 還原回去,再將 view2 的 alpha 設定為 0,會看到下圖的樣式,
再把 view2 的實際顯示的圖層列印出來,發現這是一個漸變圖層
至此,我們發現微信導航欄的最終顯示效果是由一個漸變圖層加系統提供的黑色毛玻璃組合顯示而成。
根據這些資訊,我在 App 裡也用相同的做法嘗試了一下,顯示效果終於基本一致了,真是淚流滿面啊。關鍵程式碼如下,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
- (UIView *)blurBackView { if (_blurBackView == nil) { _blurBackView = [UIView new]; _blurBackView.frame = CGRectMake(0, -20, SCREEN_WIDTH, 64); CAGradientLayer *gradientLayer = [[CAGradientLayer alloc] init]; gradientLayer.frame = CGRectMake(0, 0, SCREEN_WIDTH, 64); gradientLayer.colors = @[(__bridge id)[UIColor colorWithHex:0x040012 alpha:0.76].CGColor,(__bridge id)[UIColor colorWithHex:0x040012 alpha:0.28].CGColor]; gradientLayer.startPoint = CGPointMake(0, 0); gradientLayer.endPoint = CGPointMake(0, 1.0); [_blurBackView.layer addSublayer:gradientLayer]; _blurBackView.userInteractionEnabled = NO; _blurBackView.alpha = 0.5; } return _blurBackView; } |
blurBackView
的作用類似上述例子裡的 view1,插入到 UINavigationBar
檢視裡的最下方。
Cycript 還能執行一些其他操作,例如彈出 Alert 彈框,
結果如下
總結
本文整理了我探究微信導航欄實現的過程,發現微信導航欄的最終顯示效果是由一個漸變圖層加系統提供的黑色毛玻璃組合顯示而成。如果有其他實現方式也可以給我留言,學習一下~
逆向的用法肯定不止這一種場景,結合 class-dump 還能做更深入的分析。如果感興趣也可以自己實際操作體驗一下,enjoy~
轉載請標註出處,有任何疑問都可聯絡我,歡迎探討。
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!
任選一種支付方式