ios - एक UIButton को लक्ष्य के रूप में बंद करना जोड़ना




swift addtarget (4)

मेरे पास एक जेनेरिक कंट्रोल क्लास है जिसे व्यू नियंत्रक के आधार पर बटन को पूरा करने की जरूरत होती है। उस सेट-लेफ्टबटटन एक्शनविथ क्लोजर फ़ंक्शन को पैरामीटर के रूप में लेने की जरूरत है जिसे एक अनबटन के लिए एक्शन के रूप में सेट किया जाना चाहिए। इसे स्विफ्ट में कैसे संभव होगा चूंकि हमें स्ट्रिंग टू एक्शन के रूप में फ़ंक्शन का नाम देना होगा: पैरामीटर

func setLeftButtonActionWithClosure(completion: () -> Void)
{
self.leftButton.addTarget(<#target: AnyObject?#>, action: <#Selector#>, forControlEvents: <#UIControlEvents#>)
}

आप UIButton subclassing द्वारा प्रभावी रूप से इसे प्राप्त कर सकते हैं:

class ActionButton: UIButton {
    var touchDown: ((button: UIButton) -> ())?
    var touchExit: ((button: UIButton) -> ())?
    var touchUp: ((button: UIButton) -> ())?

    required init?(coder aDecoder: NSCoder) { fatalError("init(coder:)") }
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupButton()
    }

    func setupButton() {
        //this is my most common setup, but you can customize to your liking
        addTarget(self, action: #selector(touchDown(_:)), forControlEvents: [.TouchDown, .TouchDragEnter])
        addTarget(self, action: #selector(touchExit(_:)), forControlEvents: [.TouchCancel, .TouchDragExit])
        addTarget(self, action: #selector(touchUp(_:)), forControlEvents: [.TouchUpInside])
    }

    //actions
    func touchDown(sender: UIButton) {
        touchDown?(button: sender)
    }

    func touchExit(sender: UIButton) {
        touchExit?(button: sender)
    }

    func touchUp(sender: UIButton) {
        touchUp?(button: sender)
    }
}

उपयोग:

let button = ActionButton(frame: buttonRect)
button.touchDown = { button in
    print("Touch Down")
}
button.touchExit = { button in
    print("Touch Exit")
}
button.touchUp = { button in
    print("Touch Up")
}

नोट: जैसे @ एथानहुआंग ने कहा "यदि आपके पास दो से अधिक उदाहरण हैं तो यह समाधान काम नहीं करता है। सभी कार्यों को अंतिम असाइनमेंट द्वारा अधिलेखित किया जाएगा।" जब आप विकसित होते हैं तो इसे ध्यान में रखें, मैं जल्द ही एक और समाधान पोस्ट करूंगा

यदि आप किसी UIButton को लक्ष्य के रूप में बंद करना चाहते हैं, तो आपको extension का उपयोग करके UIButton वर्ग में फ़ंक्शन जोड़ना होगा

import UIKit

extension UIButton {
    private func actionHandleBlock(action:(() -> Void)? = nil) {
        struct __ {
            static var action :(() -> Void)?
        }
        if action != nil {
            __.action = action
        } else {
            __.action?()
        }
    }

    @objc private func triggerActionHandleBlock() {
        self.actionHandleBlock()
    }

    func actionHandle(controlEvents control :UIControlEvents, ForAction action:() -> Void) {
        self.actionHandleBlock(action)
        self.addTarget(self, action: "triggerActionHandleBlock", forControlEvents: control)
    }
}

और कॉल:

 let button = UIButton()
 button.actionHandle(controlEvents: UIControlEvents.TouchUpInside, 
 ForAction:{() -> Void in
     print("Touch")
 })

पहले से ही सूचीबद्ध उन लोगों के लिए समान समाधान, लेकिन शायद हल्का वजन:

class ClosureSleeve {
    let closure: ()->()

    init (_ closure: @escaping ()->()) {
        self.closure = closure
    }

    @objc func invoke () {
        closure()
    }
}

extension UIControl {
    func add (for controlEvents: UIControlEvents, _ closure: @escaping ()->()) {
        let sleeve = ClosureSleeve(closure)
        addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
        objc_setAssociatedObject(self, String(format: "[%d]", arc4random()), sleeve, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
    }
}

उपयोग:

button.add(for: .touchUpInside) {
    print("Hello, Closure!")
}

यह मूलतः अरमानोइड का उत्तर ऊपर है, लेकिन मेरे लिए कुछ उपयोगी बदलाव हैं:

  • पास-इन क्लोजर एक UIButton तर्क ले सकते हैं, जिससे आप self को पारित कर सकते हैं
  • फ़ंक्शन और तर्कों का एक तरह से नाम दिया गया है, जो कि मेरे लिए, जो कि चल रहा है स्पष्ट करता है, उदाहरण के लिए, UIButton कार्रवाई से एक स्विफ्ट बंद करने में अंतर करके

    private func setOrTriggerClosure(closure:((button:UIButton) -> Void)? = nil) {
    
      //struct to keep track of current closure
      struct __ {
        static var closure :((button:UIButton) -> Void)?
      }
    
      //if closure has been passed in, set the struct to use it
      if closure != nil {
        __.closure = closure
      } else {
        //otherwise trigger the closure
        __. closure?(button: self)
      }
    }
    @objc private func triggerActionClosure() {
      self.setOrTriggerClosure()
    }
    func setActionTo(closure:(UIButton) -> Void, forEvents :UIControlEvents) {
      self.setOrTriggerClosure(closure)
      self.addTarget(self, action:
        #selector(UIButton.triggerActionClosure),
                     forControlEvents: forEvents)
    }

अरमानोइड के लिए कुछ सहारा हालांकि यहाँ कुछ भारी शुल्क जादू के लिए।





addtarget