由于 SwiftUI 的 Alert
不支持 TextField
,我需要使用 UIAlertContoller
。
由于各种原因(包括可访问性、动态类型、深色模式支持等),我不能使用自定义创建的 AlertView。
基本思路是,SwiftUI 的警报必须包含 TextField
,并且输入的文本必须反映回用途。
我通过符合 UIViewControllerRepresentable
来创建了一个 SwiftUI 视图,下面是可工作的代码。
struct AlertControl: UIViewControllerRepresentable {
typealias UIViewControllerType = UIAlertController
@Binding var textString: String
@Binding var show: Bool
var title: String
var message: String
func makeUIViewController(context: UIViewControllerRepresentableContext<AlertControl>) -> UIAlertController {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addTextField { textField in
textField.placeholder = "Enter some text"
}
let cancelAction = UIAlertAction(title: "cancel", style: .destructive) { (action) in
self.show = false
}
let submitAction = UIAlertAction(title: "Submit", style: .default) { (action) in
self.show = false
}
alert.addAction(cancelAction)
alert.addAction(submitAction)
return alert
}
func updateUIViewController(_ uiViewController: UIAlertController, context: UIViewControllerRepresentableContext<AlertControl>) {
}
func makeCoordinator() -> AlertControl.Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UITextFieldDelegate {
var control: AlertControl
init(_ control: AlertControl) {
self.control = control
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let text = textField.text {
self.control.textString = text
}
return true
}
}
}
// SwiftUI View in some content view
AlertControl(textString: self.$text,
show: self.$showAlert,
title: "Title goes here",
message: "Message goes here")
问题:
当点击警报操作时,没有任何反应。 我设置了断点进行检查,但它从未命中过。
即使是UITextFieldDelegate
的函数也从未执行。
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
编辑: 点击这些字段时,
cancelAction
或submitAction
不会被触发。
cancelAction
或submitAction
不会触发。 - Nasir2020-04-17 22:11:27.121106+0530 SwiftUI Alert Controller[98884:3206838] Warning: Attempt to present <UIAlertController: 0x7f8cdd87e000> on <UIViewController: 0x7f8cdd704fd0> which is already presenting (null)
总的来说,它解决了问题。再次感谢。 - Nasirguard
是必需的,因为我们无法控制SwiftUI何时调用可表示性中的更新,所以为了避免冲突,如果警报已经显示,我添加了guard并修改了代码来存储警报。当我使用这种方法进行测试时,我不再收到控制台中的任何警告。 - Asperi