- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个使用 SwiftUI 的项目需要 CloudKit 共享,但我无法让 UICloudSharingController
在 SwiftUI 环境中正常运行。
第一个问题
使用 UIViewControllerRepresentable
直接包装 UICloudSharingController
会产生一个无限旋转器(参见 this )。正如对其他系统 Controller (如 UIActivityViewController
)所做的那样,我将 UICloudSharingController
包装在一个包含 UIViewController
中,如下所示:
struct CloudSharingController: UIViewControllerRepresentable {
@EnvironmentObject var store: CloudStore
@Binding var isShowing: Bool
func makeUIViewController(context: Context) -> CloudControllerHost {
let host = CloudControllerHost()
host.rootRecord = store.noteRecord
host.container = store.container
return host
}
func updateUIViewController(_ host: CloudControllerHost, context: Context) {
if isShowing, host.isPresented == false {
host.share()
}
}
}
final class CloudControllerHost: UIViewController {
var rootRecord: CKRecord? = nil
var container: CKContainer = .default()
var isPresented = false
func share() {
let sharingController = shareController
isPresented = true
present(sharingController, animated: true, completion: nil)
}
lazy var shareController: UICloudSharingController = {
let controller = UICloudSharingController { [weak self] controller, completion in
guard let self = self else { return completion(nil, nil, CloudError.controllerInvalidated) }
guard let record = self.rootRecord else { return completion(nil, nil, CloudError.missingNoteRecord) }
let share = CKShare(rootRecord: record)
let operation = CKModifyRecordsOperation(recordsToSave: [record, share], recordIDsToDelete: [])
operation.modifyRecordsCompletionBlock = { saved, _, error in
if let error = error {
return completion(nil, nil, error)
}
completion(share, self.container, nil)
}
self.container.privateCloudDatabase.add(operation)
}
controller.delegate = self
controller.popoverPresentationController?.sourceView = self.view
return controller
}()
}
这允许 Controller 正常启动,但是......
第二个问题
点击关闭按钮或滑动以关闭, Controller 将消失,但没有通知它已被关闭。启动呈现 Controller 的 SwiftUI View 的 @State
属性仍然是 true
。没有明显的方法来检测模态的解除。经过一些试验,我发现呈现 Controller 是在 SceneDelegate
中创建的原始 UIHostingController
。通过一些 hackery,您可以将 UIHostingController
子类中引用的对象注入(inject)到 CloudSharingController
中。这将使您检测到解雇并将 @State
属性设置为 false
。然而,所有导航栏按钮在关闭后都不再起作用,所以你只能点击一次这个东西。场景的其余部分完全可用,但导航栏中的按钮没有响应。
第三个问题
即使您可以让 UICloudSharingController
正常显示和关闭,点击任何共享方法(消息、邮件等)都会使 Controller 消失,没有动画和用于共享的 Controller URL
没有出现。没有崩溃或控制台消息——它就消失了。
演示
我在 GitHub 上做了一个快速而肮脏的项目来演示这个问题:CloudKitSharing .它只是创建一个 String
和一个 CKRecord
来使用 CloudKit 来表示它。该界面显示 String
(一个 UUID
)和一个用于共享它的导航栏按钮:
请求
有什么方法可以在 SwiftUI 中使用 UICloudSharingController
吗?没有时间在 UIKit 或自定义共享 Controller 中重建项目(我知道——处于最前沿的代价 💩)
最佳答案
我得到了这个工作 - 最初,我将 UICloudSharingController
包装在 UIViewControllerRepresentable
中,很像你提供的链接(我在构建它时引用了它),并且简单将它添加到 SwiftUI .sheet() View 。这在 iPhone 上有效,但在 iPad 上失败了,因为它需要你设置 popoverPresentationController?.sourceView
,而我没有,因为我用 SwiftUI 按钮触发了工作表.
回到绘图板,我将按钮本身重新构建为 UIViewRepresentable
,并且能够使用 SeungUn Ham 在这里建议的 rootViewController 技巧来呈现 View 。在 iPhone 和 iPad 上一切正常——至少在模拟器中是这样。
我的按钮:
struct UIKitCloudKitSharingButton: UIViewRepresentable {
typealias UIViewType = UIButton
@ObservedObject
var toShare: ObjectToShare
@State
var share: CKShare?
func makeUIView(context: UIViewRepresentableContext<UIKitCloudKitSharingButton>) -> 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<UIKitCloudKitSharingButton>) {
}
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)
}
}
}
关于ios - SwiftUI 和 UICloudSharingController 互相讨厌,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59230784/
我遇到的问题不是紧急情况,但我不知道该怎么做。我有两个 aspx 网络表单页面。每个都有一个下拉列表。两者都由来自 sql server 的相同数据源填充。问题是,如果我在第 1 页选择一个值,然后转
我正在使用 OpenvSwitch-2.5.2 在两个虚拟机上设置第 2 层网络,如上图所示。 在阅读了 ovs 官方教程和其他一些文章后,我在每个虚拟机上尝试了以下命令: # on vm1 ip l
我是一名优秀的程序员,十分优秀!