15

我刚刚将我的应用程序从支持 iOS 8 更改为支持 iOS 9 及更高版本。

由于我不使用故事板来创建我的视图,我想知道是否有“使用安全区域指南”选项以编程方式或类似的东西。

我试图锚定我的视图,但它们在 iPhone X 模拟器中不断重叠顶部和底部。

4

2 回答 2

32

在 Objective-C 中试试这个,看看:

UIView * myView = // initialize view using IBOutlet or programtically

myView.backgroundColor = [UIColor redColor];
myView.translatesAutoresizingMaskIntoConstraints = NO;

if (@available(iOS 11, *)) {
    UILayoutGuide * guide = self.view.safeAreaLayoutGuide;
    [myView.leadingAnchor constraintEqualToAnchor:guide.leadingAnchor].active = YES;
    [myView.trailingAnchor constraintEqualToAnchor:guide.trailingAnchor].active = YES;
    [myView.topAnchor constraintEqualToAnchor:guide.topAnchor].active = YES;
    [myView.bottomAnchor constraintEqualToAnchor:guide.bottomAnchor].active = YES;
} else {
    UILayoutGuide *margins = self.view.layoutMarginsGuide;
    [myView.leadingAnchor constraintEqualToAnchor:margins.leadingAnchor].active = YES;
    [myView.trailingAnchor constraintEqualToAnchor:margins.trailingAnchor].active = YES;
    [myView.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor].active = YES;
    [myView.bottomAnchor constraintEqualToAnchor:self.bottomLayoutGuide.topAnchor].active = YES;

}

// Refresh myView and/or main view
[self.view layoutIfNeeded];
//[self.myView layoutIfNeeded];

参考:以编程方式使用安全区域布局 - Swift

结果:

在此处输入图像描述

于 2017-11-02T13:01:50.910 回答
15

您可以通过编程找到顶部底部填充。我认为这将解决您的问题。

if (@available(iOS 11.0, *)) {
        UIWindow *window = UIApplication.sharedApplication.keyWindow;
        CGFloat topPadding = window.safeAreaInsets.top;
        CGFloat bottomPadding = window.safeAreaInsets.bottom;
}

编辑:正如评论中提到的(感谢@albert-renshaw),在第一次运行时无法从viewDidLoad中绘制对象,因为 UIWindow 在至少一个运行循环之后才能访问。要绕过这一点,您可以通过以下几种方式进行操作:

1.只需将您的 viewDidLoad 代码移动到新方法 postViewDidLoad 中并使用:

[self performSelector:@selector(postViewDidLoad) withObject:nil afterDelay:0.0f];

...在原始 viewDidLoad 方法中,将可以访问 UIWindow。

或者

2.将您的对象的创建包含在

dispatch_async(dispatch_get_main_queue(), ^{
// your code here...
});
于 2017-11-02T12:49:05.550 回答