swift - 按钮控件封装

import UIKit
import SnapKit
public enum UIButtonEdgeInsetsStyle {
        case Top         //图片在上,文字在下,垂直居中对齐
        case Left        //图片在左,文字在右,水平居中对齐
        case Bottom      //图片在下,文字在上,垂直居中对齐
        case Right       //图片在右,文字在左,水平居中对齐
}
extension UIButton {
    
    /// 快速初始化UIButton 包含默认参数,初始化过程可以删除部分默认参数简化方法
    /// - Parameters:
    ///   - title: 内容
    ///   - titleColor: 内容颜色
    ///   - font: 字体大小
    ///   - image: 按钮图片
    ///   - backgroundColor: 背景颜色
    ///   - supView: 被添加视图
    ///   - result: button对象
    ///   - action: 事件
    ///   - snapKitMaker: 约束
    /// - Returns: 返回UIButton对象
    @discardableResult
    public static func reloadCustemButton(title:String = "", titleColor:UIColor = UIColor.black, font:CGFloat = 14, image:String = "", backgroundColor:UIColor = UIColor.clear, supView: UIView? = nil, result: (( _ button:UIButton) -> ())? = nil, action: ((UIButton) -> ())? = nil, snapKitMaker: ((ConstraintMaker) -> Void)? = nil) -> UIButton {
        let tempButton = UIButton(type: .custom)
        tempButton.setTitle(title, for: .normal)
        tempButton.setTitleColor(titleColor, for: .normal)
        tempButton.titleLabel?.font = UIFont.systemFont(ofSize: font)
        tempButton.setImage(UIImage(named: image), for: UIControl.State.normal)
        tempButton.backgroundColor = backgroundColor
        
        guard let bt = result, let ac = action, let lv = supView, let sn = snapKitMaker else {
            return tempButton
        }
        lv.addSubview(tempButton)
        bt(tempButton)
        tempButton.snp.makeConstraints { make in
            sn(make)
        }
        tempButton.setOnClickedListener(listener: ac)
        return tempButton
    }
    
    
    /// 快速初始化UIButton 图片+文字
    /// - Parameters:
    ///   - style: 图片位置
    ///   - spacing: 图片与文字间距
    ///   - title: 标题
    ///   - showImage: 展示图片
    ///   - titleColor: 标题颜色
    ///   - font: 标题字体
    ///   - backgroundColor: 标题背景颜色
    ///   - target: 目标事件
    ///   - supView: 被添加视图
    ///   - result: button对象
    ///   - action: 事件
    ///   - snapKitMaker: 约束
    /// - Returns: 返回UIButton对象
    @discardableResult
    public static func reloadCustemEdgeInsetsStyleButton(style:UIButtonEdgeInsetsStyle,spacing: CGFloat,title:String? ,showImage:String?,titleColor:UIColor? ,font:CGFloat? ,backgroundColor:UIColor?, target:Any?, supView: UIView? = nil, result: (( _ button:UIButton) -> ())? = nil, action: ((UIButton) -> ())? = nil, snapKitMaker: ((ConstraintMaker) -> Void)? = nil) -> UIButton {
        let tempButton = UIButton(type: .custom)
        tempButton.setTitle(title, for: .normal)
        tempButton.setTitleColor(titleColor, for: .normal)
        tempButton.titleLabel?.font = UIFont.systemFont(ofSize: font ?? 15)
        tempButton.backgroundColor = backgroundColor
        tempButton.setImage(UIImage(named: showImage ?? ""), for: .normal)
        
        //根据style和space得到imageEdgeInsets和labelEdgeInsets的值
        var imageWidth:CGFloat = 0.0
        var imageHeight:CGFloat = 0.0
        if tempButton.imageView?.image != nil {
            imageWidth = (tempButton.imageView?.image?.size.width)!
            imageHeight = (tempButton.imageView?.image?.size.height)!
        }
        
        let titleStr:NSString = (tempButton.titleLabel?.text)! as NSString
        let font:UIFont = tempButton.titleLabel!.font
        let attributes = [NSAttributedString.Key.font:font]
        let option = NSStringDrawingOptions.usesLineFragmentOrigin
        let rect:CGRect = titleStr.boundingRect(with: CGSize(width: LONG_MAX, height: LONG_MAX), options: option, attributes: attributes , context: nil)
        
        let labelWidth:CGFloat = rect.width
        let labelHeight:CGFloat = rect.height
        
        let imageOffsetX:CGFloat = (imageWidth + labelWidth) / 2.0 - imageWidth/2.0
        let imageOffsetY:CGFloat = imageHeight / 2.0 + spacing / 2.0
        let labelOffsetX:CGFloat = (imageWidth + labelWidth / 2.0) - (imageWidth + labelWidth)/2.0
        let labelOffsetY:CGFloat = labelHeight / 2.0 + spacing / 2.0
        
        let tempWidth:CGFloat = max(labelWidth, imageWidth)
        let changedWidth:CGFloat = labelWidth + imageWidth - tempWidth
        let tempHeight:CGFloat = max(labelHeight, imageHeight)
        let changedHeight:CGFloat = labelHeight + imageHeight + spacing - tempHeight
        
        switch style {
        case .Top:
            tempButton.imageEdgeInsets = UIEdgeInsets(top: -imageOffsetY, left: imageOffsetX, bottom: imageOffsetY, right: -imageOffsetX)
            tempButton.titleEdgeInsets = UIEdgeInsets(top: labelOffsetY, left: -labelOffsetX, bottom: -labelOffsetY, right: labelOffsetX)
            tempButton.contentEdgeInsets = UIEdgeInsets(top: imageOffsetY, left: -changedWidth/2, bottom: changedHeight-imageOffsetY, right: -changedWidth/2)
            break
            
        case .Left:
            tempButton.imageEdgeInsets = UIEdgeInsets(top: 0, left: -spacing/2.0, bottom: 0, right: spacing/2.0)
            tempButton.titleEdgeInsets = UIEdgeInsets(top: 0, left: spacing/2.0, bottom: 0, right: -spacing/2.0)
            tempButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: spacing/2.0, bottom: 0, right: spacing/2.0)
            break
            
        case .Bottom:
            tempButton.imageEdgeInsets = UIEdgeInsets(top: imageOffsetY, left: imageOffsetX, bottom: -imageOffsetY, right: -imageOffsetX)
            tempButton.titleEdgeInsets = UIEdgeInsets(top: -labelOffsetY, left: -labelOffsetX, bottom: labelOffsetY, right: labelOffsetX)
            tempButton.contentEdgeInsets = UIEdgeInsets(top: changedHeight-imageOffsetY, left: -changedWidth/2, bottom: imageOffsetY, right: -changedWidth/2)
            break
            
        case .Right:
            tempButton.imageEdgeInsets = UIEdgeInsets(top: 0, left: labelWidth + spacing/2.0, bottom: 0, right: -(labelWidth + spacing / 2.0))
            tempButton.titleEdgeInsets = UIEdgeInsets(top: 0, left: -(imageWidth + spacing/2), bottom: 0, right: imageWidth + spacing/2)
            tempButton.contentEdgeInsets = UIEdgeInsets(top: 0, left: spacing/2.0, bottom: 0, right: spacing/2.0)
            break
        }
        guard  let ac = action, let lv = supView, let sn = snapKitMaker else {
            return tempButton
        }
        lv.addSubview(tempButton)
        tempButton.snp.makeConstraints { make in
            sn(make)
        }
        tempButton.setOnClickedListener(listener: ac)
        return tempButton
    }
}
extension UIButton {
    typealias UIButtonClickedListener = (UIButton) -> ()
    private struct Keys {
        static var clickedListener = "clickedListener"
    }
    private var clickedListener: UIButtonClickedListener? {
        get {
            return objc_getAssociatedObject(self, &Keys.clickedListener) as? UIButtonClickedListener
        }
        set(newValue) {
            objc_setAssociatedObject(self, &Keys.clickedListener, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    func setOnClickedListener(listener: @escaping UIButtonClickedListener) {
        removeTarget(self, action: #selector(touchUpInSideBtnAction), for: .touchUpInside)
        clickedListener = listener
        addTarget(self, action: #selector(touchUpInSideBtnAction), for: .touchUpInside)
    }
    @objc func touchUpInSideBtnAction() {
        if let listener = self.clickedListener {
            listener(self)
        }
    }
}


作者头像
文墨书生创始人

上一篇:swift - 文本控件封装
下一篇:swift - 图片控件封装

发表评论