iOS动态化配置页面(页面可后端或用户自己编辑定制)

如何做到页面动态化配置解决方案

Demo:源码地址:https://mp.csdn.net/mp_download/manage/download/UpDetailed?spm=3001.5299

1.前言:页面动态化配置和所谓的模块化/组件化是不同的概念,最下方正好也提供出关于模块/组件的不错的文章

2.下面我要将的是页面的动态化配置,所谓的动态化配置是指当前页面的呈现的任何形式,布局,那些控件,数据显示,刷新机制,跳转形式,传参形式,包括父控件上的子控件样式/事件,子控件上的子控件的样式/事件,子控件的子控件的子控件…….

3.总之一句话,开发者对于UI的处理只需要绘制一个label,一个imageView,或者已经既定的不需要改变的大的组合控件,比如轮播,日历,瀑布流等

4.适用场景:

1)页面需要运营频繁调整的,比如那些东西需要展示,那些东西需要隐藏,那些模块位置需要调整等等

2)类似淘宝店铺可用户自己编辑页面,设置装修风格的

3)类似淘宝,可以控制任意模块的展示以及功能模块的搜索

针对第一点补充说明两点:运营控制页面那些东西是否展示或位置调整,很多人觉得通过后端返回tableView的data就可以做到,OK这里仅仅是控制了列表那些整体一大块的section或者row需不需要,但是无法控制单行cell上子控件都有那些,并且他们的的布局,显示以及事件。如果是scrollView更是如此了。

通过上述的介绍,我们应该如何设置我们的动态化配置方案呢?

两个思路:

思路1:页面所有的配置,全部通过后端下发,返回我要的数据

这里的弊端:如果是长列表,自动化配置的地方很多,那么后端就需要维护大量的数据,包括复杂的数据结构

1.数据结构包括到了label的间距,颜色,文字大小等等所有属性,以及其他控件的属性,这里的数据量是很大的导致在该页面请求接口耗时较久,且无法做到预渲染机制。一旦接口报错则页面就出现无数据或白屏的显示。

2.通过配置文件来控制。和运营及业务规定好默认样式,和后端约定好json格式,配置好默认文件放在项目中,首次下载读取本地json

如果运营需要控制页面的显示与隐藏,如何更新配置文件

1)app启动请求接口,接口只有一个字段,告知需要不需要更新json文件,需要则更新,不需要则跳过

2)如果app集成了推送功能,json数据可以通过推送下发,1.透传能力强,随时接收 2.推送内部自己维护socket 更加实时  3.不需要开发者主动频次调用接口来获知要不要更新

3)如果app没有推送就在页面每次请求是否需要更新的接口(即便这里页面变化很慢也无所谓,因为用户不知道ta的页面展示正在被后端控制,如果很快变化,比如一个模块突然没了,或者突然多了个模块,人家还以为见鬼了呢….)

4)页面需要集成路由来控制页面的跳转和传参,路由的选择根据上述链接的组件化,自己选择一个就好。

5)用户自定义编辑更新本地文件即可

下面给出一个json文件样式

{\"type\":\"view\",\"x\":15,\"y\":90,\"width\":350,\"height\":300,\"backgroundColor\":\"#f0f0f0\",\"subViews\":[{\"type\":\"view\",\"x\":0,\"y\":0,\"width\":150,\"height\":100,\"backgroundColor\":\"#eaeaea\",\"subViews\":[{\"type\":\"view\",\"x\":0,\"y\":0,\"width\":50,\"height\":50,\"backgroundColor\":\"#aaaaaa\",\"subViews\":[]},{\"type\":\"view\",\"x\":55,\"y\":0,\"width\":50,\"height\":50,\"backgroundColor\":\"#aaaaaa\",\"subViews\":[]},{\"type\":\"label\",\"x\":0,\"y\":50,\"width\":50,\"backgroundColor\":\"#66631e\",\"lineSpacing\":5,\"textList\":[{\"text\":\"基于Json的动态化\",\"textSize\":10,\"textColor\":\"#ff631e\"},{\"text\":\"处理方案\",\"textSize\":12,\"textColor\":\"#22631e\"}]}]},{\"type\":\"view\",\"x\":155,\"y\":0,\"width\":150,\"height\":100,\"backgroundColor\":\"#eaeaea\",\"subViews\":[{\"type\":\"view\",\"x\":0,\"y\":0,\"width\":50,\"height\":50,\"backgroundColor\":\"#aaaaaa\",\"subViews\":[]},{\"type\":\"imageView\",\"isNeedCallBack\":1,\"x\":55,\"y\":0,\"width\":50,\"height\":50,\"backgroundColor\":\"#aaaaaa\",\"url\":\"http://v1.qzone.cc/avatar/201503/08/11/30/54fbc2419012c836.jpg%21200x200.jpg\"}]}]}

这是具体控制页面的控件以及属性

其余字段还有很多需要开发者自己定义,比如当前模块的名称(中文名)虽然用不到但是还是需要的,给运营区分使用,比如模块的ID,tableView的话模块应该放在第几区,是否需要使用,scrollView或者View需要定义Frame,各个控件的间距等等。包括控件属于哪一个具体的类,比如当前控件类名,如UIImageView  SGImageView ,模块的数据接口,请求方式等等

借助下面两个Json格式化工具,将会大大简化这一过程。

http://www.bejson.com/jsoneditoronline/

http://www.bejson.com/zhuanyi/

解析了Json,就会生成了对应的Model对象,每个控件都有自己的Model,而App端的JsonView就是用来根据这个key-Value值,来配置View的属性的。

1、JsonModel

iOS的基础控件都是基于UIView的,所以我们也需要针对UIView的公共属性,抽象出一层顶层JsonModel,这些包括UIView的x、y、width、Height、background等,当然还有很多属性等待着未来扩展。为了区别生成不同的UIView控件,在此model中还有个type属性,根据此字端来判断需要渲染哪种控件,以后所有子ViewModel都要继承此基类Model。

2、JsonView与JsonBaseView

JsonViewModel最重要的一个属性是如下这个字端:

@property (nonatomic, strong) NSArray <MDJsonModel *> *subViews;

这里也是生成嵌套View的关键。JsonBaseView是暴露给业务使用的baseView,解析Json的任务主要在这里进行,里面生成了嵌套JsonView以及各种Json子View。嵌套代码实现是在这里:

- (void)creatJsonSubViewsWith:(MDJsonViewModel *)model inView:(UIView *)rootView;

在这里,我们将初始化了要生成的子View,并将model传进去,进行属性的配置。

3、JsonLabel与JsonLabelModel

JsonLabel是一个可以单独拿出来的富文本组件,通过JsonLabelModel,生成NSMutableAttributedString可以完美实现动态富文本效果。

4、JsonImageView与JsonImageViewModel

JsonImageView采取加载url和本地图片的两种方式,你只需要配置不同的参数即可。但是常常我们需要获取图片这种异步数据的回调消息,所以在此我特意为此做了处理,你在拼写Json时,只是传入isNeedCallBack的值即可。设置了此属性,实现如下回调代码,即可获取异步资源的所有回调信息:

  [_jsonView obtainResult:^(MDJsonNotificationResultModel *result) {

        NSLog(@"%@",result);

    }];

为此,特意封装了MDJsonNotificationResultModel,目前只支持图片的回调信息,后续待扩展。

5、后续扩展

如果你下载了此项目代码,而且此项目代码不能满足你的业务需求时,你需要扩展这些控件或者已有控件的属性,你可以大概遵循下面几个步骤即可完成:

(1)MDJsonMappers中注册,如下:

- (NSDictionary *)allViewMappers

{

    return @{

             @"view":@"MDJsonViewModel",

             @"label":@"MDJsonLabelModel",

             @"imageView":@"MDJsonImageViewModel"

             };

}

未经注册的view组件是不能被解析的。

(2)继承MDJsonModel,定义自己控件的customModel类型;

(3)继承原生控件,创建customView,解析customModel即可;

五、相关开发工具

前面介绍过,由于直接书写Json,转义Json是一个十分繁琐的过程,一不小心就会解析失败。

在这里http://www.bejson.com/jsoneditoronline/,你可以拼写自己的Json,并结构化它,便于你直观的书写View的层级;其次,写完Json之后,还需要用http://www.bejson.com/zhuanyi/进行转义,才能生成最终的客户端传输Json字符串。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,188评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,464评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,562评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,893评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,917评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,708评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,430评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,342评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,801评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,976评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,115评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,804评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,458评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,008评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,135评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,365评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,055评论 2 355

推荐阅读更多精彩内容