iOS中通過代碼生成view,不過是通過調(diào)用set方法對(duì)相關(guān)屬性進(jìn)行配置,由此可以考慮通過后臺(tái)傳遞相關(guān)數(shù)據(jù)進(jìn)行解析。
設(shè)計(jì)思路同RN、Weex原理類似,前者通過js進(jìn)行解析生成配置,我們這里通過對(duì)json解析進(jìn)行配置,盡管這種方式操作復(fù)雜,但是相對(duì)于前者性能更高優(yōu)(主要是不經(jīng)過js線程~~?。?。
目標(biāo)功能
可以實(shí)現(xiàn)在某個(gè)畫布(view)上進(jìn)行任意的生成特定ui樣式

實(shí)現(xiàn)原理
string-》類型配置
很多屬性都是非string類型,那么為了實(shí)現(xiàn)支持string轉(zhuǎn)到配置,需要我們寫出相關(guān)方法,博主采用的是繼承的方案
@interface RuntimeLabel : UILabel
@property (nonatomic,copy) NSString *alignment_string;
@property (nonatomic,copy) NSString *font_color_string;
@property (nonatomic,copy) NSString *font_size_string;
@property (nonatomic,copy) NSString *line_breakmode_string;
@end
利用runtime方法解析
相信大家都不愿意每個(gè)方法都去走switch或者if然后進(jìn)行方法分發(fā),由此引出runtime去調(diào)用set方法即可
NSString *setterName = v_key;
NSString *firstLetter = [NSString stringWithFormat:@"%c", [setterName characterAtIndex:0]];
setterName = [setterName substringFromIndex:1];
setterName = [NSString stringWithFormat:@"%@%@", firstLetter.uppercaseString, setterName];
setterName = [NSString stringWithFormat:@"set%@:", setterName];
SEL setter = NSSelectorFromString(setterName);
if ([subView respondsToSelector:setter]) {
((void (*)(id, SEL, id))objc_msgSend)(subView, setter, [viewDict objectForKey:v_key]);
}
專門解析view的類
有了上述準(zhǔn)備接下來就是對(duì)json文件的解析了,json文件是是對(duì)布局信息與view相關(guān)信息的描述
data_layoutArray json:[
{
"layout_style" : "horizontal_layout",
"frame_string" : "{{0,70},{200,100}}",
"bgcolor_hex_string" : "#00FF00",
"layout_views" : [
{
"layout_margin" : "{10,10}",
"layout_width_height" : "{30,30}",
"image_url" : "https:\/\/ss3.bdstatic.com\/70cFv8Sh_Q1YnxGkpoWK1HF6hhy\/it\/u=2515044163,2570565162&fm=27&gp=0.jpg",
"view_class" : "RuntimeUIImageView"
},
{
"image_url" : "https:\/\/ss3.bdstatic.com\/70cFv8Sh_Q1YnxGkpoWK1HF6hhy\/it\/u=2515044163,2570565162&fm=27&gp=0.jpg",
"frame_string" : "{{50,10},{30,30}}",
"view_class" : "RuntimeUIImageView"
},
{
"layout_margin" : "{10,10}",
"layout_width_height" : "{30,30}",
"image_url" : "https:\/\/ss3.bdstatic.com\/70cFv8Sh_Q1YnxGkpoWK1HF6hhy\/it\/u=2515044163,2570565162&fm=27&gp=0.jpg",
"view_class" : "RuntimeUIImageView"
},
{
"layout_style" : "horizontal_layout",
"frame_string" : "{{0,50},{100,50}}",
"bgcolor_hex_string" : "#FF0000",
"layout_views" : [
{
"layout_margin" : "{10,10}",
"layout_width_height" : "{30,30}",
"image_url" : "https:\/\/ss3.bdstatic.com\/70cFv8Sh_Q1YnxGkpoWK1HF6hhy\/it\/u=2515044163,2570565162&fm=27&gp=0.jpg",
"view_class" : "RuntimeUIImageView"
}
]
}
]
},
{
"layout_style" : "vertical_layout",
"frame_string" : "{{0,180},{300,420}}",
"bgcolor_hex_string" : "#0000FF",
"layout_views" : [
{
"layout_margin" : "{10,10}",
"layout_width_height" : "{200,200}",
"image_url" : "https:\/\/ss3.bdstatic.com\/70cFv8Sh_Q1YnxGkpoWK1HF6hhy\/it\/u=2515044163,2570565162&fm=27&gp=0.jpg",
"childs" : [
{
"layout_style" : "vertical_layout",
"frame_string" : "{{10,10},{180,180}}",
"bgcolor_hex_string" : "#FF0000",
"layout_views" : [
{
"layout_margin" : "{60,20}",
"layout_width_height" : "{60,60}",
"image_url" : "https:\/\/ss3.bdstatic.com\/70cFv8Sh_Q1YnxGkpoWK1HF6hhy\/it\/u=2515044163,2570565162&fm=27&gp=0.jpg",
"view_class" : "RuntimeUIImageView"
},
{
"layout_margin" : "{60,20}",
"layout_width_height" : "{60,60}",
"image_url" : "https:\/\/ss3.bdstatic.com\/70cFv8Sh_Q1YnxGkpoWK1HF6hhy\/it\/u=2515044163,2570565162&fm=27&gp=0.jpg",
"view_class" : "RuntimeUIImageView"
}
]
}
],
"view_class" : "RuntimeUIImageView"
},
{
"image_url" : "https:\/\/ss3.bdstatic.com\/70cFv8Sh_Q1YnxGkpoWK1HF6hhy\/it\/u=2515044163,2570565162&fm=27&gp=0.jpg",
"frame_string" : "{{10,220},{90,90}}",
"view_class" : "RuntimeUIImageView"
},
{
"layout_margin" : "{10,10}",
"layout_width_height" : "{90,90}",
"image_url" : "https:\/\/ss3.bdstatic.com\/70cFv8Sh_Q1YnxGkpoWK1HF6hhy\/it\/u=2515044163,2570565162&fm=27&gp=0.jpg",
"view_class" : "RuntimeUIImageView"
}
]
},
{
"layout_margin" : "{300,80}",
"layout_width_height" : "{30,30}",
"image_url" : "https:\/\/ss3.bdstatic.com\/70cFv8Sh_Q1YnxGkpoWK1HF6hhy\/it\/u=2515044163,2570565162&fm=27&gp=0.jpg",
"view_class" : "RuntimeUIImageView"
}
]
博主通過對(duì)此信息的描述構(gòu)造了基本的view(UIButton、UILabel支持富文本、UIImageVIew、UIView)以及水平垂直布局進(jìn)行了解析,解析后的效果如下:

對(duì)于view與label多種樣式實(shí)現(xiàn)效果如下:

結(jié)論
1.用作展示view是可以滿足的
2.具有同類型的操作的功能是可以滿足的(如點(diǎn)擊圖片進(jìn)行瀏覽)
3.打點(diǎn)功能是可以滿足的(打點(diǎn)信息需要后臺(tái)傳入)
不能滿足的是手勢(shì)交互(單個(gè)view移動(dòng)、手勢(shì)滑動(dòng)),同上如果是同類型的操作可以引入通過后臺(tái)控制是否開啟