Passing functions as parameters in Swift

前端 未结 4 684
广开言路
广开言路 2021-02-04 23:57

I have the following function working as I expect, in iOS 8:

func showConfirmBox(msg:String, title:String,
    firstBtnStr:String,
    secondBtnStr:String,
    c         


        
相关标签:
4条回答
  • 2021-02-05 00:43

    I wrote this routine based on various site examples. Here is how I call the routine...

    @IBAction func buttonClick(_ sender: Any) {
        SS_Alert.createAlert(parmTitle: "Choose", parmMessage: "Please select Yes or No", parmOptions: ["Yes","No","Cancel"], parmFunctions: [testYes, testNo, nil])
    }
    
    func testYes() {
        print("yes")
    }
    
    func testNo() {
        print("no")
    }
    

    You can pass in button options and the functions to performed when the buttons are selected. Took a little time to figure out how to pass functions as parameters, but appears to work fine now. I did encounter a strange problem trying to use loops to dynamically add buttons, and finally gave up and used a switch/case. I included the loop code I tried to use, if someone can figure out what I was doing wrong let me know. Thanks.

    https://github.com/blakeguitar/iOS/blob/0e243d13cb2decd6e1dbe134a8a046c2caed3876/SS_Alert.swift

    0 讨论(0)
  • 2021-02-05 00:53

    Oneword answer for your question is Closures

    The Default Syntax for closures is () -> ()

    Instead of Selector you could directly mention the method definition

    func showConfirmBox(msg:String, title:String,
        firstBtnStr:String, firstSelector:(sampleParameter: String) -> returntype,
        secondBtnStr:String, secondSelector:() -> returntype,
        caller:UIViewController) {
        //Your Code
    }
    

    But using this will create readability problems so i suggest you to use typeAlias

    typealias MethodHandler1 = (sampleParameter : String)  -> Void
    typealias MethodHandler2 = ()  -> Void
    
    func showConfirmBox(msg:String, title:String,
                        firstBtnStr:String, firstSelector:MethodHandler1,
                        secondBtnStr:String, secondSelector:MethodHandler2) {
    
        // After any asynchronous call
        // Call any of your closures based on your logic like this
        firstSelector("FirstButtonString")
        secondSelector()
    }
    

    You can call your method like this

    func anyMethod() {
       //Some other logic 
    
       showConfirmBox(msg: "msg", title: "title", firstBtnStr: "btnString", 
             firstSelector: { (firstSelectorString) in
                  print(firstSelectorString) //this prints FirstButtonString
             }, 
             secondBtnStr: "btnstring") { 
               //Invocation comes here after secondSelector is called
    
             }
    }
    
    0 讨论(0)
  • 2021-02-05 00:58

    Just in case anyone else stumbles upon this. I worked out an updated simple solution for Swift 5.1 while I was working through this for while building a global alert utility for a project.

    Swift 5.1

    Function with Closure:

    func showSheetAlertWithOneAction(messageText: String, dismissButtonText: String, actionButtonText : String, presentingView : NSWindow, actionButtonClosure: @escaping () -> Void) {
            let alert = NSAlert()
            alert.messageText = messageText
            alert.addButton(withTitle: actionButtonText)
            alert.addButton(withTitle: dismissButtonText)
            alert.beginSheetModal(for: presentingView) { (response) in
                if response == .alertFirstButtonReturn {
                    actionButtonClosure()
                }
            }
        }
    

    Function Called:

    showSheetAlertWithOneAction(messageText: "Here's a message", dismissButtonText: "Nope", actionButtonText: "Okay", presentingView: self.view.window!) {
                                                someFunction()
                                    }
    
    0 讨论(0)
  • 2021-02-05 01:00

    Adding to got2jam's answer... If you're working with UIAlertController

    The generic function to show an alert with closure:

    func showAlertAction(title: String, message: String, actionClosure: @escaping () -> Void){
      let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
      alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: {(action: UIAlertAction!) in actionClosure()}))
      self.present(alertController, animated: true, completion: nil)
    }
    

    Now you can call it like that:

    showAlertAction(title: "This is the title", message: "This is the message") {
       self.close()
    }
    

    in this case, close is the particular UIAlertAction to execute

    func close(){
      dismiss(animated: true, completion: nil)
    }
    
    0 讨论(0)
提交回复
热议问题