iOS runtime 修復(fù)微博登錄進度條 UI 問題

在實現(xiàn)客戶端集成微博登錄功能時,點擊通過新浪微博登錄按鈕,此時

  • 假如設(shè)備上已經(jīng)安裝微博客戶端,會跳轉(zhuǎn)到微博客戶端進行授權(quán)登錄
  • 假如設(shè)備上尚無安裝微博客戶端,會在當(dāng)前客戶端中彈出微博的網(wǎng)頁登錄授權(quán)界面

在沒有安裝微博客戶端的情況中,加載網(wǎng)頁時出現(xiàn)了下圖中的 UI 展示 BUG:藍(lán)色進度條位置不對(原因后面會介紹)。


藍(lán)色進度條的位置很尷尬

仔細(xì)看了一下項目中的邏輯,確定不是自己的代碼問題之后,開始檢查是否是 WeiBoSDK 中的問題。WeiBoSDK 不開源,不過我們可以用第三方輔助開發(fā)工具 Reveal 試著檢查一下 WeiBoSDK 中的界面元素:

通過 Reveal 檢查出現(xiàn) Bug 的界面

通過 Reveal 的分析,發(fā)現(xiàn)這個進度條在其 superViewY 方向向下偏移 64 個點,比較敏感的開發(fā)者這時候應(yīng)該能察覺出來的這一 BUG 可能與狀態(tài)欄和導(dǎo)航欄有一定關(guān)系(在 iOS 中,statusBar.height + navigationBar.height = 64)。在當(dāng)前開發(fā)的客戶端中,presentingViewController(即彈出微博登錄頁面之前的那個 VC)是沒有導(dǎo)航欄的。

出現(xiàn)這種情況,可以通過Objective-C runtime 機制糾正一下進度條的垂直位置。
在項目工程中新建一個category : UIViewController+TWWBWebViewFix,這里的頭文件中沒有代碼邏輯,下面展示出實現(xiàn)文件中的完整代碼:

#import "UIViewController+TWWBWebViewFix.h"
#import <objc/runtime.h>

@implementation UIViewController (TWWBWebViewFix)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        // When swizzling a class method, use the following:
        //      'Class class = object_getClass((id)self);'
        // or   'Class class = object_getClass([self class]);'

        // Here swizzling a instance method:
        Class class = [self class];
        
        SEL originalSelector = @selector(viewWillAppear:);
        SEL swizzledSelector = @selector(TW_viewWillAppear:);
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        
        // 先嘗試給源方法添加實現(xiàn),這里是為了避免源方法沒有實現(xiàn)的情況
        BOOL didAddMethod = class_addMethod(class,
                                            originalSelector,
                                            method_getImplementation(swizzledMethod),
                                            method_getTypeEncoding(swizzledMethod));
        if (didAddMethod) {
            // 添加成功:將源方法的實現(xiàn)替換到交換方法的實現(xiàn)
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            // 添加失?。赫f明源方法已經(jīng)有實現(xiàn),直接將兩個方法的實現(xiàn)交換即可
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

#pragma mark - Method Swizzling

- (void)TW_viewWillAppear:(BOOL)animated {
    [self TW_viewWillAppear:animated];
  
    // 下面代碼中的字符串所對應(yīng)的類可以查看文末圖片給出的信息
    if ([self isKindOfClass:NSClassFromString(@"WBSDKAuthorizeWebViewController")]) {
        for (UIView *view in self.view.subviews) {
            if ([view isKindOfClass:NSClassFromString(@"WBSDKWebView")]) {
                for (UIView *subView in view.subviews) {
                    if ([subView isKindOfClass:NSClassFromString(@"WBSDKWebViewProgressView")]) {
                        subView.frame = CGRectMake(0, 0, kDeviceWidth, 3);
                    }
                }
            }
        }
    }
}

@end
在 Reveal 中檢查 V 與 C 對應(yīng)關(guān)系
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,881評論 25 709
  • 后會無期中有這樣一句臺詞:這輩子知道很多道理,卻仍然過不好這一生。 沒有去看這部電影,但是記住了這句臺詞。人往往就...
    e62a12d1b933閱讀 318評論 0 2
  • grains存儲于minion端,主要是minion在啟動時收集系統(tǒng)信息發(fā)送至master,可以自定義。pilla...
    詞窮又詞貧閱讀 991評論 0 2
  • 鄭重聲明:文章系原創(chuàng)首發(fā),文責(zé)自負(fù)。 我老媽39年(身份證)出生,老媽卻說是40年古歷九月二十巳時...
    堅持看得見閱讀 1,003評論 7 16

友情鏈接更多精彩內(nèi)容