UIButton扩展分类,添加自己封装的方法和属性

import UIKit

public final class ButtonMake<Base> {
    
    public let base : Base
    public init(_ base : Base){
        self.base = base
    }
    
    @discardableResult
    func makeButton(completion: ((UIButton)-> ())) ->UIButton{
        let btn = UIButton.init(type: UIButtonType.custom)
        completion(btn)
        return btn
    }
}
public protocol ButtonMakeCompatible {
    
}

public extension ButtonMakeCompatible {

    public static var dx : ButtonMake<UIButton> {
        get { return ButtonMake(UIButton()) }
    }
}

extension UIButton : ButtonMakeCompatible {
    
}

//====================分割线===================

public final class ButtonChain<Base> {
    
    public let base : Base
    public init(_ base : Base){
        self.base = base
    }
}

public protocol ButtonChainCompatible {
    
}

public extension ButtonChainCompatible {
    public var dx : ButtonChain<Self> {
        get { return ButtonChain(self) }
    }
}

extension UIButton : ButtonChainCompatible {
    
}



extension ButtonChain where Base: UIButton{
    

    @discardableResult
    func systemFont(ofSize fontSize: CGFloat) -> ButtonChain {
        base.titleLabel?.font = UIFont.systemFont(ofSize: fontSize)
        return self
    }
    
    @discardableResult
    func boldSystemFont(ofSize fontSize: CGFloat) -> ButtonChain {
        base.titleLabel?.font = UIFont.boldSystemFont(ofSize: fontSize)
        return self
    }
    
    @discardableResult
    func title(_ title: String?, for state: UIControlState...) -> ButtonChain {
        state.forEach { base.setTitle(title, for: $0) }
        return self
    }
    
    @discardableResult
    func titleColor(_ color: UIColor?, for state: UIControlState...) -> ButtonChain {
        state.forEach { base.setTitleColor(color, for: $0) }
        return self
    }
    
    @discardableResult
    func image(_ image: UIImage?, for state: UIControlState...) -> ButtonChain {
        state.forEach { base.setImage(image, for: $0) }
        return self
    }
    
    @discardableResult
    func backgroundImage(_ image: UIImage?, for state: UIControlState...) -> ButtonChain {
        state.forEach { base.setBackgroundImage(image, for: $0) }
        return self
    }
    
    @discardableResult
    func attributedTitle(_ attributedTitle: NSAttributedString?, for state: UIControlState...) -> ButtonChain {
        state.forEach { base.setAttributedTitle(attributedTitle, for: $0) }
        return self
    }
    
    @discardableResult
    func titleEdgeInsets(_ edgeInsets: UIEdgeInsets) -> ButtonChain {
        base.titleEdgeInsets = edgeInsets
        return self
    }
    
    @discardableResult
    func titleEdgeInsets(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> ButtonChain {
        base.titleEdgeInsets = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
        return self
    }
    
    @discardableResult
    func imageEdgeInsets(_ edgeInsets: UIEdgeInsets) -> ButtonChain {
        base.imageEdgeInsets = edgeInsets
        return self
    }
    
    @discardableResult
    func imageEdgeInsets(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> ButtonChain {
        base.imageEdgeInsets = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
        return self
    }

    @discardableResult
    func tag(_ tag: Int) -> ButtonChain {
        base.tag = tag
        return self
    }
    
    @discardableResult
    func frame(_ frame: CGRect) -> ButtonChain {
        base.frame = frame
        return self
    }
    
    @discardableResult
    func frame(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) -> ButtonChain {
        base.frame = CGRect(x: x, y: y, width: width, height: height)
        return self
    }
    
    @discardableResult
    func bounds(_ bounds: CGRect) -> ButtonChain {
        base.bounds = bounds
        return self
    }
    
    @discardableResult
    func center(_ center: CGPoint) -> ButtonChain {
        base.center = center
        return self
    }
    
    @discardableResult
    func center(x: CGFloat, y: CGFloat) -> ButtonChain {
        base.center = CGPoint(x: x, y: y)
        return self
    }
    
    @discardableResult
    func backgroundColor(_ backgroundColor: UIColor) -> ButtonChain {
        base.backgroundColor = backgroundColor
        return self
    }
    
    @discardableResult
    func contentMode(_ contentMode: UIViewContentMode) -> ButtonChain {
        base.contentMode = contentMode
        return self
    }
    
    @discardableResult
    func clipsToBounds(_ clipsToBounds: Bool) -> ButtonChain {
        base.clipsToBounds = clipsToBounds
        return self
    }
    
    @discardableResult
    func alpha(_ alpha: CGFloat) -> ButtonChain {
        base.alpha = alpha
        return self
    }
    
    @discardableResult
    func isHidden(_ isHidden: Bool) -> ButtonChain {
        base.isHidden = isHidden
        return self
    }
    
    @discardableResult
    func isOpaque(_ isOpaque: Bool) -> ButtonChain {
        base.isOpaque = isOpaque
        return self
    }
    
    @discardableResult
    func isUserInteractionEnabled(_ isUserInteractionEnabled: Bool) -> ButtonChain {
        base.isUserInteractionEnabled = isUserInteractionEnabled
        return self
    }
    
    @discardableResult
    func tintColor(_ tintColor: UIColor) -> ButtonChain {
        base.tintColor = tintColor
        return self
    }
    
    @discardableResult
    func cornerRadius(_ cornerRadius: CGFloat) -> ButtonChain {
        base.layer.cornerRadius = cornerRadius
        return self
    }
    
    @discardableResult
    func masksToBounds(_ masksToBounds: Bool) -> ButtonChain {
        base.layer.masksToBounds = masksToBounds
        return self
    }
    
    @discardableResult
    func borderWidth(_ borderWidth: CGFloat) -> ButtonChain {
        base.layer.borderWidth = borderWidth
        return self
    }
    
    @discardableResult
    func borderColor(_ borderColor: UIColor) -> ButtonChain {
        base.layer.borderColor = borderColor.cgColor
        return self
    }
    
    @discardableResult
    func shadowColor(_ shadowColor: UIColor?) -> ButtonChain {
        base.layer.shadowColor = shadowColor?.cgColor
        return self
    }
    
    @discardableResult
    func shadowOpacity(_ shadowOpacity: Float) -> ButtonChain {
        base.layer.shadowOpacity = shadowOpacity
        return self
    }
    
    @discardableResult
    func shadowOffset(_ shadowOffset: CGSize) -> ButtonChain {
        base.layer.shadowOffset = shadowOffset
        return self
    }
    
    @discardableResult
    func shadowRadius(_ shadowRadius: CGFloat) -> ButtonChain {
        base.layer.shadowRadius = shadowRadius
        return self
    }
    
    @discardableResult
    func shadowPath(_ shadowPath: CGPath?) -> ButtonChain {
        base.layer.shadowPath = shadowPath
        return self
    }
    
    @discardableResult
    func addSubview(_ view: UIView) -> ButtonChain {
        base.addSubview(view)
        return self
    }
    
    @discardableResult
    func addGestureRecognizer(_ gestureRecognizer: UIGestureRecognizer) -> ButtonChain {
        base.addGestureRecognizer(gestureRecognizer)
        return self
    }
    
    @discardableResult
    func addConstraint(_ constraint: NSLayoutConstraint) -> ButtonChain {
        base.addConstraint(constraint)
        return self
    }
    
    @discardableResult
    func addConstraints(_ constraints: [NSLayoutConstraint]) -> ButtonChain {
        base.addConstraints(constraints)
        return self
    }
    
        @discardableResult
    func isEnabled(_ isEnabled: Bool) -> ButtonChain {
        base.isEnabled = isEnabled
        return self
    }
    
    @discardableResult
    func isSelected(_ isSelected: Bool) -> ButtonChain {
        base.isSelected = isSelected
        return self
    }
    
    @discardableResult
    func isHighlighted(_ isHighlighted: Bool) -> ButtonChain {
        base.isHighlighted = isHighlighted
        return self
    }
    
    @discardableResult
    func addTarget(_ target: Any?, action: Selector, for controlEvents: UIControlEvents) -> ButtonChain {
        base.addTarget(target, action: action, for: controlEvents)
        return self
    }

}

用法示例

let btn = UIButton.init(type: UIButtonType.custom)
btn.dx.title("Hello--", for: UIControlState.normal)
btn.dx.titleColor(UIColor.green, for: UIControlState.normal)
btn.dx.systemFont(ofSize: 12)
view.addSubview(btn)

这样的写法跟原生写法没啥区别,看起来整齐了一些,使用了命名空间.dx这样区别于系统方法,方便其他开发者一眼就看出来这个是使用了非原生的API

还可以这样子写

let button = UIButton.dx.makeButton { (button) in
    button.dx.title("Hello World", for: UIControlState.normal)
    .titleColor(UIColor.blue, for: UIControlState.normal)
    .systemFont(ofSize: 12)
    .frame(x: 100, y: 100, width: 200, height: 50)
    .backgroundColor(UIColor.lightGray)
    .cornerRadius(10)
    .masksToBounds(true)
    .addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
}
view.addSubview(button)

@objc private func buttonAction() {
    print("Hello World")
}

注:代码UIButton.dx这里会创建一个新的button

这样写代码看起来非常的整齐优雅,通过链式的调用快速的创建了一个button,当然这里开发效率提升了,对于App来说,会损耗一点点性能,这个对于我们现在智能手机来说可以忽略不计的

这里我建议常用控件,比如UILabel,UIButton,UIView,UITableView,UIImageView等常用控件做这种扩展,方便开发者纯代码的书写,而不常用的比如UIPageControl等,可以不做扩展.