目标C:如何以编程方式在Safe Area中创建self.view

Rav*_*ran 13 xcode objective-c ios swift safearealayoutguide

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

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

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

Kru*_*nal 27

在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];
Run Code Online (Sandbox Code Playgroud)

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

结果:

在此输入图像描述


use*_*419 14

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

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

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

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

[self performSelector:@selector(postViewDidLoad) withObject:nil afterDelay:0.0f];
Run Code Online (Sandbox Code Playgroud)

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

要么

2.包含对象的创建

dispatch_async(dispatch_get_main_queue(), ^{
// your code here...
});
Run Code Online (Sandbox Code Playgroud)

  • @PranjalBikashDas这是客观C不快捷 (5认同)
  • 这个问题与目标C没有迅速关系.在某人投票给你之前编辑它. (2认同)
  • 如果您不使用AutoLayout或Storyboard,那么这就是您的选择. (2认同)
  • 注意:无法在主 ViewController 的 viewDidLoad 中调用此函数,因为只有在至少一个运行循环之后才能访问 UIWindow。要绕过,您可以简单地将 viewDidLoad 代码移动到新方法 `postViewDidLoad` 中,并在原始 viewDidLoad 方法中使用 `[self PerformSelector:@selector(postViewDidLoad) afterDelay:0.0f];` ,然后 UIWindow 将可以访问,这将起作用。 (2认同)