2015-11-11 7 views
15

मैं बस सोच रहा था कि एक बटन एक्शन (जो आम तौर पर एक चयनकर्ता है) में फ़ंक्शन पास करना संभव था।स्विफ्ट उपयोग चयनकर्ता तर्क जैसे बंद

उदाहरण के लिए, सामान्य रूप से मैं कहना चाहता हूँ:

UIBarButtonItem(title: "Press", style: .Done, target: self, action: "functionToCall") 

func functionToCall() { 
    // Do something 
} 

लेकिन अगर यह की तरह कुछ करने के लिए संभव है मैं सोच रहा था: मेरे कार्य है क्योंकि

UIBarButtonItem(title: "Press", style: .Done, target: self, action: { 
    // Do Something 
}) 

कारण मैं यह है क्या करना चाहते हैं सुपर सरल और ऐसा लगता है कि यह साफ-सुथरा और अधिक स्विफ्ट-जैसा होगा जो वे बंद होने पर जोर दे रहे हैं।

उत्तर

0

Unfortunatelly यह संभव नहीं है एप्पल के साथ initialisers प्रदान की है। पृष्ठभूमि में यह जिस तरह से काम करता है वह प्रतिबिंब के साथ है, और एक बंद करना कुछ अलग है जो वर्तमान में समर्थित नहीं है।

आप कुछ हैकिंग या एप्पल के साथ एक कस्टम समाधान बनाने के लिए उत्पन्न हो जाएं कि भविष्य में सक्षम हो सकता है। https://www.reddit.com/r/swift/comments/3fjzap/creating_button_action_programatically_using

इसका इस्तेमाल करने के लिए हालांकि मैं स्टोरीबोर्ड के माध्यम से बटन जोड़ने के लिए प्रोग्राम के बजाय था -

1

Reddit पर एक पोस्ट के लिए एक कस्टम घटक के साथ इस के लिए एक समाधान बताते हैं। यहां मैंने यह कैसे किया था।

let tempVariableIWantToReference = "Classy" 

navigationTitle.leftBarButtonItem = BlockBarButtonItem.init(
    title: "< Back", style: UIBarButtonItemStyle.Plain, 
    actionHandler: {() -> Void in 
     print("Hey I'm in a closure") 
     print("I can even reference temporary variables. \(self.tempVariableIWantToReference)!!!") 
    }) 
10

यहाँ स्विफ्ट 3.

class BlockBarButtonItem: UIBarButtonItem { 
    private var actionHandler: ((Void) -> Void)? 

    convenience init(title: String?, style: UIBarButtonItemStyle, actionHandler: ((Void) -> Void)?) { 
    self.init(title: title, style: style, target: nil, action: #selector(barButtonItemPressed)) 
    self.target = self 
    self.actionHandler = actionHandler 
    } 

    convenience init(image: UIImage?, style: UIBarButtonItemStyle, actionHandler: ((Void) -> Void)?) { 
    self.init(image: image, style: style, target: nil, action: #selector(barButtonItemPressed)) 
    self.target = self 
    self.actionHandler = actionHandler 
    } 

    func barButtonItemPressed(sender: UIBarButtonItem) { 
    actionHandler?() 
    } 
} 
+0

यह उद्देश्य-सी संपत्ति ब्लॉकों के लिए काम करता है:

इस के साथ

, किसी भी क्षण में आप बस किसी भी UIBarButtonItem की actionClosure की स्थापना की और सब कुछ काम करने की उम्मीद कर सकते हैं, यहां एक उदाहरण है? http://stackoverflow.com/questions/42172472/how-to-invoke-objective-c-block-property-in-swift – Aleksandr

+0

हां आप उद्देश्य-सी के साथ कुछ ऐसा करने में सक्षम होना चाहिए। – David

+0

जैसा कि आप लिंक के तहत प्रश्न में देख सकते हैं, ऐसा लगता है कि यह संभव नहीं है। शायद आप जानते हैं क्यों?) – Aleksandr

4

के लिए एक अद्यतन समाधान है यह उपवर्गीकरण बिना कोई वैकल्पिक समाधान है:

extension UIBarButtonItem { 
    private struct AssociatedObject { 
     static var key = "action_closure_key" 
    } 

    var actionClosure: (()->Void)? { 
     get { 
      return objc_getAssociatedObject(self, &AssociatedObject.key) as?()->Void 
     } 
     set { 
      objc_setAssociatedObject(self, &AssociatedObject.key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 
      target = self 
      action = #selector(didTapButton(sender:)) 
     } 
    } 

    @objc func didTapButton(sender: Any) { 
     actionClosure?() 
    } 
} 

यह करने के लिए ऑब्जेक्टिव-सी क्रम से संबद्ध वस्तुओं पर निर्भर करता है एक बंद/ब्लॉक संपत्ति जोड़ें।

जब निर्धारित करते हैं, यह अपने आप के लिए लक्ष्य बदलता है और एक नया समारोह है कि बंद के कॉल यदि वह मौजूद है करने के लिए चयनकर्ता इंगित करता है।

let button = UIBarButtonItem(
    barButtonSystemItem: .action, 
    target: nil, action: nil 
) 
button.actionClosure = { 
    print("hello") 
} 
संबंधित मुद्दे