SwiftUI Catalyst Mac应用中UIButton第二次点击失效如何解决
问题根因
- 现有代码的核心问题是在
makeUIView方法中只创建了一次UIActivityViewController实例,同一个视图控制器实例只能被present一次,第一次弹出dismiss后该实例已经处于不可复用的状态,第二次点击尝试再次present同一个失效实例自然无响应,和UIButton销毁重建没有直接关系。 - 次要问题:直接取全局key window的根控制器present可能会有层级冲突,比如当前页面已经有其他present出来的控制器时会弹出失败。
修复方案1:修正现有UIViewRepresentable封装
适合需要支持Mac Catalyst 16以下版本的场景:
private struct ShareButton: UIViewRepresentable { // 可将分享内容做成参数,方便复用 let shareItems: [Any] func makeUIView(context: Context) -> UIButton { weak var weakButton: UIButton? let action = UIAction(title: "Share") { _ in // 每次点击都新建UIActivityViewController实例 let activityViewController = UIActivityViewController(activityItems: shareItems, applicationActivities: nil) guard let button = weakButton else { return } activityViewController.popoverPresentationController?.sourceView = button // 优先从当前最上层的控制器present,避免层级问题 guard let rootVC = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.rootViewController else { return } var topVC = rootVC while let presented = topVC.presentedViewController { topVC = presented } topVC.present(activityViewController, animated: true) } let button = UIButton(primaryAction: action) weakButton = button return button } func updateUIView(_ uiView: UIButton, context: Context) { } } // 使用示例:ShareButton(shareItems: [URL(string: "https://www.apple.com/")!])
修复方案2:使用SwiftUI原生ShareLink(推荐,适用于iOS 16+/Mac Catalyst 16+)
SwiftUI从16版本开始提供了原生的分享组件,完全适配Mac Catalyst的交互逻辑,不需要手动处理UIKit封装:
// 基础用法 ShareLink(item: URL(string: "https://www.apple.com/")!) { Text("Share") } // 自定义样式、分享预览的完整用法 ShareLink( title: "分享链接", items: [URL(string: "https://www.apple.com/")!], preview: SharePreview("Apple官网", image: Image(systemName: "link")) ) { Label("分享", systemImage: "square.and.arrow.up") }
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

