3

我一直在尝试创建一个UIAlertAtion也有处理程序的。我阅读了这个问题的答案,并且知道该怎么做。

我的问题只是关于它的关闭部分。

1)我知道我会写:{alert in println("Foo")}或者{_ in println("Foo")}但我不会{println("Foo")}在这里的评论中进行了解释,因为您需要处理参数 action

这是否意味着由于处理程序的类型是(UIAlertAction) -> Void)?我必须始终捕获传递的警报动作?


2) 我也读了这个,答案基本上是说你可以传入一个函数作为你的参数,但函数应该采用 type 的东西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) 在评论中还说:但除此之外,您不必快速编写 UIAlertActionStyle.Default 。.Default 也可以

我尝试不使用样式编写,因此默认为.Default

let sendLogAction = UIAlertAction(title: "Log") { action in print("goodbye")}

但后来我收到以下错误:

'(title: String, (_) -> ())' (aka '(title: String, _ -> ())') 不能转换为 '(title: String?, style: UIAlertActionStyle, handler: (( UIAlertAction) -> Void)?)' (aka '(title: Optional, style: UIAlertActionStyle, handler: Optional ()>)'),元组有不同数量的元素


4) 同时阅读这个答案。我不明白为什么我们需要传递alert它是没有意义的。并不是不知道 alert 的类型是什么……我们不是已经定义了它的类型了吗?!!谁能解释一下传递动作本身通常在哪里有用,我的意思是我们能用它做什么?


我知道这是写成 4 个问题,但我认为这实际上只是一个基础问题。我已经广泛阅读,在我正在操场上工作和玩耍的项目中使用了闭包/完成处理程序,但我仍然感到困惑。

4

3 回答 3

3
  1. 是的,您必须始终处理争论。它是签名的一部分,不容忽视。它也是一种特殊的 Swift 语法,能够删除handler参数,因为它是最后一个参数并且它是一个闭包参数。

  2. 更改anything(action)anything就像您链接到的示例中一样。

  3. 你误会了。他们并不是说您可以删除样式参数。他们说你可以放弃UIAlertActionStylefromUIAlertActionStyle.Default意思,你只需要.Default作为参数传递给 style 参数。

  4. 您想要一个action处理程序参数有用的示例。真的没有太多用处。唯一的属性是标题、样式以及是否启用。后者是没有意义的,因为如果调用了处理程序,您就知道它已启用。唯一可能的用途是,如果需要在处理程序中使用标题或样式,并且在创建警报操作时它们没有硬编码到警报操作中。通过访问处理程序中的标题或样式属性,您可以轻松访问创建操作时使用的实际值。

于 2016-11-30T17:09:22.343 回答
1

rmaddy 的回答就足够了,但作为 OP :) 我找到了我的问题的根本原因:

我缺乏对参数处理程序的理解,处理程序是类型:(UIAlertAction) -> Void)?即闭包/函数

处理程序只需要一个函数名称,一旦您提供该函数,它将填写该函数本身的输入。

传递anything作为处理程序,即函数名。

UIAlertAction 的内部实现有一些行,例如handler(action)which 将使用anythingwhich 类型(UIAlertAction) -> Void)?,inject action(传递给它)最终执行anything(action)

话虽如此,你anything(input: UIAlertAction)应该做一些有意义的事情。(已经在与 rmaddy 的评论中讨论过)


另一种解决方案是提供函数,而是在尾随闭包中使用捕获的操作,并使用它做任何你喜欢做的事情。

let retryAction = UIAlertAction(title: returnTitle(), style: UIAlertActionStyle.Default) { action in
switch action.title {
        case "OK":
        okFunc()
        case "cancel":
        cancelFunc()
        default:
        defaultFunc()
        }
      }

这种切换只有在您动态获取代码时才有价值,否则对于您知道它的价值的图块没有附加值切换。

于 2016-11-30T20:26:08.317 回答
0

1) UIAlerAction init 方法定义需要 3 个参数,最后一个参数是 (UIAlertAction -> Void)?这意味着你可以有一个“无名”函数(又名闭包)或一个 nil(由可选符号指定?)。如果您选择不指定最后一个参数,您可以像这样创建 UIAlertController

alert.addAction(UIAlertAction(title: "test", style: .default, handler: nil))

但是如果你想指定最后一个参数(不是 nil),那么你必须提供一个闭包,它将 UIAlertAction 作为参数并且什么都不返回(Void)。参考您的链接,他只是使用他为简单起见已经创建的“警报”常量。

要回答您的问题“这是否意味着……”,答案是肯定的,因为第三个参数的定义:(UIAlertAction) -> Void)?

2)您收到错误是因为您传递了参数(动作)。试试让

anotherAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default,
 handler: anything)

你不应该得到错误。

3) UIAlertAction 只有(我相信)一个 init 方法,所以你需要提供所有三个参数来创建它。请参阅我的 1) 样式答案:.default。这是一种调用 Swift Enums 的新方法。顺便说一句,所有枚举都必须是小写的,所以 .default 不是 .Default`在此处输入代码

alert.addAction(UIAlertAction(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) -> Void))

4)从答案中可以看出,您有链接。你可以使用常量'alert' (UIAlertAction) 来做任何你想做的事情,比如检查样式和做一些事情。

func anything(alert: UIAlertAction!) {
    print("somehandler")
    switch alert.title {
    case "OK"?:
      print("title is OK")
    default:
      print("title is not OK")
    }
  }
于 2016-11-30T17:41:55.757 回答