你应该如何处理 UIAlertAction 的闭包参数
How should you handle closure arguments for UIAlertAction
我一直在尝试创建一个 UIAlertAtion
,它也有一个处理程序。我阅读了 this 问题的答案并知道如何去做。
我的问题只是关于它的关闭部分。
1) 我知道我可以写:{alert in println("Foo")}
或者 {_ in println("Foo")}
但我 不能 写{println("Foo")}
。在评论here中解释是因为你需要处理参数action。
这是否意味着由于处理程序是 (UIAlertAction) -> Void)?
类型,我必须始终捕获传递的 alertAction?
2)
我还阅读了 this,答案基本上是说你可以传入一个函数作为你的参数,但该函数应该采用 UIAlertAction -> Void
类型的东西,我写道:
private func anything(action : UIAlertAction) {
print("hello")
}
然后这样写我的警报动作:
let anotherAction = UIAlertAction(title: "hi", style: UIAlertActionStyle.Default,
handler: anything(action)) // error: Use of unresolved identifier 'action'
搞不懂为什么我会收到那个错误
3)
在评论中它还说:但除此之外你不必在swift中写UIAlertActionStyle.Default。 .默认也有效
我尝试不使用样式来编写,因此它会默认为 .Default
let sendLogAction = UIAlertAction(title: "Log") { action in print("goodbye")}
但随后出现以下错误:
'(title: String, (_) -> ())' (aka '(title: String, _ -> ())') is not
convertible to '(title: String?, style: UIAlertActionStyle, handler:
((UIAlertAction) -> Void)?)' (aka '(title: Optional, style:
UIAlertActionStyle, handler: Optional ()>)'), tuples
have a different number of elements
4)
同时阅读 this 答案。我不明白为什么我们需要传入 alert
这没有意义。并不是说我们不知道警报的类型是什么……我们不是已经定义了它的类型吗?!!任何人都可以解释传递操作本身通常在哪里有用,我的意思是我们可以用它做什么?
我知道这是写成 4 个问题,但我认为这实际上只是一个基础问题。我在我正在操场上工作和玩耍的项目中广泛 read、使用了 closures/completion 处理程序,但我仍然感到困惑。
是的,您必须始终处理参数。它是签名的一部分,不容忽视。它也是特殊的 Swift 语法,能够删除 handler
参数,因为它是最后一个参数并且是一个闭包参数。
将 anything(action)
更改为 anything
就像您 link 更改为的示例一样。
你误会了。他们并不是说您可以删除样式参数。他们说你可以从 UIAlertActionStyle.Default
中删除 UIAlertActionStyle
意味着你只需要将 .Default
作为参数传递给样式参数。
您想要一个示例,说明处理程序的 action
参数在哪里有用。真的没有太多用处。唯一的属性是标题、样式以及是否启用。后者毫无意义,因为如果调用了处理程序,您就知道它已启用。唯一可能的用途是标题或样式需要在处理程序中使用,并且它们在创建时没有硬编码到警报操作中。通过访问处理程序中的标题或样式属性,您可以轻松访问创建操作时使用的实际值。
1) UIAlerAction 初始化方法定义有 3 个参数,最后一个参数是 (UIAlertAction -> Void)?这意味着你可以有一个“无名”函数(又名闭包)或一个 nil(由可选符号 ? 指定)。如果您选择不指定最后一个参数,您可以像这样创建 UIAlertController
alert.addAction(UIAlertAction(title: "test", style: .default, handler: nil))
但是如果你想指定最后一个参数(不是 nil),那么你必须提供一个将 UIAlertAction 作为参数并且 return 没有任何参数(Void)的闭包。参考您的 link,他只是使用他为简单起见已经创建的“警报”常量。
要回答您的问题“这是否意味着……”,答案是肯定的,因为第三个参数的定义:(UIAlertAction) -> Void)?
2) 您收到错误是因为您传递了参数(操作)。试试让
anotherAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default,
handler: anything)
你应该不会出错。
3) UIAlertAction 只有(我相信)一个初始化方法,因此您需要提供所有三个参数来创建它。请参阅我的 1) style:.default 答案。这是一种调用 Swift 枚举的新方法。顺便说一句,所有枚举都必须是小写的,所以 .default 不是 .Default`enter code here
alert.addAction(UIAlertAction(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) -> Void))
4) 从答案中可以看出,您有 link。你可以使用常量 'alert' (UIAlertAction) 来做任何你想做的事情,比如检查样式和做一些事情。
func anything(alert: UIAlertAction!) {
print("somehandler")
switch alert.title {
case "OK"?:
print("title is OK")
default:
print("title is not OK")
}
}
rmaddy 的回答就足够了,但作为 OP :) 我找到了问题的根本原因:
我对参数处理程序缺乏理解,处理程序的类型为:(UIAlertAction) -> Void)?
即 closure/function
处理程序只需要一个函数名称,一旦您提供该函数,它将填写该函数的输入本身。
你只传递anything
作为处理程序,即函数名称。
UIAlertAction 的 internal 实现有 some line like handler(action)
which would use anything
which is of type(UIAlertAction) -> Void)?
, 注入 action
(传递给它)最终做 anything(action)
.
话虽如此,您的 anything(input: UIAlertAction)
应该做一些有意义的事情。 (已经在 rmaddy 的评论中讨论过)
另一个解决方案是 不 提供一个函数,而是在尾随闭包中使用 captured 操作并做任何你喜欢的事情用它做。
let retryAction = UIAlertAction(title: returnTitle(), style: UIAlertActionStyle.Default) { action in
switch action.title {
case "OK":
okFunc()
case "cancel":
cancelFunc()
default:
defaultFunc()
}
}
只有当您动态地获得代码时,这种切换才有价值,否则您知道它的价值的磁贴没有附加值切换。
我一直在尝试创建一个 UIAlertAtion
,它也有一个处理程序。我阅读了 this 问题的答案并知道如何去做。
我的问题只是关于它的关闭部分。
1) 我知道我可以写:{alert in println("Foo")}
或者 {_ in println("Foo")}
但我 不能 写{println("Foo")}
。在评论here中解释是因为你需要处理参数action。
这是否意味着由于处理程序是 (UIAlertAction) -> Void)?
类型,我必须始终捕获传递的 alertAction?
2)
我还阅读了 this,答案基本上是说你可以传入一个函数作为你的参数,但该函数应该采用 UIAlertAction -> Void
类型的东西,我写道:
private func anything(action : UIAlertAction) {
print("hello")
}
然后这样写我的警报动作:
let anotherAction = UIAlertAction(title: "hi", style: UIAlertActionStyle.Default,
handler: anything(action)) // error: Use of unresolved identifier 'action'
搞不懂为什么我会收到那个错误
3) 在评论中它还说:但除此之外你不必在swift中写UIAlertActionStyle.Default。 .默认也有效
我尝试不使用样式来编写,因此它会默认为 .Default
let sendLogAction = UIAlertAction(title: "Log") { action in print("goodbye")}
但随后出现以下错误:
'(title: String, (_) -> ())' (aka '(title: String, _ -> ())') is not convertible to '(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) -> Void)?)' (aka '(title: Optional, style: UIAlertActionStyle, handler: Optional ()>)'), tuples have a different number of elements
4)
同时阅读 this 答案。我不明白为什么我们需要传入 alert
这没有意义。并不是说我们不知道警报的类型是什么……我们不是已经定义了它的类型吗?!!任何人都可以解释传递操作本身通常在哪里有用,我的意思是我们可以用它做什么?
我知道这是写成 4 个问题,但我认为这实际上只是一个基础问题。我在我正在操场上工作和玩耍的项目中广泛 read、使用了 closures/completion 处理程序,但我仍然感到困惑。
是的,您必须始终处理参数。它是签名的一部分,不容忽视。它也是特殊的 Swift 语法,能够删除
handler
参数,因为它是最后一个参数并且是一个闭包参数。将
anything(action)
更改为anything
就像您 link 更改为的示例一样。你误会了。他们并不是说您可以删除样式参数。他们说你可以从
UIAlertActionStyle.Default
中删除UIAlertActionStyle
意味着你只需要将.Default
作为参数传递给样式参数。您想要一个示例,说明处理程序的
action
参数在哪里有用。真的没有太多用处。唯一的属性是标题、样式以及是否启用。后者毫无意义,因为如果调用了处理程序,您就知道它已启用。唯一可能的用途是标题或样式需要在处理程序中使用,并且它们在创建时没有硬编码到警报操作中。通过访问处理程序中的标题或样式属性,您可以轻松访问创建操作时使用的实际值。
1) UIAlerAction 初始化方法定义有 3 个参数,最后一个参数是 (UIAlertAction -> Void)?这意味着你可以有一个“无名”函数(又名闭包)或一个 nil(由可选符号 ? 指定)。如果您选择不指定最后一个参数,您可以像这样创建 UIAlertController
alert.addAction(UIAlertAction(title: "test", style: .default, handler: nil))
但是如果你想指定最后一个参数(不是 nil),那么你必须提供一个将 UIAlertAction 作为参数并且 return 没有任何参数(Void)的闭包。参考您的 link,他只是使用他为简单起见已经创建的“警报”常量。
要回答您的问题“这是否意味着……”,答案是肯定的,因为第三个参数的定义:(UIAlertAction) -> Void)?
2) 您收到错误是因为您传递了参数(操作)。试试让
anotherAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default,
handler: anything)
你应该不会出错。
3) UIAlertAction 只有(我相信)一个初始化方法,因此您需要提供所有三个参数来创建它。请参阅我的 1) style:.default 答案。这是一种调用 Swift 枚举的新方法。顺便说一句,所有枚举都必须是小写的,所以 .default 不是 .Default`enter code here
alert.addAction(UIAlertAction(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) -> Void))
4) 从答案中可以看出,您有 link。你可以使用常量 'alert' (UIAlertAction) 来做任何你想做的事情,比如检查样式和做一些事情。
func anything(alert: UIAlertAction!) {
print("somehandler")
switch alert.title {
case "OK"?:
print("title is OK")
default:
print("title is not OK")
}
}
rmaddy 的回答就足够了,但作为 OP :) 我找到了问题的根本原因:
我对参数处理程序缺乏理解,处理程序的类型为:(UIAlertAction) -> Void)?
即 closure/function
处理程序只需要一个函数名称,一旦您提供该函数,它将填写该函数的输入本身。
你只传递anything
作为处理程序,即函数名称。
UIAlertAction 的 internal 实现有 some line like handler(action)
which would use anything
which is of type(UIAlertAction) -> Void)?
, 注入 action
(传递给它)最终做 anything(action)
.
话虽如此,您的 anything(input: UIAlertAction)
应该做一些有意义的事情。 (已经在 rmaddy 的评论中讨论过)
另一个解决方案是 不 提供一个函数,而是在尾随闭包中使用 captured 操作并做任何你喜欢的事情用它做。
let retryAction = UIAlertAction(title: returnTitle(), style: UIAlertActionStyle.Default) { action in
switch action.title {
case "OK":
okFunc()
case "cancel":
cancelFunc()
default:
defaultFunc()
}
}
只有当您动态地获得代码时,这种切换才有价值,否则您知道它的价值的磁贴没有附加值切换。