UIButton block equivalent to addTarget:action:forControlEvents: method?

后端 未结 9 1199
旧巷少年郎
旧巷少年郎 2020-11-29 20:58

I looked around, but couldn\'t find this on the internet, nor anywhere in the Apple docs, so I\'m guessing it doesn\'t exist.

But is there a iOS4 blocks equivalent A

9条回答
  •  渐次进展
    2020-11-29 21:32

    Swift extension / category based implementation that I whipped up. Using OBJC associated objects is not an anti-pattern. :P

    import UIKit
    
    // MARK: UIControl Block based actions
    typealias ActionBlock = (UIControl) -> ()
    
    class UIButtonActionDelegate : NSObject {
        let actionBlock : ActionBlock
        init(actionBlock: ActionBlock) {
            self.actionBlock = actionBlock
        }
        func triggerBlock(control : UIControl) {
            actionBlock(control)
        }
    }
    
    private var actionHandlersKey: UInt8 = 0
    extension UIControl {
        var actionHandlers: NSMutableArray { // cat is *effectively* a stored property
            get {
                return associatedObject(self, key: &actionHandlersKey, initialiser: { () -> NSMutableArray in
                    return NSMutableArray()
                })
            }
            set { associateObject(self, key: &actionHandlersKey, value: newValue) }
        }
    
        func addBlockForEvents(events: UIControlEvents, block: ActionBlock) {
            let actionDelegate = UIButtonActionDelegate(actionBlock: block)
            actionHandlers.addObject(actionDelegate) // So it gets retained
            addTarget(actionDelegate, action: #selector(UIButtonActionDelegate.triggerBlock(_:)), forControlEvents: events)
        }
    }
    
    // MARK: Associated Object wrapper
    
    func associatedObject(
        base: AnyObject,
        key: UnsafePointer,
        initialiser: () -> ValueType)
        -> ValueType {
            if let associated = objc_getAssociatedObject(base, key)
                as? ValueType { return associated }
            let associated = initialiser()
            objc_setAssociatedObject(base, key, associated,
                                     .OBJC_ASSOCIATION_RETAIN)
            return associated
    }
    
    func associateObject(
        base: AnyObject,
        key: UnsafePointer,
        value: ValueType) {
        objc_setAssociatedObject(base, key, value,
                                 .OBJC_ASSOCIATION_RETAIN)
    }
    

提交回复
热议问题