如何设置 UIViewController 以避免在槽口和底部滑块区域绘制?

How do I set up my UIViewController to avoid drawing in the notch and bottom slidebar areas?

提问人:Todd Lehman 提问时间:8/29/2023 最后编辑:HangarRashTodd Lehman 更新时间:8/30/2023 访问量:77

问:

我正在复活我在 2015 年编写的应用程序,它仍然可以全屏运行,但我正在努力弄清楚如何避免在 iPhone X 及其后代的缺口区域和底部滑动条区域绘图。

这是它在 iPhone 14 Pro Max 上的样子(在 iOS 模拟器中)。请注意,它一直向上绘制到药丸区域:

My app leaks content into the notch area and bottom area

我的启动屏幕 View Controller Scene 在 Xcode 编辑器中具有以下属性。

  • Interface Builder 文档
    • 构建对象:部署目标 (12.0)
    • 使用特征变化:开
    • 使用安全区域布局指南:开
    • 用作启动屏幕:ON
  • 视图
    • 安排:位置视图
    • 布局:自动调整蒙版大小
    • 布局边距:默认
      • 保留 Superview 边距:关闭
      • 跟随可读宽度:OFF
      • 安全区域相对边距:关闭
    • 布局参考线
      • 安全区域:开
      • 键盘:关闭

我的主视图控制器场景具有以下属性:

  • Interface Builder 文档
    • 构建对象:部署目标 (12.0)
    • 使用特征变体:关闭
    • 使用安全区域布局指南:开
    • 用作启动屏幕:关闭
  • 视图控制器
    • 布局
      • 调整滚动视图插入:开
      • 按下时隐藏底栏:关闭
      • 从 NIB 调整视图大小:ON
      • 使用全屏(已弃用):关闭
    • 扩展边缘
      • 在顶栏下:关闭
      • 在底栏下:关闭
      • 在不透明条下:关闭

相反,我想要的是将我的 UIViewController 的框架自动限制为屏幕的“安全”区域,即缺口/药丸区域和底部滑块区域之间的区域。

在iPhone 8和所有iPad上一切看起来都不错。只是最近的 iPhone 遇到了麻烦。

iOS 布局 UIVieviceController iPhone-X

评论

0赞 DonMag 8/29/2023
听起来你的UI元素被限制在视图上......他们需要被限制在安全区域
0赞 Todd Lehman 8/30/2023
@DonMag — 没错!不幸的是,我还没有找到任何详细的教程或描述,说明如何去做。是否可以通过 Xcode 故事板编辑器或启动屏幕进行操作?还是需要在代码中以编程方式完成?
0赞 DonMag 8/30/2023
当您谈论“Interface Builder Document”时......您在使用 Storyboard 吗?还是单个 XIB 文件?
0赞 Todd Lehman 8/30/2023
@DonMag — 我基本上只有一个空的故事板来建立创业公司。只有一个视图控制器,我以编程方式从 填充它。除了主视图控制器之外,没有 segues,也没有其他视图控制器。MainViewController.m
0赞 HangarRash 8/30/2023
使用相关代码更新您的问题,该代码显示了如何在视图控制器中设置视图的约束。

答:

1赞 DonMag 8/30/2023 #1

这是非常基本的自动布局。阅读文档并浏览一些教程会让您受益匪浅。

但是,一个非常快速的例子,使用堆栈视图来获取类似于您发布的图像的布局:

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0];
    
    // we're going to add 6 views in a 2x3 layout
    NSArray <UIColor *>*colors = @[
        [UIColor redColor], [UIColor greenColor], [UIColor blueColor],
        [UIColor cyanColor], [UIColor yellowColor], [UIColor orangeColor],
    ];
    
    UIStackView *sv = [UIStackView new];
    sv.axis = UILayoutConstraintAxisVertical;
    sv.distribution = UIStackViewDistributionFillEqually;
    sv.spacing = 8.0;
    
    int cIdx = 0;
    for (int i = 0; i < 3; i++) {
        UIStackView *sv2 = [UIStackView new];
        sv2.axis = UILayoutConstraintAxisHorizontal;
        sv2.distribution = UIStackViewDistributionFillEqually;
        sv2.spacing = 8.0;
        for (int j = 0; j < 2; j++) {
            UIView *v = [UIView new];
            v.backgroundColor = colors[cIdx];
            v.layer.cornerRadius = 12.0;
            cIdx++;
            [sv2 addArrangedSubview:v];
        }
        [sv addArrangedSubview:sv2];
    }

    sv.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:sv];
    
    // respect safe area
    UILayoutGuide *g = [self.view safeAreaLayoutGuide];

    [NSLayoutConstraint activateConstraints:@[
        [sv.topAnchor constraintEqualToAnchor:g.topAnchor constant:0.0],
        [sv.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:0.0],
        [sv.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:0.0],
        [sv.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:0.0],
    ]];
    
}

@end

iPhone SE 上的结果(无缺口或虚拟主页按钮):

enter image description here

旋转:

enter image description here

在 iPhone 14 Pro 上:

enter image description here

enter image description here