You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS 17中UIPopoverPresentationController无法保留偏好尺寸问题

iOS 17 中 UIPopoverPresentationController 无法保留内容控制器偏好尺寸的解决方法

问题根源

iOS 17 对 UIPopoverPresentationController 的尺寸计算逻辑做了调整,原有的依赖 view.frame 设置 preferredContentSize 的方式不再可靠,且重复展示弹窗时,控制器复用会导致尺寸被系统缓存的状态重置,出现压缩问题。

具体解决方案

1. 调整内容控制器的尺寸设置逻辑

在 contentVC 的 viewDidLoad 中,不要直接设置 self.view.frame,改为直接指定 preferredContentSize,避免依赖未完成布局的 view 尺寸:

- (void)viewDidLoad {
    [super viewDidLoad];

    // 直接设置偏好尺寸,替代手动设置view.frame
    self.preferredContentSize = CGSizeMake(320, 480);
    
    // 保留原有的边框设置
    CALayer *layer = self.view.layer;
    layer.borderColor = [[UIColor darkGrayColor] CGColor];
    layer.borderWidth = 2;
    layer.cornerRadius = 10;
}

2. 优化弹窗展示方法

移除从 contentVC.view.frame 获取尺寸的代码,确保 preferredContentSize 由内容控制器内部管理,或在外部明确指定:

+ (void) showDialogiPad:(UIViewController *)contentVC
       fromPresentingVC:(UIViewController *)presentingVC
                 inView:(UIView *)view
                atFrame:(CGRect)frame
          withDirection:(UIPopoverArrowDirection)direction {
    
    contentVC.modalPresentationStyle = UIModalPresentationPopover;
    
    // 若需外部控制尺寸,可直接在此设置,否则依赖contentVC内部的preferredContentSize
    // contentVC.preferredContentSize = CGSizeMake(320, 480);
    
    contentVC.popoverPresentationController.sourceRect = frame;
    contentVC.popoverPresentationController.sourceView = view;
    contentVC.popoverPresentationController.permittedArrowDirections = direction;
    
    [presentingVC presentViewController:contentVC animated:YES completion:nil];
}

3. 解决重复展示的压缩问题

如果复用 contentVC 实例,每次展示前必须重置 preferredContentSize,避免系统复用之前缓存的尺寸状态:

// 复用contentVC时,展示前重新设置尺寸
contentVC.preferredContentSize = CGSizeMake(320, 480);
[YourClass showDialogiPad:contentVC fromPresentingVC:presentingVC inView:view atFrame:frame withDirection:direction];

对应观察点的解释

  • 首次打开正常、后续压缩:首次展示时 view 布局刚好符合预期尺寸,但复用控制器时,系统会根据之前的布局状态调整尺寸,且未重置 preferredContentSize,导致压缩。
  • 注释 preferredContentSize 后弹窗最大尺寸:此时系统会自动计算内容所需的最大可用空间,填充弹窗。
  • 改用 UIModalPresentationFormSheet 尺寸正确:该样式的尺寸计算逻辑更严格遵循 preferredContentSize,不受 popover 的自适应布局规则影响。

内容的提问来源于stack exchange,提问作者Silverness

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 01:42:33