没想到Swift里KVC还能有坑

移动开发 iOS
最近看了@南峰子_老驴写的ViewStyle。利用KVC的来简化抽取出控件设置style的代码,想达到一个css的效果。

起因

最近看了@南峰子_老驴写的ViewStyle。利用KVC的来简化抽取出控件设置style的代码,想达到一个css的效果。这个库用swift编写,使用起来大概这样:

class ViewController: UIViewController {



var tableView: UITableView?



override func viewDidLoad() {

super.viewDidLoad()

tableView = UITableView(frame: self.view.bounds)



tableView!.mi_styles = self.tableViewStyle



self.view.addSubview(tableView!)

}

}



// MARK: - Table View Style



extension ViewController {

var tableViewStyle: [Property: Any] {

return [

.rowHeight: 60.0,

.separatorStyle: UITableViewCellSeparatorStyle.singleLine,

.separatorColor: UIColor.lightGray,

.backgroundView: UIView(),

.separatorInset: UIEdgeInsets(top: 10.0, left: 5.0, bottom: 3.0, right: 10.0),

.cellLayoutMarginsFollowReadableWidth: true

]

}

}

阅读源码后发现有些属性在swift是不能直接KVC的,和OC有些区别。

Bool值:isHidden

先来看下正常的在swift中kvc的套路:

let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))

view.setValue(UIColor.blue, forKey: #keyPath(UIView.backgroundColor))

在swift 3中提供了#keypath()来省去开发者直接输入字符串的尴尬。

然而,如果这个属性是isHidden的话运行起来就会报错。 

 

 

​ 

控制台会输出错误:

‘[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key isHidden.’

提示我们没有isHidden这个属性。

那为什么我们平时没有注意到这个问题呢?

view.isHidden = true

这么写代码是没问题的。

其实就是Swift团队在升级3.0的时候keypath忘记做这个功能了。。。 

 

 

[[182955]]​ 

你可以安慰自己这个功能在swift 2.0的时候还是好好的。

如果读者写过OC这个原因很容易猜到。有些单独声明过getter的bool值直接kvc会报错。比如isHidden这样:

@property (nonatomic, getter=isHidden) BOOL hidden;

UIView上确实没有isHidden属性,那么怎么解决呢?只能回到老路上了:

view.setValue(true, forKey: "Hidden")

Enum

KVC在设置枚举的时候也会报错。 

 

 

 

错误提示的无效的参数类型。

因为setValue的参数类型是Any,所以这里参数可以是任意类型,没有类型检查。但是这毕竟是一个OC的方法,所以无法直接使用swift的类型(其实String到NSString也是有转换的,只是编译器帮我们做了这层转换)。

前面直接赋值的时候是正常的,但是调用KVC方法的时候编译器没有帮我们转。所以这里报错了。

那就只能自己手动转换了:

view.setValue(UIViewTintAdjustmentMode.automatic.rawValue, forKey: "tintAdjustmentMode")

在OC中的枚举其实就是对应几个数值,这里直接取出rawValue的值就可以正常使用了。

***我有一句话想对swift说: 

 

 

责任编辑:庞桂玉 来源: iOS大全
相关推荐

2021-01-27 18:13:35

日志nginx信息

2020-08-14 08:19:25

Shell命令行数据

2023-02-26 00:00:02

字符串分割String

2022-03-21 08:55:53

RocketMQ客户端过滤机制

2018-01-26 23:23:23

JDBC MySQL数据库

2017-12-26 15:41:26

2021-11-29 05:37:24

Windows Def操作系统微软

2009-04-28 07:48:29

盖茨打工基金会

2012-12-28 13:47:36

Raspberry PGeek

2022-01-05 17:13:28

监控HTTPS网站

2021-08-12 06:52:02

谷歌面试ArrayList

2023-10-31 12:29:25

模型训练

2019-03-08 10:08:41

网络程序猿代码

2021-02-25 17:58:26

Python 开发编程语言

2023-09-07 06:48:38

Intel显卡AMD

2022-11-02 07:46:31

GoFrameGcache缓存

2020-12-31 06:12:38

Siri Windows电脑

2018-10-22 15:29:50

2023-09-08 06:39:33

NVIDIA显卡行业

2015-07-15 13:00:31

英特尔开源
点赞
收藏

51CTO技术栈公众号