UIView 位于半透明导航栏后面,具有实用创建的视图约束

Posted

技术标签:

【中文标题】UIView 位于半透明导航栏后面,具有实用创建的视图约束【英文标题】:UIView is behind translucent navigation bar with pragmatically created view constraints 【发布时间】:2017-01-10 00:45:48 【问题描述】:

我有一个函数可以将通用 UIView 插入到视图顶部的视图控制器中,我希望插入的视图位于导航栏的底部,或者如果没有,在状态栏的底部。

我认为视图控制器顶部布局指南在嵌入导航控制器时会自动更新,但事实并非如此。

这是我目前所拥有的:

init(in viewController: UIViewController) 
    super.init(frame: CGRect(x: 0, y: 0,
                             width: viewController.view.frame.size.width, height: 50))
    initializeSubviews()

    viewController.view.addSubview(self)

    self.topAnchor.constraint(equalTo: viewController.topLayoutGuide.bottomAnchor, constant: 0).isActive = true
    self.leadingAnchor.constraint(equalTo: viewController.view.leadingAnchor, constant: 0).isActive = true
    viewController.view.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0).isActive = true
    self.addConstraint(NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 50))

    self.setNeedsLayout()

我可以在界面构建器中使用占位符视图来实现这一点,因此我尝试使用与此处使用的相同的约束锚:

问题是视图总是在 Y 位置 0 并且在导航栏的后面。我无法更改导航栏的半透明设置。

加载视图时,我在控制台中收到以下错误:

<MyApp.MyReusableView: 0x101f3b590; frame = (0 0; 0 0); layer = <CALayer: 0x17003e720>>
2017-01-09 17:07:21.347965 MyApp[2483:984880] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x1742862c0 h=--& v=--& MyApp.MyReusableView:0x101f3b590.width == 0   (active)>",
    "<NSLayoutConstraint:0x1702882f0 H:|-(0)-[MyApp.MyReusableView:0x101f3b590]   (active, names: '|':UIView:0x101f29f00 )>",
    "<NSLayoutConstraint:0x170288340 H:[MyApp.MyReusableView:0x101f3b590]-(0)-|   (active, names: '|':UIView:0x101f29f00 )>",
    "<NSLayoutConstraint:0x174286450 'UIView-Encapsulated-Layout-Width' UIView:0x101f29f00.width == 375   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x170288340 H:[MyApp.MyReusableView:0x101f3b590]-(0)-|   (active, names: '|':UIView:0x101f29f00 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2017-01-09 17:07:21.350923 MyApp[2483:984880] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x174280a50 h=-&- v=-&- UIView:0x102b38f70.width == MyApp.MyReusableView:0x101f3b590.width   (active)>",
    "<NSAutoresizingMaskLayoutConstraint:0x1742862c0 h=--& v=--& MyApp.MyReusableView:0x101f3b590.width == 0   (active)>",
    "<NSLayoutConstraint:0x174286090 H:|-(16)-[UILabel:0x102b23d20'\Uf170']   (active, names: '|':UIControl:0x102b22d10 )>",
    "<NSLayoutConstraint:0x174285ff0 H:[UILabel:0x102b23d20'\Uf170']-(8)-[UILabel:0x102b2efa0'Test Notification']   (active)>",
    "<NSLayoutConstraint:0x174285f50 H:[UILabel:0x102b2efa0'Test Notification']-(0)-|   (active, names: '|':UIControl:0x102b22d10 )>",
    "<NSLayoutConstraint:0x174285cd0 H:|-(0)-[UIControl:0x102b22d10]   (active, names: '|':UIView:0x102b38f70 )>",
    "<NSLayoutConstraint:0x174285870 H:[UIButton:0x102b0d040'\Uf05e']-(0)-|   (active, names: '|':UIView:0x102b38f70 )>",
    "<NSLayoutConstraint:0x1742857d0 H:[UIControl:0x102b22d10]-(0)-[UIButton:0x102b0d040'\Uf05e']   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x174285ff0 H:[UILabel:0x102b23d20'']-(8)-[UILabel:0x102b2efa0'Test Notification']   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2017-01-09 17:07:21.352456 MyApp[2483:984880] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x174286360 h=--& v=--& MyApp.MyReusableView:0x101f3b590.height == 0   (active)>",
    "<NSLayoutConstraint:0x170288390 MyApp.MyReusableView:0x101f3b590.height == 50   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x170288390 MyApp.MyReusableView:0x101f3b590.height == 50   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2017-01-09 17:07:21.354622 MyApp[2483:984880] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<_UILayoutSupportConstraint:0x1702877b0 _UILayoutGuide:0x101f3ae30.height == 64   (active)>",
    "<_UILayoutSupportConstraint:0x17009d420 V:|-(0)-[_UILayoutGuide:0x101f3ae30]   (active, names: '|':UIView:0x101f29f00 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x174286270 h=--& v=--& MyApp.MyReusableView:0x101f3b590.midY == 0   (active)>",
    "<NSAutoresizingMaskLayoutConstraint:0x174286360 h=--& v=--& MyApp.MyReusableView:0x101f3b590.height == 0   (active)>",
    "<NSLayoutConstraint:0x170287f30 V:[_UILayoutGuide:0x101f3ae30]-(0)-[MyApp.MyReusableView:0x101f3b590]   (active)>",
    "<NSAutoresizingMaskLayoutConstraint:0x174286540 h=-&- v=-&- 'UIView-Encapsulated-Layout-Top' UIView:0x101f29f00.minY == 0   (active, names: '|':UIViewControllerWrapperView:0x102b09100 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x170287f30 V:[_UILayoutGuide:0x101f3ae30]-(0)-[MyApp.MyReusableView:0x101f3b590]   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2017-01-09 17:07:21.356571 MyApp[2483:984880] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x174280a50 h=-&- v=-&- UIView:0x102b38f70.width == MyApp.MyReusableView:0x101f3b590.width   (active)>",
    "<NSAutoresizingMaskLayoutConstraint:0x1742862c0 h=--& v=--& MyApp.MyReusableView:0x101f3b590.width == 0   (active)>",
    "<NSLayoutConstraint:0x174285f00 UIButton:0x102b0d040'\Uf05e'.width == 50   (active)>",
    "<NSLayoutConstraint:0x174285cd0 H:|-(0)-[UIControl:0x102b22d10]   (active, names: '|':UIView:0x102b38f70 )>",
    "<NSLayoutConstraint:0x174285870 H:[UIButton:0x102b0d040'\Uf05e']-(0)-|   (active, names: '|':UIView:0x102b38f70 )>",
    "<NSLayoutConstraint:0x1742857d0 H:[UIControl:0x102b22d10]-(0)-[UIButton:0x102b0d040'\Uf05e']   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x174285f00 UIButton:0x102b0d040''.width == 50   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

这个视图约束我做错了什么?

【问题讨论】:

您是否看到控制台中的自动布局有任何错误?您正在通过设置框架来设置视图的高度,您是否尝试过像在 IB 中那样将其添加为约束? 我确实在控制台中遇到了自动布局错误,但它们很难理解。我已更新问题以包括我的高度限制和控制台错误。 确保您已将视图和 viewController.view 的 translatesAutoresizingMaskIntoConstraints 设置为 false 成功了!您能否将该评论格式化为答案,以便我将其标记为已接受? 【参考方案1】:

确保您已将视图和 viewController.view 的 translatesAutoresizingMaskIntoConstraints 设置为 false

【讨论】:

所以这适用于垂直对齐,但我仍然无法让子视图跨越其父视图的整个宽度。我在控制台中没有收到任何布局错误,而且我仍在使用与问题中相同的代码。

以上是关于UIView 位于半透明导航栏后面,具有实用创建的视图约束的主要内容,如果未能解决你的问题,请参考以下文章

Android 半透明状态栏但非半透明导航栏(如果存在)

iOS Autolayout - 在半透明导航栏下方正确定位视图

iOS 7状态栏半透明,具有向后兼容性

黑色半透明导航栏/UITableView/内容插入/滚动位置问题

在状态和导航栏后面显示内容

Android Draw 在状态栏后面但不在导航栏后面