【问题标题】:ActionSheet crashes on iPad, not on iPhoneActionSheet 在 iPad 上崩溃,而不是在 iPhone 上
【发布时间】:2021-11-05 12:43:33
【问题描述】:

以下代码可以在多个地方的示例中找到,并且曾经为我工作,但现在它崩溃了。问题似乎出在 iPadOS 上,因为它似乎适用于 iPhone,包括模拟器和物理设备。

错误是:

'UIPopoverPresentationController () 应该有一个非零 sourceView 或 barButtonItem 在演示发生之前设置。 以 NSException 类型的未捕获异常终止

这是 iPadOS 上的错误还是我做错了什么?

import SwiftUI

struct ContentView: View {
    @State var showSheet = false
    var body: some View {
        Button(action: actionSheet)
        {
            Label("", systemImage: "square.and.arrow.up")
        }
    }
    
    func actionSheet() {
        let av = UIActivityViewController(activityItems: ["Testing"], applicationActivities: nil)
        UIApplication.shared.windows.first?.rootViewController?.present(av, animated: true, completion: nil)
    }
}

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

【问题讨论】:

  • 该错误非常具有描述性。查看at this 以获取有关如何在自定义视图控制器中设置sourceView 的示例。 popover.adaptiveSheetPresentationController 代码是 iOS 15 代码,您可以跳过所有代码以使其适用于 iOS 14 及更低版本。

标签: swiftui ipados actionsheet


【解决方案1】:

看到 lorem ipsum 的回复后,我更改了以下内容,它适用于 iOS 15 及之前的版本。

func actionSheet() {
        let av = UIActivityViewController(activityItems: ["Testing"], applicationActivities: nil)
        
        av.popoverPresentationController?.sourceView = HostingView(rootView: self)
        UIApplication.shared.windows.first?.rootViewController?.present(av, animated: true, completion: nil)
    }
    
    class HostingView<T: View>: UIView {
        
        private(set) var hostingController: UIHostingController<T>
        
        var rootView: T {
            get { hostingController.rootView }
            set { hostingController.rootView = newValue }
        }
        
        init(rootView: T, frame: CGRect = .zero) {
            hostingController = UIHostingController(rootView: rootView)
            
            super.init(frame: frame)
            
            backgroundColor = .clear
            hostingController.view.backgroundColor = backgroundColor
            hostingController.view.frame = self.bounds
            hostingController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            
            addSubview(hostingController.view)
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }

【讨论】:

  • 把 if 拿出来。只有自适应部分是 iOS 15 你的代码不使用它。
  • 非常感谢。我尝试了另一种解决方案,它也很有效,但这更简单。
  • 很高兴您找到了解决方案。仅供参考,如果您在任何类型的工作表上,UIApplication 部分将不起作用。那是因为 SwiftUI 出现在同一个地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-07
  • 1970-01-01
相关资源
最近更新 更多