SwiftUI Sheet中展示UIActivityViewController出现布局警告,求最佳实现方案
在SwiftUI中正确展示UIActivityViewController的方法
在iOS 16、Xcode 14环境下,直接用SwiftUI的sheet展示UIActivityViewController会触发布局约束警告,这是因为sheet的容器布局和系统分享控制器的自适配逻辑冲突导致的。正确的做法是通过UIKit的present方式调用分享控制器,而非SwiftUI的sheet组件。
触发的警告信息
2022-10-23 23:41:07.692216+0300 Test UIActivityViewController[92164:30374157] [LayoutConstraints] Changing the translatesAutoresizingMaskIntoConstraints property of a UICollectionReusableView that is managed by a UICollectionView is not supported, and will result in incorrect self-sizing. View: <_UIActivityContentFooterView: 0x15cd56340; baseClass = UICollectionReusableView; frame = (16 244.333; 361 52); layer = <CALayer: 0x600001ab8180>>
正确实现代码
1. 封装UIActivityViewController的UIViewControllerRepresentable
import SwiftUI struct ShareSheet: UIViewControllerRepresentable { let items: [Any] let completion: (UIActivity.ActivityType?, Bool) -> Void func makeUIViewController(context: Context) -> UIActivityViewController { let controller = UIActivityViewController(activityItems: items, applicationActivities: nil) controller.completionWithItemsHandler = { activityType, completed, _, _ in completion(activityType, completed) } return controller } func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {} }
2. 在ContentView中调用分享控制器
import SwiftUI struct ContentView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundColor(.accentColor) Text("Hello, world!") .onTapGesture { showShareSheet() } } } private func showShareSheet() { let shareText = "Hello everybody" let shareSheet = ShareSheet(items: [shareText]) { activityType, completed in // 分享完成后的回调逻辑,比如更新状态、提示用户等 if completed { print("分享成功") } } guard let rootViewController = UIApplication.shared.connectedScenes .filter({ $0.activationState == .foregroundActive }) .first(where: { $0 is UIWindowScene }) .flatMap({ $0 as? UIWindowScene })?.windows .first(where: { $0.isKeyWindow })?.rootViewController else { return } rootViewController.present(shareSheet, animated: true) } }
关键说明
- 避免使用SwiftUI的
sheet展示UIActivityViewController,改用UIKit的present方法,从当前活跃的keyWindow的rootViewController发起调用,确保分享控制器的布局符合系统规范。 - 增加了
completion回调,可以在分享完成后处理后续逻辑,比如给用户反馈状态。
内容的提问来源于stack exchange,提问作者Husam
相关产品推荐
相关产品推荐

