分析
各看官请看 项目中有如下页面需要实现
优雅的实现方式
当然,最优雅的方式当属用UITableView
+Model
实现了,其中,“提供服务人员信息”、“订单服务信息”、“订单基本信息”为headerView
,其他的每一行“XXX:xxxxx”都是一个由model(Model
)控制的cell
,每个model
中包含title和detail字段,配置好数据源、代理(Controller
),具体的布局、样式逻辑就交给Cell(View
)来控制就OK了。
使用这种思想的方法,有一篇文章写的很好,推荐一下写一个iOS复杂表单的正确姿势
逗逼版实现方式
从图中可见,UILabel
的数量极多,而其中又有三种字体,分别为一级标题,二级标题和内容,其中有字号和字体粗细之分。
如果刚好碰巧,之前实现这个页面的程序员非常耐dou心bi,所有label都手动添加进去,这时候需求来了,要改Appearence。
如果手动设置字体,不仅重复代码多,而且不方便,more,需要改变字号、增加UILabel
等的话,将会十分麻烦。于是这时候可以利用OC之Runtime
之便利,实现功能代码以满足项目需求。
逗逼版补救步骤
主要思路
- 利用
Runtime
,取得当前类的属性列表 - 通过便利属性列表,获得title或detail的label属性名
- 利用
KVC
,通过属性名取得当前对象中的UILabel
实例 - 各种
setFont
、setColor
......
实现代码
unsigned int count = 0;
// 获得属性列表
objc_property_t *propertyList = class_copyPropertyList([self class], &count);
for(int i=0; i<count; i++) {
//取得属性名
objc_property_t property = propertyList[i];
const char* propertyName = property_getName(property);
//分情况进行不同的操作,此处分为detailLbl和titleLbl
if (strstr(propertyName, "Title")) {
UILabel *label = [self valueForKey:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]];
[label setFont:[UIFont systemFontOfSize:kZFFontSizeThirdlyTitle weight:UIFontWeightRegular]];
} else if (strstr(propertyName, "Detail")) {
UILabel *label = [self valueForKey:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]];
[label setFont:[UIFont systemFontOfSize:kZFFontSizeThirdlyTitle weight:UIFontWeightLight]];
}
}
// 释放资源
free(propertyList);
总结
然而,本文这种方式来使用Runtime
是一种非主流的方式,只在特定业务或者编程需求下使用,正确的Runtime
应用,是在用于那些字典模型互相转、实现多继承、添加属性关联对象等功能上,关于Runtime
更多详情可以看我的另一篇文章 Runtime学习笔记