iOS17下UIActivityController在消息及社交平台无法正常工作求助
iOS 17 UIActivityViewController 分享异常问题解决
问题场景
使用以下代码实现分享功能:
let shareMesage = "\(StringUtils.getTranslationWithKey("checknow")) \(package_name)\n\n\(urlString)" let activityViewController = UIActivityViewController(activityItems: [shareMesage], applicationActivities: nil) activityViewController.popoverPresentationController?.sourceView = self.custom_navigationBar activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToFacebook ] self.present(activityViewController, animated: true)
在iOS 17系统中,点击WhatsApp或短信平台时,分享活动控制器无法关闭,同时抛出以下错误:
Attempt to present <SLComposeViewController: 0x12283ba00> on <UINavigationController: 0x122816000> (from <SHSheetSceneViewController: 0x11f258f00>) whose view is not in the window hierarchy. Trying to perform <UISocialActivity: 0x282e18b00> activityType:net.whatsapp.WhatsApp.ShareExtension activityTitle:UISocialActivity but there is already an activity performing:<SHSheetActivityPerformer: 0x2839638e0>
解决方法
1. 改用窗口根视图控制器present分享面板
iOS 17中系统对分享面板的容器SHSheetSceneViewController做了调整,直接用当前控制器present可能导致视图层级异常。改用key window的根视图控制器来present:
// 获取当前活跃窗口的根视图控制器 guard let rootVC = UIApplication.shared.connectedScenes .filter({ $0.activationState == .foregroundActive }) .compactMap({ $0 as? UIWindowScene }) .first?.windows .first(where: { $0.isKeyWindow })?.rootViewController else { return } rootVC.present(activityViewController, animated: true)
2. 完善popoverPresentationController配置
仅设置sourceView可能导致popover定位错误,补充sourceRect参数:
activityViewController.popoverPresentationController?.sourceView = self.custom_navigationBar activityViewController.popoverPresentationController?.sourceRect = self.custom_navigationBar.bounds // iPad端可指定箭头方向 activityViewController.popoverPresentationController?.permittedArrowDirections = .any
3. 添加分享完成回调确保控制器正常关闭
通过completionWithItemsHandler监听分享状态,手动处理控制器的dismiss:
activityViewController.completionWithItemsHandler = { [weak self] activityType, completed, returnedItems, error in guard let self = self else { return } // 无论成功/失败/取消,确保控制器被关闭 if activityViewController.presentingViewController != nil { activityViewController.dismiss(animated: true) } }
4. 排查重复触发逻辑
检查按钮点击事件是否存在重复绑定、多次调用present的情况,避免多个分享面板叠加导致的冲突。
内容的提问来源于stack exchange,提问作者Krishna Yadav
相关产品推荐
相关产品推荐

