iOS逆向之分析微信導航欄實現
最近需要實現微信的毛玻璃導航欄效果,嘗試了各種方式后還是有點差別,這在追求完美的設計師眼里是絕不能忍的,于是只好“看看”原作是怎么實現的。在逆向分析了微信的實現后,發現微信的實現十分特殊,文末會告訴大家答案:)
環境準備
- 一臺越獄設備
- OpenSSH 插件
- Cycript 插件
盤古支持 9.3.3 以下版本的越獄,越獄過程十分快速方便。越獄完成后還要在 Cydia 里搜索安裝 OpenSSH 和 Cycript 插件。OpenSSH 用以電腦遠程登錄 iPhone,Cycript 用來運行時鉤住應用程序。Cycript 允許開發者動態查看和修改正在運行的應用程序,更多介紹請查看 官網 。
環境準備完畢后,我們就可以開始逆向了。我手里的是 iOS 9.2.1 版本的越獄設備,以下都是用這個設備進行演示。
越獄有風險,建議使用備用機進行越獄,并且越獄前先備份資料
實際操作
首先打開電腦的命令行工具,執行 ssh 遠程登錄到 iPhone 手機上,默認連接密碼是 alpine,建議連上后修改默認密碼,修改命令是 passwd ,連上后的界面如下圖所示,
下面我們可以用 ps 命令查看微信進程,執行
ps -e|grepWeChat
結果如下圖,
這里我們能夠獲取到微信的沙盒路徑,進入到這個目錄后我們能看到如下的內容,主要是一些靜態圖片資源,如下圖:
Cycript
前面已經介紹了 Cycript,我們分析導航欄的實現就是需要借助這個工具, 官網 里有更多詳細說明。
首先在越獄手機上打開微信,然后使用 ps 命令獲取到微信的進程id,然后再輸入
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 里也用相同的做法嘗試了一下,顯示效果終于基本一致了,真是淚流滿面啊。關鍵代碼如下,
- (UIView *)blurBackView
{
if (_blurBackView == nil) {
_blurBackView = [UIViewnew];
_blurBackView.frame = CGRectMake(0, -20, SCREEN_WIDTH, 64);
CAGradientLayer *gradientLayer = [[CAGradientLayeralloc] init];
gradientLayer.frame = CGRectMake(0, 0, SCREEN_WIDTH, 64);
gradientLayer.colors = @[(__bridgeid)[UIColorcolorWithHex:0x040012 alpha:0.76].CGColor,(__bridgeid)[UIColorcolorWithHex:0x040012 alpha:0.28].CGColor];
gradientLayer.startPoint = CGPointMake(0, 0);
gradientLayer.endPoint = CGPointMake(0, 1.0);
[_blurBackView.layeraddSublayer:gradientLayer];
_blurBackView.userInteractionEnabled = NO;
_blurBackView.alpha = 0.5;
}
return _blurBackView;
}
blurBackView 的作用類似上述例子里的 view1,插入到 UINavigationBar 視圖里的最下方。
Cycript 還能執行一些其他操作,例如彈出 Alert 彈框,
結果如下
總結
本文整理了我探究微信導航欄實現的過程,發現微信導航欄的最終顯示效果是 由一個漸變圖層加系統提供的黑色毛玻璃組合顯示而成。
來自:http://ios.jobbole.com/91702/