说道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