有一个需求,相信业务需求中总会碰到的吧。按钮点击前背景色是这样的,点击后背景色又是这样的。那么有什么好的方法实现呢?
UIButton 的多个方法可以设置不同 controlState 下的 UI 状态,比如 setTitlecolor,setTitle 等。而 backgroundColor 却没有对应的方法可以进行设置,大多时候是通过 setBackgroundImage: 来设置不同状态下的“背景颜色”。UIView -> UIControl -> UIButton,继承链是这样的。而 backgroundColor 是 UIView 的一个属性。着实无法通过 backgroundColor 来直接设置不同状态下的背景色。兴许 UIKit 的开发工程师也是考虑到了这点,才选择了通过 setBackgroudImage:forState 来设置 UIButton 的不同背景色吧。
其实可以通过 Category 来进行方法扩展。一种是直接生成 不同状态下 backgroundColor 的图片,然后用 setBackgroudImage:forState 来设置,一种是直接记录不同状态下 backgroundColor,直接进行 setBackgroundColor 。
方法一
|
|
这是通过生成一张对应背景色图片从而间接设置背景图片来实现的。为了参考系统方法的,因此还是增多了一个 NSDictionary 来继续不同状态下的 backgroundColor,从而可以 ac_backgroundColorForState: 来得到对应的背景色。其实有点多余呐。(逃
方法二
|
|
这是通过记录不同状态下的 backgroundColor ,再去用 swizzle 去替换掉原先 setSelected: / setEnabled: / setHighlighted: 方法,从而得到实现。但是因为直接判定得到三种状态( UIControlStateSelected / UIControlStateDisabled / UIControlStateHighlighted )。因此只能实现这三种状态下的切换。
又由于如果是在按钮点击事件中改变 selected 状态,因此在 ac_setHighlighted 方法进行加以判断,这是因为在测试过程中,发现 selected 后还会再次 highlighted。
结尾
觉得在开发过程中,一些好的方法还是设置抽离出来的。比如方法一中的通过颜色得到一个 UIImage。这样的方法其实也可以以扩展方法的形式存在 UIImage 中。再者 Swizzle 的方法其实也可以进行一个抽离。
最后,再上个源码吧。ACKit/ UIButton+ACKit