SwiftUI and UICloudSharingController hate each other

后端 未结 2 2008
离开以前
离开以前 2021-02-06 12:27

I have a project using SwiftUI that requires CloudKit sharing, but I\'m unable to get the UICloudSharingController to play nice in a SwiftUI environment.

2条回答
  •  长情又很酷
    2021-02-06 12:58

    I got this working -- initially, I wrapped the UICloudSharingController in a UIViewControllerRepresentable, much like the link you provided (I referenced that while building it), and simply adding it to a SwiftUI .sheet() view. This worked on the iPhone, but it failed on the iPad, because it requires you to set the popoverPresentationController?.sourceView, and I didn't have one, given that I triggered the sheet with a SwiftUI Button.

    Going back to the drawing board, I rebuilt the button itself as a UIViewRepresentable, and was able to present the view using the rootViewController trick that SeungUn Ham suggested here. All works, on both iPhone and iPad - at least in the simulator.

    My button:

    struct UIKitCloudKitSharingButton: UIViewRepresentable {
        typealias UIViewType = UIButton
    
        @ObservedObject
        var toShare: ObjectToShare
        @State
        var share: CKShare?
    
        func makeUIView(context: UIViewRepresentableContext) -> UIButton {
            let button = UIButton()
    
            button.setImage(UIImage(systemName: "person.crop.circle.badge.plus"), for: .normal)
            button.addTarget(context.coordinator, action: #selector(context.coordinator.pressed(_:)), for: .touchUpInside)
    
            context.coordinator.button = button
            return button
        }
    
        func updateUIView(_ uiView: UIButton, context: UIViewRepresentableContext) {
    
        }
    
        func makeCoordinator() -> Coordinator {
            Coordinator(self)
        }
    
        class Coordinator: NSObject, UICloudSharingControllerDelegate {
            var button: UIButton?
    
            func cloudSharingController(_ csc: UICloudSharingController, failedToSaveShareWithError error: Error) {
                //Handle some errors here.
            }
    
            func itemTitle(for csc: UICloudSharingController) -> String? {
                return parent.toShare.name
            }
    
            var parent: UIKitCloudKitSharingButton
    
            init(_ parent: UIKitCloudKitSharingButton) {
                self.parent = parent
            }
    
            @objc func pressed(_ sender: UIButton) {
                //Pre-Create the CKShare record here, and assign to parent.share...
    
                let sharingController = UICloudSharingController(share: share, container: myContainer)
    
                sharingController.delegate = self
                sharingController.availablePermissions = [.allowReadWrite]
                if let button = self.button {
                    sharingController.popoverPresentationController?.sourceView = button
                }
    
                UIApplication.shared.windows.first?.rootViewController?.present(sharingController, animated: true)
            }
        }
    }
    

提交回复
热议问题