Objective C:如何以编程方式在安全区域内创建 self.view
Objective C : How to create self.view inside Safe Area programmatically
我刚刚将我的应用程序从支持 iOS 8 及更高版本更改为支持 iOS 9 及更高版本。
因为我不使用故事板来创建我的视图,所以我想知道是否有 "Use Safe Area Guides" 选项以编程方式或类似的方式。
我试图锚定我的视图,但它们在 iPhone X 模拟器中一直与顶部和底部重叠。
您可以通过编程找到 top 和 bottom 填充。我想这会解决你的问题。
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...
});
在 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];
参考自:
结果:
我刚刚将我的应用程序从支持 iOS 8 及更高版本更改为支持 iOS 9 及更高版本。
因为我不使用故事板来创建我的视图,所以我想知道是否有 "Use Safe Area Guides" 选项以编程方式或类似的方式。
我试图锚定我的视图,但它们在 iPhone X 模拟器中一直与顶部和底部重叠。
您可以通过编程找到 top 和 bottom 填充。我想这会解决你的问题。
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...
});
在 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];
参考自:
结果: