旋转时隐藏视图和不可满足的布局的UIStackView

时间:2017-12-04 02:02:42

标签: xcode interface-builder uistackview

我有一个视图控制器,我想隐藏某些子视图,标签等,具体取决于特征集合。例如,水平压缩时我想要隐藏的一侧有标签,而垂直压缩时我想隐藏顶部和底部的标签。

因为我想隐藏界面的整个部分,听起来像UIStackView会让这更容易。同样,我试图在Interface Builder / Xcode(9.1 9B55)中尽可能多地尝试,而不是在代码中,尝试保持简单。

设计的主要元素是棋盘,其中:

  • 总长宽比为1:1
  • 在视图中尽可能大

然后我想根据当前的特征集合移动和隐藏标签和其他项目。

我已经开始构建水平堆栈视图,对齐和分布设置为"填充。"其中有两个项目,boardView(紫色)和labelView(黄色)。

labelView中有几个标签,视图中的约束设置为这些标签的布局。

boardView具有宽高比1:1(@ 1000)的约束:

enter image description here

我为Stack View设置了以下约束,将其固定到superview(底部除外):

  • Safe Area.trailing = Stack View.trailing(@ 1000)
  • Safe Area.leading = Stack View.leading(@ 1000)
  • Safe Area.top = Stack View.top(@ 1000)
  • Safe Area.bottom> = Stack View.bottom(@ 1000)

我设置了这些约束以确保boardView永远不会溢出superview:

  • boardView.width< = Safe Area.width(@ 1000)
  • boardView.height< = Safe Area.height(@ 1000)

然后我将这些约束设置为较低的优先级,以便在可能的情况下,宽度或高度将扩展以填充超级视图(但不会溢出,因为它们的优先级低于上述值):

  • boardView.width = Safe Area.width(@ 250)
  • boardView.height = Safe Area.height(@ 250)

这一切似乎都很有效。 Xcode和应用程序中的错误行为与我期望的一样,在纵向和横向上(这些来自iPhone 8模拟器的屏幕截图):

enter image description here enter image description here

当我尝试隐藏正确的视图时出现问题。当我们垂直处于常规模式时,我试图通过隐藏nameView来做到这一点。我选择nameView,单击Installed复选框旁边的+,选择hR:

enter image description here

然后取消选中hR的已安装框:

enter image description here

这在Xcode中看起来很棒。没有错误,IB似乎正在显示所有视图,正如我在横向和纵向(隐藏名称标签的位置)中所期望的那样:

enter image description here enter image description here

到目前为止,这么好。事实上,当我运行它时,它看起来就像我们期望的那样,最初。如果我们在景观中启动模拟器,它看起来不错:

enter image description here

如果我们以纵向方式启动模拟器,它看起来不错:

enter image description here

那么问题是什么?好吧,只要我们从纵向旋转到横向,布局就完全错了:

enter image description here

同时,我们在控制台中遇到LayoutConstraints错误:

2017-12-03 19:25:55.710381-0600 TestLayoutSIngleView[31439:3231004] [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 fixes it. 
(
    "<NSLayoutConstraint:0x60400009b8a0 UIView:0x7fe920603e90.width == UIView:0x7fe920603e90.height   (active)>",
    "<NSLayoutConstraint:0x60000009ced0 UIStackView:0x7fe92050bd70.leading == UILayoutGuide:0x6000001b5d20'UIViewSafeAreaLayoutGuide'.leading   (active)>",
    "<NSLayoutConstraint:0x60000009d100 UIStackView:0x7fe92050bd70.top == UILayoutGuide:0x6000001b5d20'UIViewSafeAreaLayoutGuide'.top   (active)>",
    "<NSLayoutConstraint:0x60000009d150 UILayoutGuide:0x6000001b5d20'UIViewSafeAreaLayoutGuide'.trailing == UIStackView:0x7fe92050bd70.trailing   (active)>",
    "<NSLayoutConstraint:0x60000009d1a0 UILayoutGuide:0x6000001b5d20'UIViewSafeAreaLayoutGuide'.bottom >= UIStackView:0x7fe92050bd70.bottom   (active)>",
    "<NSLayoutConstraint:0x60000009e5a0 'UISV-canvas-connection' UIStackView:0x7fe92050bd70.leading == UIView:0x7fe920603e90.leading   (active)>",
    "<NSLayoutConstraint:0x60000009ce30 'UISV-canvas-connection' UIStackView:0x7fe92050bd70.top == UIView:0x7fe920603e90.top   (active)>",
    "<NSLayoutConstraint:0x60000009e5f0 'UISV-canvas-connection' V:[UIView:0x7fe920603e90]-(0)-|   (active, names: '|':UIStackView:0x7fe92050bd70 )>",
    "<NSLayoutConstraint:0x60000009cde0 'UISV-canvas-connection' H:[UIView:0x7fe920603e90]-(0)-|   (active, names: '|':UIStackView:0x7fe92050bd70 )>",
    "<NSLayoutConstraint:0x60000009e7d0 'UIView-Encapsulated-Layout-Height' UIView:0x7fe92050b8f0.height == 375   (active)>",
    "<NSLayoutConstraint:0x60000009e780 'UIView-Encapsulated-Layout-Width' UIView:0x7fe92050b8f0.width == 667   (active)>",
    "<NSLayoutConstraint:0x60000009d060 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x6000001b5d20'UIViewSafeAreaLayoutGuide']-(0)-|   (active, names: '|':UIView:0x7fe92050b8f0 )>",
    "<NSLayoutConstraint:0x60000009d010 'UIViewSafeAreaLayoutGuide-left' H:|-(0)-[UILayoutGuide:0x6000001b5d20'UIViewSafeAreaLayoutGuide'](LTR)   (active, names: '|':UIView:0x7fe92050b8f0 )>",
    "<NSLayoutConstraint:0x60000009d0b0 'UIViewSafeAreaLayoutGuide-right' H:[UILayoutGuide:0x6000001b5d20'UIViewSafeAreaLayoutGuide']-(0)-|(LTR)   (active, names: '|':UIView:0x7fe92050b8f0 )>",
    "<NSLayoutConstraint:0x60000009cfc0 'UIViewSafeAreaLayoutGuide-top' V:|-(0)-[UILayoutGuide:0x6000001b5d20'UIViewSafeAreaLayoutGuide']   (active, names: '|':UIView:0x7fe92050b8f0 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x60400009b8a0 UIView:0x7fe920603e90.width == UIView:0x7fe920603e90.height   (active)>

我喜欢使用UIStackView进行自动布局和隐藏视图的想法。但是,如果我在Xcode中看到的东西在编译和运行时不起作用,那么这似乎会很棘手。

我做错了什么(或者我遇到了Xcode错误)?

我创建了一个GitHub项目,演示了以上内容: https://github.com/johnstewart/TestLayoutSIngleView

编辑....当我完成上述所有内容时,我会想到,如果我们要以横向模式隐藏这个视图,那么布局就不会令人满意......但是我没有将这个视图隐藏在风景中,只有肖像。出于某种原因,iOS正在轮换之前对布局进行更改。

如果我将此优先级设置为1000到750:

  • Safe Area.trailing = Stack View.trailing(@ 1000)

...我在控制台上没有出现任何自动布局错误。然而,一旦旋转的景观视图根本没有在正确的地方放置东西。

好像堆栈视图在开始从纵向旋转到横向时立即收缩,并且在旋转完成后将堆栈视图保持在收缩状态,即使现在有足够的空间:

enter image description here

我真诚地希望我在这里遗漏了一些明显的东西......否则,我不知道如何使用UIStackView基于特征集合的未安装视图是完全可行的;这似乎是一个简单的例子(事实上,我已经有更多的东西需要添加!)

编辑:

我看到这种技术的WWDC视频来自WWDC2017,Interface Builder中的自动布局技术(https://developer.apple.com/videos/play/wwdc2017/412/)。这个演示从29:00开始。

然而,我错了,它是&#34;已安装&#34;正在使用的财产。正如接受的答案所示,&#34; Hidden&#34;是这样做的。

1 个答案:

答案 0 :(得分:3)

我认为如果没有安装&#39;属性: 只是设置隐藏的&#39;对于肖像模式:enter image description here

enter image description here