【问题标题】:SwiftUI using .alert(isPresented) with a TextField for input?SwiftUI 使用 .alert(isPresented) 和 TextField 进行输入?
【发布时间】:2021-07-10 12:16:27
【问题描述】:

如何在 SwiftUI 中将 TextField 添加到 .alert() 函数?我只能找到需要 Swift 的解决方案,而不是 SwiftUI。

.alert(isPresented:$showingAlert) {
    Alert(
        title: Text("What is your name?"),
        message: Text("Fill in your name in the TextField beow"),
        primaryButton: .default(Text("OK")) {
            print("Opening...")

        },
        secondaryButton: .cancel() {
            print("cancelled)
        }
    )
}

【问题讨论】:

标签: swift swiftui


【解决方案1】:
extension UIAlertController {
    convenience init(alert: AlertConfig) {
        self.init(title: alert.title, message: nil, preferredStyle: .alert)
        addTextField { $0.placeholder = alert.placeholder }
        addAction(UIAlertAction(title: alert.cancel, style: .cancel) { _ in
            alert.action(nil)
        })
        let textField = self.textFields?.first
        addAction(UIAlertAction(title: alert.accept, style: .default) { _ in
            alert.action(textField?.text)
        })
    }
}



struct AlertHelper<Content: View>: UIViewControllerRepresentable {
    @Binding var isPresented: Bool
    let alert: AlertConfig
    let content: Content
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<AlertHelper>) -> UIHostingController<Content> {
        UIHostingController(rootView: content)
    }
    
    final class Coordinator {
        var alertController: UIAlertController?
        init(_ controller: UIAlertController? = nil) {
            self.alertController = controller
        }
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator()
    }
    
    
    func updateUIViewController(_ uiViewController: UIHostingController<Content>, context: UIViewControllerRepresentableContext<AlertHelper>) {
        uiViewController.rootView = content
        if isPresented && uiViewController.presentedViewController == nil {
            var alert = self.alert
            alert.action = {
                self.isPresented = false
                self.alert.action($0)
            }
            context.coordinator.alertController = UIAlertController(alert: alert)
            uiViewController.present(context.coordinator.alertController!, animated: true)
        }
        if !isPresented && uiViewController.presentedViewController == context.coordinator.alertController {
            uiViewController.dismiss(animated: true)
        }
    }
}

public struct AlertConfig {
    public var title: String
    public var placeholder: String = ""
    public var accept: String = "OK"
    public var cancel: String = "Cancel"
    public var action: (String?) -> ()
}

extension View {
    public func alert(isPresented: Binding<Bool>, _ alert: AlertConfig) -> some View {
        AlertHelper(isPresented: isPresented, alert: alert, content: self)
    }
}

struct ContentView: View {
    @State var isAlert = false
    var body: some View {
        VStack {
            Button("Show Alert") {
                self.isAlert = true
            }
        }
        .alert(isPresented: $isAlert, AlertConfig(title: "Title", action: {
            print("Text \($0 ?? "Cancelled")")
        }))
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

【讨论】:

  • 有效,谢谢!但由于某种原因,我的布局随着元素上的一些填充而发生了变化,我也添加了它
  • 知道是什么导致了你的代码吗? @rtxgamer
  • 我没听明白,你看到你展示的视图上的布局发生了变化吗?分享复制它的步骤。
  • pastebin.com/yy2SgWqg > 当你添加警报时,TitleBar() 会被垂直放置,并被大填充包围
  • NVM。通过将 TitleBar 代码移动到 Mainview 来解决它。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
  • 2021-05-17
  • 1970-01-01
相关资源
最近更新 更多