iOS之JSPatch修改指定控件的文本

前言:最近用JSPatch修復(fù)了線上App一個(gè)UILabel文本寫錯(cuò)的Bug。其中過(guò)程記錄下來(lái),希望對(duì)大家有幫助。

場(chǎng)景

事情是這樣的,我們的客戶給我們反饋一個(gè)問(wèn)題,發(fā)來(lái)了一個(gè)照片。
如下圖顯示,我們的一個(gè)UILabel的文本寫錯(cuò)了。


解決問(wèn)題

使用我們鼎鼎大名的JSPatch熱修復(fù)。
思路一:重寫該UILabel所在的方法,但是該方法內(nèi)容太多了,改起來(lái)太麻煩了,不行。
思路二:在該UILabel所在類,新增一個(gè)方法遍歷self.view的所有控件,找到文本是身份證照片上傳的UILabel,然后修改這個(gè)UILabel的文本。但是在上圖中,有兩個(gè)文本是身份證照片上傳的UILabel,第二個(gè)是正確的,所以還要只處理第一個(gè),第二個(gè)不用管。
嗯,思路二不錯(cuò),就用你啦!

這里主要分三步走:
1.在本地寫OC代碼測(cè)試修改的效果
2.把OC代碼轉(zhuǎn)換成對(duì)應(yīng)的JS代碼,通過(guò)JSPatch在本地測(cè)試
3.在JSPatch官網(wǎng)上分發(fā)JS代碼到客戶端

第一步

在本地寫OC代碼測(cè)試修改的效果。
新增以下兩個(gè)方法,第二個(gè)方法遍歷self.view的所有控件,找到文本是身份證照片上傳的UILabel,然后修改這個(gè)UILabel的文本。

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    
    [self findSubView:self.view];
}

// 遍歷view的所有控件
-(void)findSubView:(UIView*)view
{v
    for (UIView* subview in view.subviews)
    {
        if ([subview isKindOfClass:[UILabel class]]) {
            UILabel *label = (UILabel *)subview;
            if ([label.text isEqualToString:@"身份證照片上傳"]) {
                label.text = @"銀行卡照片上傳";
                
            }
        }
        
        [self findSubView:subview];
    }
}

第二步

注釋掉上面的代碼,把上面的OC代碼轉(zhuǎn)為對(duì)應(yīng)的JS代碼,放在本地測(cè)試。
另外多說(shuō)一句JSPatch本地測(cè)試方法使用這個(gè)API。


上面OC代碼對(duì)應(yīng)的JS代碼

defineClass("TargetViewController", {
    viewWillAppear: function(animated) {
        self.super().viewWillAppear(animated);
        self.findSubView(self.view());
    }
}, {});

require("UILabel");

defineClass("TargetViewController", {
    findSubView: function(view) {
        var subviews = view.subviews().toJS();
        for (var i in view.subviews()) {
            var subview = subviews[i];
            if (subview.isKindOfClass(UILabel.class())) {
                var label = subview;
                if (label.text().isEqualToString("身份證照片上傳")) {
                    label.setText("銀行卡照片上傳");
                }
            }
            self.findSubView(subview);
        }
    }
}, {});

后來(lái)發(fā)現(xiàn)兩個(gè)文本是身份證照片上傳的UILabel都改成"銀行卡照片上傳"了,不符合我們的需求,所以還要修改一下js代碼,增加一個(gè)flag變量處理一下,只修改第一個(gè)UILabel。
最終的JS代碼如下:

defineClass("TargetViewController", {
    viewWillAppear: function(animated) {
        self.super().viewWillAppear(animated);
        self.findSubView(self.view());
    }
}, {});

require("UILabel");

var flag = 0;

defineClass("TargetViewController", {
    findSubView: function(view) {
        var subviews = view.subviews().toJS();
        for (var i in view.subviews()) {
            var subview = subviews[i];
            if (flag == 0 && subview.isKindOfClass(UILabel.class())) {
                var label = subview;
                if (label.text().isEqualToString("身份證照片上傳")) {
                    label.setText("銀行卡照片上傳");
                    flag++;
                }
            }
            self.findSubView(subview);
        }
    }
}, {});

重新測(cè)試運(yùn)行結(jié)果,大功告成!


第三方

把JS代碼丟到JSPatch官網(wǎng)分發(fā)到客戶端。

總結(jié)

在需要修改文本的控件所在的類,新增一個(gè)方法findSubView:,在viewWillAppear:中調(diào)用。在方法findSubView:中遍歷self.view,根據(jù)文本(如上述的身份證照片上傳)找到對(duì)應(yīng)的控件并做修改,如果文本是身份證照片上傳控件不唯一,可以在js代碼中增加一個(gè)flag變量做相應(yīng)的過(guò)濾處理。

最后,感謝@bang大神寫出如此牛逼的JSPatch!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容