美文网首页iOS 杂谈iOS
怎样给 UIButton 的 status 绑定 backGro

怎样给 UIButton 的 status 绑定 backGro

作者: 深度码农患者 | 来源:发表于2018-05-14 11:41 被阅读3次

    在开发中,经常能碰到需要给不同status设置不同的 backgroundColor 或者 borderColor ,如果新建一个子类的话可能会很麻烦,这时候,如果用 extension 仿照 setTitleColor 的方法新写一个 setBackGroundColor 的方法封装一下就感觉很惬意了,话不多说,上代码:
    先设置对外接口

       open func setBackgroudColor(_ color: UIColor, for state: UIControlState) {
            backGroundColorsForStates[state.rawValue] = color
            onStateChanged()
        }
    
        open func setBoarderColor(_ color: UIColor, for state: UIControlState) {
            boarderColorsForStates[state.rawValue] = color
            onStateChanged()
        }
    

    这时候出现了 boarderColorsForStates 属性和 onStateChanged 方法,status 绑定的 backGroundColor 需要存储到某个属性中,而 extension 是无法添加属性的,此时我们只好用简单的运行时方法,给 UIButton 添加一个简单的键值对属性,即

    private var boarderColorsForStates: [UInt: UIColor] {
            get {
                return (objc_getAssociatedObject(self, &UIButtonObjectKeys.boarderColorsForStates) as? [UInt: UIColor]) ?? [UInt: UIColor]()
            }
            set {
                objc_setAssociatedObject(self, &UIButtonObjectKeys.boarderColorsForStates, newValue, .OBJC_ASSOCIATION_RETAIN)
            }
        }
      
        private var backGroundColorsForStates: [UInt: UIColor] {
            get {
                return (objc_getAssociatedObject(self, &UIButtonObjectKeys.backGroundColorsForStates) as? [UInt: UIColor]) ?? [UInt: UIColor]()
            }
            set {
                objc_setAssociatedObject(self, &UIButtonObjectKeys.backGroundColorsForStates, newValue, .OBJC_ASSOCIATION_RETAIN)
            }
        }
    

    swift 中动态添加属性的 key 需要时 UnsafeRawPointer 格式的,UnsafeRawPointer 格式也就是类似于 OC 中的指针,即取 String 的指针作为 key 传过去。
    而 onStateChanged() 是在 UIButton status 状态改变时传作一些操作,例如设置 status 对应的 backGroundColor,即:

     private func onStateChanged() {
            if let color = self.backGroundColorsForStates[self.state.rawValue] {
                self.backgroundColor = color
            } else if let color = self.backGroundColorsForStates[UIControlState.normal.rawValue] {
                self.backgroundColor = color
            }
            
            if let color = self.boarderColorsForStates[self.state.rawValue] {
                self.borderColor = color
            } else if let color = self.boarderColorsForStates[UIControlState.normal.rawValue] {
                self.borderColor = color
            }
        }
    

    同样的,在设置 selected、highlighted、enabled 时也要调用这个方法,即重写这三个值的 set 方法和 get 方法:

    override open var isSelected: Bool {
            get {
                return super.isSelected
            }
            set {
                if newValue != isSelected {
                    super.isSelected = newValue
                    onStateChanged()
                }
            }
        }
        
        override open var isHighlighted: Bool {
            get {
                return super.isHighlighted
            }
            set {
                super.isHighlighted = newValue
                onStateChanged()
            }
        }
        
        override open var isEnabled: Bool {
            get {
                return super.isEnabled
            }
            set {
                if newValue != isSelected {
                    super.isEnabled = newValue
                    onStateChanged()
                }
            }
        }
    

    到这里,添加的这个 extension 就算大功告成了,你可以尝试给 UIButton 设置不同 status 下的 backGroundColor 等属性

    相关文章

      网友评论

        本文标题:怎样给 UIButton 的 status 绑定 backGro

        本文链接:https://www.haomeiwen.com/subject/qypddftx.html