說道JSPatch,相信iOS開發人員都不陌生,能實時修復iOS bug,想想都讓人激動。如果想詳細了解請參照大牛的GitHub:https://github.com/bang590/JSPatch/wiki;
這里主要想記錄在使用JSPatch過程中,有關CGRect的坑;
wiki中,JSPatch原生支持 CGRect / CGPoint / CGSize / NSRange 這四個 struct 類型,用 JS 對象表示:
// Obj-C
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 100, 100)];
[view setCenter:CGPointMake(10,10)];
[view sizeThatFits:CGSizeMake(100, 100)];
CGFloat x = view.frame.origin.x;
NSRange range = NSMakeRange(0, 1);
// JS
var view = UIView.alloc().initWithFrame({x:20, y:20, width:100, height:100})
view.setCenter({x: 10, y: 10})
view.sizeThatFits({width: 100, height:100})
var x = view.frame().x
var range = {location: 0, length: 1}
CGRect在OC當中的定義
struct CGRect {
CGPoint origin;
CGSize size;
};
typedef struct CGRect CGRect;
/* Points. */
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
/* Sizes. */
struct CGSize {
CGFloat width;
CGFloat height;
};
typedef struct CGSize CGSize;
發現在JS中不能這樣寫
var view = UIView.alloc().initWithFrame({origin:{x:20, y:20}, size:{width:100, height:100}})?
必須將結構體全部展開,這樣寫
var view = UIView.alloc().initWithFrame({x:20, y:20, width:100, height:100})
在給項目打補丁過程中,踩到如下坑:
_tableView.frame = CGRectMake(0, 20, [[UIScreen mainScreen] bounds].size.width-20, self.frame.size.height - 20);
將上面OC代碼轉JS如下(可以通過工具快速轉JS:http://bang590.github.io/JSPatchConvertor/,但不是100%轉成功,還是需手動轉)
self.valueForKey("_tableView").setFrame({x:0, y:20, width:UIScreen.mainScreen().bounds().size.width -20, height:self.frame().size.height -20});?
(注意:.size和 .width后面不能加(),不能寫成.size().width(),因為它們不是對象的property)
(上面的js有問題,會報錯誤:js exception, msg: undefined is not an object (evaluating 'UIScreen.__c("mainScreen")().__c("bounds")().size.width'))
正確寫法需將CGRect結構體完全展開:
struct CGRect {
CGFloat x;
CGFloat y;
CGFloat width;
CGFloat height;
};
self.valueForKey("_tableView").setFrame({x:0, y:20, width:UIScreen.mainScreen().bounds().width -20, height:self.frame().height -20});
至此,填坑完畢。
如果你有什么問題,歡迎在文章后留言,Thanks