SwiftUI:UIAlertController ActionSheet 全屏

Posted

技术标签:

【中文标题】SwiftUI:UIAlertController ActionSheet 全屏【英文标题】:SwiftUI: UIAlertController ActionSheet is full screen 【发布时间】:2020-04-23 07:33:51 【问题描述】:

我正在尝试在 SwiftUI View 中实现一个选中标记的操作表。我正在使用一个 UIViewControllerRepresentable 创建一个UIAlertController

struct WhatsAppAlertController: UIViewControllerRepresentable 
    let viewModel: PropViewModel

    func makeUIViewController(context: Context) -> UIAlertController 
        let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
        let contactsNumbers = viewModel.contactsNumbers()

        for number in contactsNumbers 
            let action = UIAlertAction(
                title: "\(number.value.stringValue)",
                style: .default,
                handler:  _ in
                self.viewModel.openWhatsAppURL(withNumber: number.value.stringValue)
            )
            alert.addAction(action)
        

        let cancel = UIAlertAction(title: L10n.cancel, style: .cancel, handler: nil)

        alert.addAction(cancel)

        return alert 
    

    func updateUIViewController(_ uiViewController: UIAlertController, context: Context) 
    

它是使用显示的

.sheet(isPresented: $showWhatsAppActionSheet) 
            WhatsAppAlertController(viewModel: self.viewModel)
        

我感觉这是因为 UIAlertController 是使用 .sheet 呈现的

我的计划是使用action.setValue(true, forKey: "checked") 勾选并记住所选选项。

有没有办法解决这个问题?或者也许只使用 SwiftUI 实现复选标记?

【问题讨论】:

This post 可能会有所帮助。 谢谢!设法修复它。 【参考方案1】:

我的错误是没有创建一个持有者控制器,一个UIViewController 来容纳UIAlertController。演示文稿也应该使用.background() 而不是.sheet()

这是更新后的代码:

struct WhatsappAlertController: UIViewControllerRepresentable 
    @Binding var show: Bool
    let viewModel: PropViewModel

    func makeUIViewController(context: UIViewControllerRepresentableContext<WhatsappAlertController>) -> UIViewController 
        return UIViewController() // holder controller - required to present alert
    

    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<WhatsappAlertController>) 
        if self.show 

            let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
            let contactsNumbers = viewModel.contactsNumbers()

            for number in contactsNumbers 
                let action = UIAlertAction(
                    title: "\(number.value.stringValue)",
                    style: .default,
                    handler:  _ in
                        self.viewModel.openWhatsAppURL(withNumber: number.value.stringValue)
                )
//                action.setValue(true, forKey: "checked")
                alert.addAction(action)
            

            let cancel = UIAlertAction(title: L10n.cancel, style: .cancel, handler: nil)

            alert.addAction(cancel)

            DispatchQueue.main.async  // must be async !!
                uiViewController.present(alert, animated: true, completion: 
                    self.show = false  // hide holder after alert dismiss
                )
            
        
    

并显示:

.background(WhatsappAlertController(show: self.$showWhatsAppActionSheet, viewModel: viewModel))

【讨论】:

以上是关于SwiftUI:UIAlertController ActionSheet 全屏的主要内容,如果未能解决你的问题,请参考以下文章

iOS核心笔记——UIAlertController

从第一个 UIAlertController 打开第二个 UIAlertController

swift UIAlertController使用 UIAlertController的宽度 为270

从 AppDelegate 到 PresentedViewController 的警报:“尝试在...上呈现 UIAlertController 已经在呈现 UIAlertController”

禁止UIAlertController的dimiss

UIAlertController的popover变形