ios - non - Pasando funciones como parámetros en Swift
unexpected non-void return value in void function (2)
Tengo la siguiente función trabajando como espero, en 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)
}
Me gustaría hacer algo como lo siguiente, para pasar como argumentos los métodos que se ejecutarán cuando se toque uno u otro de los botones:
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)
}
Obviamente no estoy haciendo lo correcto con firstSelector y secondSelector, porque lo que he intentado hasta ahora no funcionó. Supongo que no estoy usando la sintaxis correcta para lo que quiero, pero estoy seguro de que es posible hacer lo que me gustaría hacer. ¿Alguna idea de la forma de hacerlo correctamente?
Escribí esta rutina basada en varios ejemplos de sitios. Así es como llamo a la rutina ...
@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")
}
Puede pasar las opciones de botones y las funciones que se realizan cuando se seleccionan los botones. Tomó un poco de tiempo para averiguar cómo pasar las funciones como parámetros, pero parece funcionar bien ahora. Me encontré con un extraño problema al usar bucles para agregar botones dinámicamente, y finalmente abandoné y usé un interruptor / caja. Incluí el código de bucle que intenté usar, si alguien puede averiguar qué estaba haciendo mal, avíseme. Gracias.
https://github.com/blakeguitar/iOS/blob/0e243d13cb2decd6e1dbe134a8a046c2caed3876/SS_Alert.swift
La respuesta de Oneword a tu pregunta es Closures
La sintaxis predeterminada para los cierres es () -> ()
En lugar de Selector, puedes mencionar directamente la definición del método.
func showConfirmBox(msg:String, title:String,
firstBtnStr:String, firstSelector:(sampleParameter: String) -> returntype,
secondBtnStr:String, secondSelector:() -> returntype,
caller:UIViewController) {
//Your Code
}
Pero usar esto creará problemas legibles, así que te sugiero que uses 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()
}
Puedes llamar a tu método así.
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
}
}