在 Swift 中将函数作为参数传递
Passing functions as parameters in 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 做正确的事情,因为我到目前为止所做的尝试没有奏效。我想我没有为我想要的使用正确的语法,但我确信可以做我想做的事。知道正确的方法吗?
您问题的单字答案是 Closures
闭包的默认语法是() -> ()
您可以直接提及方法定义而不是选择器
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
}
}
我根据各种站点示例编写了这个例程。这是我调用例程的方式...
@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")
}
您可以传入按钮选项和选择按钮时要执行的功能。花了一点时间弄清楚如何将函数作为参数传递,但现在似乎工作正常。我确实遇到了一个奇怪的问题试图使用循环来动态添加按钮,最后放弃并使用了一个switch/case。我包含了我尝试使用的循环代码,如果有人能弄清楚我做错了什么,请告诉我。谢谢
https://github.com/blakeguitar/iOS/blob/0e243d13cb2decd6e1dbe134a8a046c2caed3876/SS_Alert.swift
以防其他人无意中发现这一点。在为项目构建全局警报实用程序时,我正在为 Swift 5.1 制定一个更新的简单解决方案。
Swift 5.1
闭包函数:
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()
}
}
}
调用函数:
showSheetAlertWithOneAction(messageText: "Here's a message", dismissButtonText: "Nope", actionButtonText: "Okay", presentingView: self.view.window!) {
someFunction()
}
添加到 got2jam 的回答中...
如果你正在使用 UIAlertController
显示闭包警报的通用函数:
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)
}
现在你可以这样称呼它了:
showAlertAction(title: "This is the title", message: "This is the message") {
self.close()
}
在这种情况下,close 是要执行的特定 UIAlertAction
func close(){
dismiss(animated: true, completion: nil)
}
我在 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 做正确的事情,因为我到目前为止所做的尝试没有奏效。我想我没有为我想要的使用正确的语法,但我确信可以做我想做的事。知道正确的方法吗?
您问题的单字答案是 Closures
闭包的默认语法是() -> ()
您可以直接提及方法定义而不是选择器
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
}
}
我根据各种站点示例编写了这个例程。这是我调用例程的方式...
@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")
}
您可以传入按钮选项和选择按钮时要执行的功能。花了一点时间弄清楚如何将函数作为参数传递,但现在似乎工作正常。我确实遇到了一个奇怪的问题试图使用循环来动态添加按钮,最后放弃并使用了一个switch/case。我包含了我尝试使用的循环代码,如果有人能弄清楚我做错了什么,请告诉我。谢谢
https://github.com/blakeguitar/iOS/blob/0e243d13cb2decd6e1dbe134a8a046c2caed3876/SS_Alert.swift
以防其他人无意中发现这一点。在为项目构建全局警报实用程序时,我正在为 Swift 5.1 制定一个更新的简单解决方案。
Swift 5.1
闭包函数:
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()
}
}
}
调用函数:
showSheetAlertWithOneAction(messageText: "Here's a message", dismissButtonText: "Nope", actionButtonText: "Okay", presentingView: self.view.window!) {
someFunction()
}
添加到 got2jam 的回答中... 如果你正在使用 UIAlertController
显示闭包警报的通用函数:
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)
}
现在你可以这样称呼它了:
showAlertAction(title: "This is the title", message: "This is the message") {
self.close()
}
在这种情况下,close 是要执行的特定 UIAlertAction
func close(){
dismiss(animated: true, completion: nil)
}