Передача функций в параметрах Swift
У меня есть следующая функция, работающая, как я ожидаю, в iOS 8:
func showConfirmBox(msg:String, title:String,
firstBtnStr:String,
secondBtnStr:String,
caller:UIViewController) {
let userPopUp = UIAlertController(title:title,
message:msg, preferredStyle:UIAlertControllerStyle.Alert)
userPopUp.addAction(UIAlertAction(title:firstBtnStr, style:UIAlertActionStyle.Default,
handler:{action in}))
userPopUp.addAction(UIAlertAction(title:secondBtnStr, style:UIAlertActionStyle.Default,
handler:{action in}))
caller.presentViewController(userPopUp, animated: true, completion: nil)
}
Я хотел бы сделать что-то вроде следующего, чтобы передать в качестве аргумента методы, которые будут выполняться, когда одна или другая из кнопок будет затронута:
func showConfirmBox(msg:String, title:String,
firstBtnStr:String, firstSelector:Selector,
secondBtnStr:String, secondSelector:Selector,
caller:UIViewController) {
let userPopUp = UIAlertController(title:title,
message:msg, preferredStyle:UIAlertControllerStyle.Alert)
userPopUp.addAction(UIAlertAction(title:firstBtnStr, style:UIAlertActionStyle.Default,
handler:{action in caller.firstSelector()}))
userPopUp.addAction(UIAlertAction(title:secondBtnStr, style:UIAlertActionStyle.Default,
handler:{action in caller.secondSelector()}))
caller.presentViewController(userPopUp, animated: true, completion: nil)
}
Очевидно, что я не делаю правильные вещи с firstSelector и secondSelector, потому что то, что я пробовал до сих пор, не работает. Я полагаю, что я не использую правильный синтаксис для того, что хочу, но я уверен, что можно сделать то, что я хотел бы сделать. Любая идея о том, как правильно это сделать?
Ответы
Ответ 1
Ответ на однополярный ответ на ваш вопрос: Закрытие
Синтаксис по умолчанию для замыканий - () ->()
Вместо Selector вы можете непосредственно указать метод defnition
func showConfirmBox(msg:String, title:String,
firstBtnStr:String, firstSelector:(sampleParameter: String) -> returntype,
secondBtnStr:String, secondSelector:() -> returntype,
caller:UIViewController) {
//Your Code
}
Но использование этого приведет к созданию читаемых проблем, поэтому я предлагаю вам использовать 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()
}
Вы можете вызвать свой метод следующим образом
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
}
}
Ответ 2
Я написал эту процедуру на основе различных примеров сайтов. Вот как я называю рутину...
@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")
}
Вы можете передать параметры кнопок и функции, которые будут выполняться при выборе кнопок. Потребовалось немного времени, чтобы понять, как передавать функции в качестве параметров, но, похоже, сейчас работает нормально. Я столкнулся с какой-то странной проблемой, пытающейся использовать циклы для динамического добавления кнопок, и, наконец, сдался и использовал переключатель /case. Я включил код цикла, который я пытался использовать, если кто-то может понять, что я делаю неправильно, дайте мне знать. Благодарю.
https://github.com/blakeguitar/iOS/blob/0e243d13cb2decd6e1dbe134a8a046c2caed3876/SS_Alert.swift