Unity iOS原生分享插件Swift实现报错:present方法找不到的解决办法
解决Swift实现Unity iOS分享插件的UIActivityViewController调用问题
核心问题原因
present是UIViewController的实例方法,你的UnityPlugin类受限于Swift单继承特性,没法直接继承UIViewController,所以得通过获取Unity当前的根视图控制器来调用这个方法。
具体实现步骤
1. 获取Unity根视图控制器
在Swift中通过UIApplication的keyWindow定位根控制器,代码如下:
private func getUnityRootViewController() -> UIViewController? { guard let keyWindow = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) else { return nil } return keyWindow.rootViewController }
2. 封装通用分享方法
在你的UnityPlugin类中添加分享逻辑,通过获取到的根控制器弹出UIActivityViewController:
func shareContent(text: String?, image: UIImage?, url: URL?) { var activityItems: [Any] = [] // 组装分享内容 if let text = text { activityItems.append(text) } if let image = image { activityItems.append(image) } if let url = url { activityItems.append(url) } guard !activityItems.isEmpty else { return // 无分享内容直接返回 } let activityVC = UIActivityViewController(activityItems: activityItems, applicationActivities: nil) // 弹出分享界面 if let rootVC = getUnityRootViewController() { // 适配iPad弹窗位置 if UIDevice.current.userInterfaceIdiom == .pad { activityVC.popoverPresentationController?.sourceView = rootVC.view activityVC.popoverPresentationController?.sourceRect = CGRect(x: rootVC.view.bounds.midX, y: rootVC.view.bounds.midY, width: 0, height: 0) activityVC.popoverPresentationController?.permittedArrowDirections = [] } rootVC.present(activityVC, animated: true, completion: nil) } }
3. 关键注意事项
- 必须在主线程调用:Unity的原生回调可能在子线程执行,UI操作必须切换到主线程,示例:
DispatchQueue.main.async { self.shareContent(text: "测试分享文本", image: UIImage(named: "share_icon"), url: URL(string: "https://yourlink.com")) }
- iOS版本适配:如果是iOS 13+且使用SceneDelegate架构,可调整
getUnityRootViewController方法从当前Scene获取window,不过Unity默认仍采用UIApplication的window管理方式,上述代码可正常工作。
为什么不直接继承UIViewController?
Swift不支持多继承,你的UnityPlugin类应该已经继承了Unity相关的基类(比如NSObject),无法再继承UIViewController。通过获取当前根控制器的方式,是iOS插件开发中调用UI界面的标准方案,无需让插件类继承控制器。
内容的提问来源于stack exchange,提问作者aquaman
相关产品推荐
相关产品推荐

