Как вы должны обрабатывать аргументы закрытия для UIAlertAction
Я пытаюсь создать UIAlertAtion
, который также имеет обработчик. Я прочитал ответы из этого вопроса и знаю, как это сделать.
Мой вопрос касается только его закрывающей части.
1) Я знаю, что могу написать: {alert in println("Foo")}
Или {_ in println("Foo")}
, но я не могу написать {println("Foo")}
. В комментариях здесь это объясняется тем, что вам нужно обработать действие с аргументом.
Означает ли это, что, поскольку обработчик имеет тип (UIAlertAction) -> Void)?
, я должен всегда захватывать переданный alertAction?
2)
Я также читаю этот, и в основном ответ заключается в том, что вы можете передать функцию как свой аргумент, но функция должна взять что-то типа 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'
confused, почему я получаю эту ошибку
3)
В комментариях он также сказал: Но в дополнение к этому вам не нужно писать UIAlertActionStyle.Default в быстром..Default тоже работает.
Я пробовал писать, не используя стиль, поэтому он будет по умолчанию .Default
let sendLogAction = UIAlertAction(title: "Log") { action in print("goodbye")}
Но затем я получаю следующую ошибку:
'(title: String, (_) → ())' (aka '(title: String, _ → ())') не является convertible to '(название: String?, style: UIAlertActionStyle, обработчик: ((UIAlertAction) → Void)?) '(Aka' (название: необязательно, стиль: UIAlertActionStyle, обработчик: необязательный() > ) '), кортежи имеют различное количество элементов
4)
Также читайте этот ответ. Я не понимаю, зачем нам проходить в alert
, это не имеет смысла. Это не похоже на то, что мы не знаем, что такое тип предупреждения... разве мы уже не определили его тип?!! Может ли кто-нибудь объяснить, когда передача самого действия будет полезной вообще, я имею в виду, что мы можем с ней сделать?
Я знаю, что это написано как 4 вопроса, но я думаю, что это действительно просто основополагающий вопрос. Я широко читал, использовал обработчики закрытия/завершения в проекте, который я работаю и играю на детской площадке, но все же я в замешательстве.
Ответы
Ответ 1
-
Да, вы должны всегда обрабатывать аргумент. Это часть подписи и не может быть проигнорирована. Кроме того, специальный синтаксис Swift может отбрасывать параметр handler
, поскольку он является последним параметром и является параметром закрытия.
-
Измените anything(action)
на anything
так же, как в примере, на который вы ссылаетесь.
-
Вы неправильно поняли. Они не говорят, что вы можете отказаться от параметра стиля. Они говорят, что вы можете отказаться от UIAlertActionStyle
от UIAlertActionStyle.Default
, что означает, что вам нужно передать .Default
в качестве аргумента в параметр стиля.
-
Вам нужен пример использования параметра action
для обработчика. На самом деле не так уж много применений. Единственными свойствами являются название, стиль и включен ли он или нет. Последнее бессмысленно, потому что, если обработчик был вызван, вы знаете, что он включен. Единственное возможное использование - если заголовок или стиль должны использоваться в обработчике, и они не были жестко закодированы в действие предупреждения, когда оно было создано. Получив доступ к свойствам заголовка или стиля в обработчике, вы легко получаете доступ к фактическим значениям, используемым при создании действия.
Ответ 2
1) Определение метода инициализации UIAlerAction принимает 3 аргумента, а последний аргумент (UIAlertAction → Void)? что означает, что у вас может быть функция no-name (или закрытие) или нуль (задается необязательным символом?). Если вы решите не указывать последний аргумент, вы можете таким образом отобразить 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 not. Код Default`enter здесь
alert.addAction(UIAlertAction(title: String?, style: UIAlertActionStyle, handler: ((UIAlertAction) -> Void))
4) Как вы можете видеть из ответа, у вас есть ссылка. Вы можете использовать постоянное "предупреждение" (UIAlertAction), чтобы делать с ним все, что хотите, например, проверять стиль и делать некоторые вещи.
func anything(alert: UIAlertAction!) {
print("somehandler")
switch alert.title {
case "OK"?:
print("title is OK")
default:
print("title is not OK")
}
}
Ответ 3
rmaddy answer достаточно, но являюсь OP:) Я нахожу основную причину моего вопроса:
Недостаток в понимании обработчика параметров, обработчик имеет тип: (UIAlertAction) -> Void)?
т.е. замыкание/функция
Обработчик ожидает только имя функции, как только вы предоставите эту функцию, она заполнит входы этой функции .
вы передаете anything
только как обработчик, т.е. имя функции.
Внутренняя реализация UIAlertAction имеет некоторую строку типа handler(action)
, которая использовала бы anything
, которая имеет тип (UIAlertAction) -> Void)?
, вставляет 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()
}
}
Такое переключение полезно только в том случае, если вы получаете код динамически, иначе нет переключения добавленного значения для плитки, которую вы знаете ее значение.