30.怎样在Swift中添加运行时属性?

  和OC一样,Swift中也可以添加运行时属性。下面将提供一个完整的例子,演示如何给按钮点击事件添加运行时属性。

1.示例

import UIKit

var s_GofButtonTouchDownKey = "s_GofButtonTouchDownKey";
var s_GofButtonTouchUpKey = "s_GofButtonTouchUpKey";

extension UIControl
{
    /// 按钮TouchDown
    var gof_touchDown: GofBtnClickBlock? {
        get{
            let touchDown = objc_getAssociatedObject(self, &s_GofButtonTouchDownKey);
            let dealTouchDown = unsafeBitCast(touchDown, GofBtnClickBlock.self);
            return dealTouchDown;
        }
        set(touchDown)
        {
            let dealTouchDown: AnyObject = unsafeBitCast(touchDown, AnyObject.self);
            objc_setAssociatedObject(self, &s_GofButtonTouchDownKey, dealTouchDown, .OBJC_ASSOCIATION_COPY);
            
            self.removeTarget(self, action: #selector(onTouchDown(_:)), forControlEvents: .TouchDown);
            self.addTarget(self, action: #selector(onTouchDown(_:)), forControlEvents: .TouchDown)
        }
    }
    
    /// 按钮TouchUpInside
    var gof_touchUpInside: GofBtnClickBlock? {
        get{
            let touchUp = objc_getAssociatedObject(self, &s_GofButtonTouchUpKey);
            let dealTouchUp = unsafeBitCast(touchUp, GofBtnClickBlock.self);
            return dealTouchUp;
        }
        set(touchUp)
        {
            let dealTouchUp: AnyObject = unsafeBitCast(touchUp, AnyObject.self);
            objc_setAssociatedObject(self, &s_GofButtonTouchUpKey, dealTouchUp, .OBJC_ASSOCIATION_COPY);
            
            self.removeTarget(self, action: #selector(onTouchUp(_:)), forControlEvents: .TouchUpInside);
            self.addTarget(self, action: #selector(onTouchUp(_:)), forControlEvents: .TouchUpInside)
        }
    }
    
    /**
     按钮TouchDown事件处理
     
     - parameter btn: 按钮
     */
    func onTouchDown(btn: UIButton) -> Void
    {
        let touchDown = self.gof_touchDown;

        if touchDown != nil
        {
            touchDown!(btn);
        }
        
    }
    
    /**
     按钮TouchUpInside事件处理
     
     - parameter btn: 按钮
     */
    func onTouchUp(btn: UIButton) -> Void
    {
        let touchUp = self.gof_touchUpInside;
        
        if touchUp != nil
        {
            touchUp!(btn);
        }
    }
}

2.示例说明

  在Swift中,闭包不属于AnyObject,因此,需要做一个相互转换。如下所示:

   使用方式如下:

extension UIButton
{
    /**
     创建UIButton控件
     
     - parameter title:       按钮标题
     - parameter superView:   按钮父视图
     - parameter constraints: 约束
     - parameter touchup:     按钮点击事件
     
     - returns: UIButton控件
     */
    static func gof_buttonWithTitle(title: String?, superView: UIView?, constraints: GofConstraintMaker?, touchup: GofBtnClickBlock?) -> UIButton
    {
        let button = UIButton(type: .Custom);
        if title != nil
        {
            button.setTitle(title, forState: .Normal);
            button.titleLabel?.font = kTitleFont;
        }
        
        button.backgroundColor = kCColor;
        
        if superView != nil
        {
            superView!.addSubview(button);
            
            if constraints != nil
            {
                button.snp_makeConstraints(closure: { (make) in
                    constraints!(make);
                })
            }
        }
        
        if touchup != nil
        {
            button.gof_touchUpInside = touchup!;
        }
        
        return button;
    }
}
原文地址:https://www.cnblogs.com/LeeGof/p/5684700.html