Xamarin中Rg.Plugins.Popup的PopupPage内MediaGallery无法使用如何解决
Xamarin iOS下PopupPage调用Xamarin.MediaGallery失效解决方案
问题原因
Rg.Plugins.Popup 在 iOS 平台使用独立的 Window 层级展示 PopupPage,系统相册选择器默认找不到正确的呈现控制器,导致选择器无法正常弹出。
可用解决方案
方案1:指定呈现控制器(最优解,无需关闭弹窗)
通过 Xamarin.Essentials 提供的方法获取当前顶层视图控制器,传给 MediaGallery 的重载方法,强制指定选择器的承载层级,修改代码如下:
async void pickimg_Tapped(System.Object sender, EventArgs e) { try { MediaGalleryPickResult result; if(Device.RuntimePlatform == Device.iOS) { // 获取当前顶层控制器 var currentVC = Xamarin.Essentials.Platform.GetCurrentUIViewController(); var presentationSource = PresentationSource.FromUIViewController(currentVC); // 传入控制器调用选择器 result = await MediaGallery.PickAsync(presentationSource, 5, MediaFileType.Image, MediaFileType.Video); } else { // Android 平台走原有逻辑 result = await MediaGallery.PickAsync(5, MediaFileType.Image, MediaFileType.Video); } if(result?.Files == null) { return; } foreach (var img in result.Files) { var filename = img.NameWithoutExtension; // 后续业务逻辑 } } catch(Exception ex) { // 处理权限拒绝、用户取消等异常 } }
如果未引入 Xamarin.Essentials,可在 iOS 项目自行获取根控制器:
UIViewController rootVC; if(UIDevice.CurrentDevice.CheckSystemVersion(13,0)) { rootVC = UIApplication.SharedApplication.Windows.FirstOrDefault(w => w.IsKeyWindow)?.RootViewController; } else { rootVC = UIApplication.SharedApplication.KeyWindow.RootViewController; }
方案2:临时关闭弹窗再调用选择器
如果业务逻辑允许临时关闭 PopupPage,可采用更简单的兼容方案:
async void pickimg_Tapped(System.Object sender, EventArgs e) { // 先关闭当前弹窗 await Rg.Plugins.Popup.Services.PopupNavigation.Instance.PopAsync(); // 调用相册选择 var result = await MediaGallery.PickAsync(5, MediaFileType.Image, MediaFileType.Video); if(result?.Files != null) { foreach (var img in result.Files) { var filename = img.NameWithoutExtension; // 后续业务逻辑 } } // 操作完成后重新弹出弹窗,按需传入业务参数 await Rg.Plugins.Popup.Services.PopupNavigation.Instance.PushAsync(new YourPopupPage(/* 自定义参数 */)); }
注意事项
- 提前调用权限检查接口确认相册权限已授权,权限未通过时 MediaGallery 会直接返回空,和弹窗兼容问题无关
- 升级 Rg.Plugins.Popup 到最新稳定版,旧版本在 iOS 14+ 以上存在已知的视图层级兼容问题
内容的提问来源于stack exchange,提问作者Chim Di Tru
相关产品推荐
相关产品推荐

