如何让 iOS 弹出窗口视图在气泡内正确定位

问题描述 投票:0回答:1

我编写了代码,如果选择了 UICollectionView 单元格但由于某种原因不可用,则显示该单元格中的弹出窗口。它工作正常,只是内容从未正确定位在弹出气泡内。请注意,从显示的两个示例中,内容始终向插入符号移动大约插入符号厚度的一半。

很明显,尺寸计算正确,但似乎弹出控制器只是错误地计算了 popupView 的位置。由于移动的方向超出了我的控制范围,因此我不能将所有内容都移动几个像素作为解决方法。

故事板只有一个 popupView,其约束使其在场景视图中水平和垂直居中:

这是我的代码...请注意,我打开了视图周围的边框只是为了强调这种转变。

// Inside collectionView:didSelectItemAtIndexPath:

    UIStoryboard* mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    MenuUnavailableViewController* muc = [mainStoryboard instantiateViewControllerWithIdentifier:@"MenuOptionUnavailable"];
    muc.modalPresentationStyle = UIModalPresentationPopover;

    [self presentViewController:muc animated:NO completion:nil];

    MenuCollectionViewCell* menuCell = (MenuCollectionViewCell*) [menuCollection cellForItemAtIndexPath:indexPath];
    muc.popoverPresentationController.sourceView = menuCollection;
    muc.popoverPresentationController.sourceRect = menuCell.frame;
    muc.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny;
@implementation MenuUnavailableViewController

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
   
    [self.view layoutSubviews];
    self.preferredContentSize = self.popupView.bounds.size;
    self.popupView.layer.borderColor = [UIColor blackColor].CGColor;
    self.popupView.layer.borderWidth = 2;
    self.popupView.layer.cornerRadius = 12;
}

我已经使用这个公式成功地做了弹出窗口相当长一段时间了,然后有一天,一些 iOS 或 Xcode 更新悄悄地打破了定位(不确定,但我认为它是在 iOS 13 或 14 左右)。有人知道我做错了什么吗?我一直在寻找在最新 iOS 版本下实现弹出窗口的完整示例,但在任何地方都找不到。

ios objective-c uipopovercontroller
1个回答
0
投票

不确定什么可能发生了变化,或者什么时候......而且,也许你的布局“很幸运”,所以你没有注意到它......但是......

我们要根据

控制器
视图的大小设置 .preferredContentSize - 而不是您的
popupView
子视图。

此外,我们要确保内容限制在安全区域

所以,如果我像这样设置

MenuUnavailableViewController

带有“不可用”和“原因:”标签的内容拥抱和抗压缩优先级全部设置为

Required
...

  • Unavailable Lbl
    标签将决定宽度
  • “原因 Lbl` 标签将决定高度

在调用控制器中,设置标签的字符串属性。

然后,

MenuUnavailableViewController
类看起来像这样:

@implementation MenuUnavailableViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.unavailableLbl.text = _unavailableString;
    self.reasonLbl.text = _reasonString;
    
    self.preferredContentSize = [self.view systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
}

@end

无需在

viewWillAppear
中执行任何操作。

这是它的样子(循环通过 3 组字符串):

如果我们清除颜色和边框:

并且,只是为了展示它适用于不同的“箭头”方向:

© www.soinside.com 2019 - 2024. All rights reserved.