iOS 9 by Tutorials 笔记(八)

Chapter 8: Intermediate UIStackView

上一章已经学习了 Stack View 的用法,现在我们可以将之前手工添加的约束统一改为 Stack View 的形式了。

Your first vertical stack view

现在我们来创建一个内部是垂直布局的 stack view,很简单将下面两个 Lable 选中,加入 stack view:

记得对 stack view 与周围的元素添加相应的约束

Alignment

在 Xcode 上设置 aligment 其实对应着枚举对象 UIStackViewAlignmentalignment 属性。分别在垂直和水平方向上对应着不同值:

Horizontal axis:

Vertical axis:

FirstBaseline and LastBaseline:

下面我们给 WEATHER 这部分加入 stack view,点击 Hiden,底下的内容会隐藏,同时注意 RATING 星星的变化:

Stack view 按如下方式组织,且与周边元素添加合适的约束。

Top-level stack view

现在我们有了五个 Stack View,并设置他们之间的约束,那么为什么不更进一步,把这五个 Stack View 也嵌入到 Stack View 中,这样我们就不用设置他之间的约束了。

在最外层加一个 Stack View,设置内部元素垂直布局,且间隔为 20。

注意,把元素添加到 StackView,会清除掉该元素上的所有约束

Arranged subviews

观察上面的动图,WEATHER 位于 WHAT TO SEE 的下面,而他们现在都在 Stack View 里了,只需要在 Xcode 里简单的拖动一下二者的顺序就好。

UIStackView 其实专门有一个属性 arrangedSubviews 数组来存储这些 View,而 arrangedSubviews 数组的索引也就是 StackView 中 view 的排列顺序。

UIStackView 还有一个继承自 UIView 的 subviews 属性,该属性的含义与 UIView 的相同,是指自身层级结构中包含的子 View,而他的索引主要表示在 Z 轴维度上子 View 的排列顺序。

在 StoryBoard 左边栏(outline view),展开一个 StackView 里面的 views 其实都是 arrangedSubviews,而你想要给 StackView 添加一个 subviews,则只能通过代码方式

除了在Storyboard 中拖动 stackView 里的 views,你还可以通过代码的方式来实现:

  • addArrangedSubview(_:)
  • insertArrangedSubview(_:atIndex:)
  • removeArrangedSubview(_:)

执行这些操作,仅对布局有影响,并不会改变真正的 view 层级中的 subviews

Size class based configuration

Stack View 还可以和 Size Class 配合起来满足各种需要,比如我们设置 vertical size class 为 compact 时,缩减 Stack View 内部元素之间的间距(由 20 减到 10)

为 Spacing 添加一个 size class(Any Width > Compact Height

为新 size class 下的 Spacing 设置 10

运行一下,横屏过来是不是更紧凑了呢

Animation

还记得我们之前点击 Hidden 按钮的界面动画吗,整个 WEATHER 的详细内容被隐藏掉了,实现起来也很简单:用一个 BOOL 属性 shouldHideWeatherInfo 来存储当前是否应当被隐藏,然后根据这个属性来执行一些动画

if animated {  
      UIView.animateWithDuration(0.3,
        delay: 0.0,
        usingSpringWithDamping: 0.6,
        initialSpringVelocity: 10,
        options: [],
        animations: {
          self.weatherInfoLabel.hidden = shouldHideWeatherInfo
        }, completion: { finished in
          UIView.animateWithDuration(0.3) {
            self.ratingStackView.axis =
              shouldHideWeatherInfo ? .Vertical : .Horizontal
          }
        }
      )
    } else {
      weatherInfoLabel.hidden = shouldHideWeatherInfo
      ratingStackView.axis = shouldHideWeatherInfo ? .Vertical : .Horizontal
    }

注意,最后在 Completion Block 中(完成动画的时候)将 RATING 这部分对应的 StackView axis 布局做出相应的调整,根据当前的隐藏状态(shouldHideWeatherInfo)来决定 Vertical or Horizontal(隐藏垂直布局,不隐藏水平布局)


-EOF-

如果感觉此文对你有帮助,请随意打赏支持作者 😘

chengway

认清生活真相之后依然热爱它!

Subscribe to Talk is cheap, Show me the world!

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!