【问题标题】:Objective C : How to create self.view inside Safe Area programmatically目标 C:如何以编程方式在安全区域内创建 self.view
【发布时间】:2017-11-02 12:42:37
【问题描述】:

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

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

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

【问题讨论】:

标签: ios objective-c swift xcode safearealayoutguide


【解决方案1】:

在 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];

参考来自:Use Safe Area Layout programmatically - Swift

结果:

【讨论】:

  • 如果我想将安全区域布局约束应用于自定义 tabBar 控制器并以编程方式应用,我可以知道如何修改和使用您的代码吗?
  • safeAreaLayoutGuide 仅在 iOS 11 之后可用。在 iOS 11 之前,您可以使用 topLayoutGuidebottomLayoutGuide。 (或使用 Xibs\storyboards)
  • @Krunal 如果您的部署目标小于 iOS 11,则不能这样做。对于小于 11 的 iOS,您可以在情节提要中使用 safeArea,但不能在代码中使用 (safeAreaLayoutGuide)
  • @DanSkeel - 同意你的看法。现在更新了。欢迎您通过添加输入来改进此答案。
  • 嗨@Krunal!谢谢你!如果我想添加一个常量呢?
【解决方案2】:

您可以通过编程方式找到 topbottom 填充。我认为这将解决您的问题。

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

编辑:如 cmets 中所述(感谢@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有关,而不是swift。在有人对您投反对票之前对其进行编辑。
  • 语言无关紧要。这是一个非常糟糕的例子。
  • @PranjalBikashDas 这是客观的 C 而不是 swift
  • 如果您不使用 AutoLayout 或 Storyboard,这就是您要走的路。
  • 这对于使用框架而不是约束创建的视图非常有用,如果需要,您将获得安全区域的填充。例如,填充将是 0 或 34。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-25
  • 2018-05-26
  • 1970-01-01
  • 2018-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多