Xamarin.iOS实现UIPopoverViewController在iPhone和iPad居中显示
解决Xamarin.iOS中UIPopoverViewController居中显示问题
我来帮你搞定这个在iPhone和iPad上的弹窗显示问题,这两个平台的适配逻辑确实需要针对性调整,咱们一步步修改你的代码:
问题根源分析
- iPhone端:默认情况下,UIPopover会自适应为全屏模态视图,即使设置了
UIModalPresentationStyle.Popover,也需要明确指定弹窗的尺寸,同时确保自适应样式正确生效。 - iPad端:你之前把弹窗锚定在了
showButton的Frame上,所以它会显示在按钮附近,要让它居中,需要调整弹窗的锚定区域和展示配置。
修改后的完整代码
public override void ViewDidLoad() { base.ViewDidLoad(); showButton.TouchUpInside += (sender, e) => { // 创建弹窗内容视图 UIImageView monkeyIcon = new UIImageView(new CGRect(0, 0, 200, 200)); monkeyIcon.Image = UIImage.FromFile("Abc.png"); monkeyIcon.UserInteractionEnabled = true; monkeyIcon.ContentMode = UIViewContentMode.ScaleAspectFit; // 创建弹窗容器ViewController UIViewController popover = new UIViewController(); popover.View = monkeyIcon; popover.ModalPresentationStyle = UIModalPresentationStyle.Popover; // 关键:设置弹窗的首选尺寸,这会同时影响iPhone和iPad的显示大小 popover.PreferredContentSize = new CGSize(200, 200); // 添加关闭按钮 var closeButton = new UIButton(new CGRect(0, 160, 200, 40)); closeButton.SetTitle("Close", UIControlState.Normal); closeButton.SetTitleColor(UIColor.Blue, UIControlState.Normal); closeButton.UserInteractionEnabled = true; monkeyIcon.AddSubview(closeButton); // 关闭按钮事件 closeButton.TouchUpInside += (button, e2) => { popover.DismissViewController(true, null); }; // 展示弹窗 PresentViewController(popover, true, null); // 配置Popover展示控制器 UIPopoverPresentationController presentationPopover = popover.PopoverPresentationController; if (presentationPopover != null) { presentationPopover.SourceView = this.View; // 关键:设置锚定区域为屏幕中心的一个小矩形,这样弹窗会居中显示 presentationPopover.SourceRect = new CGRect(View.Bounds.GetMidX() - 1, View.Bounds.GetMidY() - 1, 2, 2); // 禁用箭头,因为我们不需要锚定到某个控件 presentationPopover.PermittedArrowDirections = UIPopoverArrowDirection.None; presentationPopover.Delegate = this; } }; } // 关键:确保iPhone上不自动转为全屏模态 [Export("adaptivePresentationStyleForPresentationController:")] public UIModalPresentationStyle GetAdaptivePresentationStyle(UIPresentationController forPresentationController) { return UIModalPresentationStyle.None; } // 额外:如果需要支持iOS 13+,可以添加这个方法确保自适应行为 [Export("adaptivePresentationStyleForPresentationController:traitCollection:")] public UIModalPresentationStyle GetAdaptivePresentationStyle(UIPresentationController controller, UITraitCollection traitCollection) { return UIModalPresentationStyle.None; } public override void DidReceiveMemoryWarning() { base.DidReceiveMemoryWarning(); // 释放缓存资源 }
核心修改点说明
- 统一设置弹窗尺寸:添加
popover.PreferredContentSize = new CGSize(200, 200);,明确告诉系统弹窗的大小,这是让iPhone端显示小弹窗的关键。 - 调整iPad端锚定区域:把
SourceRect设置为屏幕中心的一个2x2的小矩形,这样弹窗会以这个点为中心展示,同时禁用箭头方向,避免出现不必要的箭头。 - 完善自适应样式支持:新增了iOS 13+的自适应样式方法,确保在新版本系统上也能正确生效,避免弹窗自动转为全屏。
- 调整关闭按钮位置:把关闭按钮移到弹窗底部,避免遮挡图片内容,提升用户体验。
这样修改后,iPhone上会显示居中的小尺寸弹窗,iPad上也会在屏幕中央展示弹窗,符合你的需求。
内容的提问来源于stack exchange,提问作者Harshad Pansuriya
相关产品推荐
相关产品推荐

