ios 在 Swift 中将函数作为参数传递
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33717313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing functions as parameters in Swift
提问by Michel
I have the following function working as I expect, in iOS 8:
在 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)
}
I would like to make something like the following, in order to pass as arguments the methods to be executed when one or the other of the buttons are going to be touched:
我想做如下事情,以便将要触摸一个或另一个按钮时要执行的方法作为参数传递:
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)
}
Obviously I am not doing the right thing with firstSelector and secondSelector, because what I have tried up to now did not work. I suppose I am not using the right syntax for what I want, but I am sure it is possible to do what I would like to do. Any idea of the way to do it properly?
显然我对 firstSelector 和 secondSelector 没有做正确的事情,因为我迄今为止尝试过的方法没有奏效。我想我没有为我想要的东西使用正确的语法,但我确信可以做我想做的事。知道如何正确地做到这一点吗?
回答by iPrabu
Oneword answer for your question is Closures
您的问题的 Oneword 答案是Closures
The Default Syntax for closures is () -> ()
闭包的默认语法是 () -> ()
Instead of Selector you could directly mention the method definition
您可以直接提及方法定义而不是 Selector
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
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
}
}
回答by got2jam
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 制定了一个更新的简单解决方案。
Swift 5.1
斯威夫特 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()
}
回答by Alix Huerta
Adding to got2jam's answer... If you're working with UIAlertController
添加到got2jam的答案...如果您正在使用 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, closeis the particular UIAlertAction to execute
在这种情况下,close是要执行的特定 UIAlertAction
func close(){
dismiss(animated: true, completion: nil)
}
回答by Blake Martin
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.
您可以传入按钮选项和选择按钮时要执行的功能。花了一点时间弄清楚如何将函数作为参数传递,但现在似乎工作正常。我确实遇到了一个奇怪的问题,试图使用循环来动态添加按钮,最后放弃并使用了 switch/case。我包含了我尝试使用的循环代码,如果有人能找出我做错了什么,请告诉我。谢谢。
https://github.com/blakeguitar/iOS/blob/0e243d13cb2decd6e1dbe134a8a046c2caed3876/SS_Alert.swift
https://github.com/blakeguitar/iOS/blob/0e243d13cb2decd6e1dbe134a8a046c2caed3876/SS_Alert.swift