Auto Layout Cookbook:Stack Views

Stack Views栈的看法

The following recipes show how you can use stack views to create layouts of increasing complexity. Stack views are a powerful tool for quickly and easily designing your user interfaces. Their attributes allow a high degree of control over how they lay out their arranged views. You can augment these settings with additional, custom constraints; however, this increases the layout’s complexity.

下面的菜谱展示了如何使用堆栈视图来创建越来越复杂的布局。堆栈视图是快速方便地设计用户界面的有力工具。他们的属性允许高度控制他们如何安排他们的安排的意见。您可以增加这些设置与额外的自定义约束,但是,这增加了布局的复杂性。

To view the source code for these recipes, see the Auto Layout Cookbook project.

要查看这些配方的源代码,请参见自动布局食谱项目。

Simple Stack View简单的堆栈视图

This recipe uses a single, vertical stack view to lay out a label, image view, and button.

这个配方使用单一的、垂直的堆栈视图来创建标签、图像视图和按钮。

image: ../Art/Simple_Stack_View_Screenshot_2x.png

Views and Constraints视图的观点和约束

In Interface Builder, start by dragging out a vertical stack view, and add the flowers label, image view, and edit button. Then set up the constraints as shown.

在界面生成器中,从拖动垂直堆栈视图开始,并添加“鲜花标签”、“图像视图”和“编辑”按钮。然后设置约束如图所示。

image: ../Art/simple_stack_2x.png

  1. Stack View.Leading = Superview.LeadingMargin

  2. Stack View.Trailing = Superview.TrailingMargin

  3. Stack View.Top = Top Layout Guide.Bottom + Standard

  4. Bottom Layout Guide.Top = Stack View.Bottom + Standard

Attributes属性

In the Attributes inspector, set the following stack view attributes:在属性视图中检查,设置以下属性:协议栈

 

Stack

Axis

Alignment

Distribution

Spacing

Stack View

Vertical

Fill

Fill

8

Next, set the following attributes on the Image View:接下来,在图像视图上设置以下属性:

 

View

Attribute

Value

Image View

Image

(an image of flowers)

Image View

Mode

Aspect Fit

Finally, in the Size inspector, set the Image View’s content-hugging and compression-resistance (CHCR) priorities.最后,在大小的督察,将图像视图内容的拥抱和抗压(CHCR)优先。

 

Name

Horizontal hugging

Vertical hugging

Horizontal resistance

Vertical resistance

Image View

250

249

750

749

Discussion讨论

You must pin the stack view to the superview, but otherwise, the stack view manages the entire layout without any other explicit constraints.

你必须销堆栈视图的父视图,否则堆栈视图管理整个布局没有任何明确的约束。

In this recipe, the stack view fills its superview, with a small, standard margin. The arranged views are resized to fill the stack view’s bounds. Horizontally, each view is stretched to match the stack view’s width. Vertically, the views are stretched based on their CHCR priorities. The image view should always shrink and grow to fill the available space. Therefore, its vertical content hugging and compression resistance priorities must be lower than the label and button’s default priorities.

在这个食谱中,堆栈视图填充它的父视图,用一个小的标准保证金。设置视图调整大小以填充堆栈视图边界。水平地,每个视图被拉伸以匹配堆栈视图的宽度。纵向上,根据他们的意见被CHCR优先。图像视图应该始终缩小并增长以填充可用空间。因此,其垂直内容的拥抱和压缩优先权必须低于标签和按钮的默认优先级。

Finally, set the image view’s mode to Aspect Fit. This setting forces the image view to resize the image so that it fits within the image view’s bounds, while maintaining the image’s aspect ratio. This lets the stack view arbitrarily resize the image view without distorting the image.

最后,将图像视图模式设置为方面匹配。此设置强制图像视图调整图像的大小,使其适合于图像视图的范围内,同时保持图像的纵横比。这使堆栈视图可以任意调整图像视图而不扭曲图像。

For more information on pinning a view to fill its superview, see Attributes and Adaptive Single View

在固定期填补它的父视图的更多信息,参见属性和自适应单视图。

Nested Stack Views嵌套堆栈视图

This recipe shows a complex layout built from multiple layers of nested stack views. However, in this example, the stack views cannot create the wanted behaviors alone. Instead, additional constraints are needed to further refine the layout.

此配方显示了由多层堆栈视图构建的复杂布局。然而,在此示例中,堆栈视图不能单独创建所需的行为。相反,需要额外的约束,以进一步完善布局。

image: ../Art/Nested_Stack_Views_Screenshot_2x.png

After the view hierarchy is built, add the constraints shown in the next section, Views and Constraints.

在生成视图层次结构之后,添加下一节、视图和约束中显示的约束。

Views and Constraints视图的观点和约束

When working with nested stack views, it is easiest to work from the inside out. Begin by laying out the name rows in Interface Builder. Position the label and text field in their correct relative positions, select them both, and then click the Editor > Embed In > Stack View menu item. This creates a horizontal stack view for the row. 

当使用嵌套堆栈视图时,从内部工作是最容易的。首先在接口生成器中设置名称行。将标签和文本字段放在正确的相对位置,选择它们,然后单击编辑器>嵌入在“堆栈视图”菜单项中。这将创建行的水平堆栈视图。

Next, position these rows horizontally, select them, and click the Editor > Embed In > Stack View menu item again. This creates a horizontal stack of rows. Continue to build the interface as shown.

接下来,水平地排列这些行,选择它们,然后单击编辑器>在“堆栈视图”菜单项中再次嵌入。这将创建行的水平堆栈。继续建立界面如图所示。

image: ../Art/nested_stack_views_2x.png

  1. Root Stack View.Leading = Superview.LeadingMargin

  2. Root Stack View.Trailing = Superview.TrailingMargin

  3. Root Stack View.Top = Top Layout Guide.Bottom + 20.0

  4. Bottom Layout Guide.Top = Root Stack View.Bottom + 20.0

  5. Image View.Height = Image View.Width

  6. First Name Text Field.Width = Middle Name Text Field.Width

  7. First Name Text Field.Width = Last Name Text Field.Width

Attributes属性

Each stack has its own set of attributes. These define how the stack lays out its contents. In the Attribute inspector, set the following attributes:每个堆栈都有自己的属性集。这些定义了堆栈的内容。在属性检查程序中,设置以下属性:

 

Stack

Axis

Alignment

Distribution

Spacing

First Name

Horizontal

First Baseline

Fill

8

Middle Name

Horizontal

First Baseline

Fill

8

Last Name

Horizontal

First Baseline

Fill

8

Name Rows

Vertical

Fill

Fill

8

Upper

Horizontal

Fill

Fill

8

Button

Horizontal

First Baseline

Fill Equally

8

Root

Vertical

Fill

Fill

8

Additionally, give the text view a light gray background color. This makes it easier to see how the text view is resized when the orientation changes.

此外,给文本视图一个浅灰色背景颜色。这使得它更容易看到的文本视图大小当方向的变化。

 

View

Attribute

Value

Text View

Background

Light Gray Color

Finally, the CHCR priorities define which views should stretch to fill the available space. In the Size inspector, set the following CHCR priorities:

最后,该定义的观点应该优先CHCR拉伸以填充可用空间。在大小的检查员,设置以下CHCR优先:

 

Name

Horizontal hugging水平的拥抱

Vertical hugging

Horizontal resistance水平抗性

Vertical resistance

Image View

250

250

48

48

Text View

250

249

250

250

First, Middle, and Last Name Labels

251

251

750

750

First, Middle, and Last Name Text Fields

48

250

749

750

Discussion讨论

In this recipe, the stack views work together to manage most of the layout. However, they cannot—by themselves—create all of the wanted behaviors. For example, the image should maintain its aspect ratio as the image view is resized. Unfortunately, the technique used in Simple Stack View won’t work here. The layout needs to fit close to both the trailing and bottom edge of the image, and using the Aspect Fit mode would add extra white space to one of those dimensions. Fortunately, in this example, the image’s aspect ratio is always square, so you can let the image completely fill the image view’s bounds, and constrain the image view to a 1:1 aspect ratio. 

在这个配方中,堆栈视图一起工作来管理大部分的布局。然而,他们不能自己创造所有的通缉行为。例如,图像应保持其纵横比为图像大小。不幸的是,在简单堆栈视图中使用的技术在这里不起作用。布局需要紧贴图像的尾部和底部边缘,并且使用外观匹配模式将在这些维度中添加额外的空白。幸运的是,在这个例子中,图像的纵横比始终是正方形的,所以可以让图像完全填充图像视图的边界,并将图像视图限制为1:1的纵横比。

NOTE

In Interface Builder, an aspect ratio constraint is simply a constraint between a view’s height and its width. Interface Builder can also show the multiplier for constraints in a number of ways. Typically, for aspect ratio constraints, it shows them as a ratio. So, a View.Width = View.Height constraint may appear as a 1:1 aspect ratio.

在接口生成器中,纵横比约束只是视图高度与其宽度之间的约束。接口生成器还可以在多个方面显示约束的乘数。通常情况下,纵横比约束,它显示他们的比例。因此,一个视图。宽度=视图。高度约束可能出现为1:1的纵横比。

Additionally, all the text fields should be the same width. Unfortunately, they are all in separate stack views, so the stacks cannot manage this. Instead, you must explicitly add equal width constraints.

此外,所有文本字段应该是相同的宽度。不幸的是,它们都是单独的堆栈视图,所以堆栈不能管理这个。相反,必须显式地添加等宽约束。

Like the simple stack view, you must also modify some of the CHCR priorities. These define how the views shrink and grow as the superclass’s bounds change.

喜欢简单的堆栈视图,您还必须修改一些的CHCR优先。这些定义的观点收缩和父类的边界变化成长。

Vertically, you want the text view to expand to fill the space between the upper stack and the button stack. Therefore, the text view’s vertical content hugging must be lower than any other vertical content hugging priority.

垂直地,您希望文本视图展开以填充上堆栈和按钮堆栈之间的空间。因此,文本视图的垂直内容拥抱必须低于任何其他垂直内容拥抱优先级。

Horizontally, the labels should appear at their intrinsic content size, while the text fields resize to fill any extra space. The default CHCR priorities work well for the labels. Interface Builder already sets the content hugging at 251, making it higher than the text fields; however, you still need to lower both the horizontal content hugging and the horizontal compression resistance of the text fields.

水平,标签应该出现在其内在内容的大小,而文本字段的大小,以填补任何额外的空间。默认优先级的工作以及标签CHCR。界面生成器已经设置了251的内容拥抱,使其高于文本字段,但是,您仍然需要降低水平内容拥抱和水平压缩阻力的文本字段。

The image view should shrink so that it is the same height as the stack containing the name rows. However, stack views only loosely hug their content. This means that the image view’s vertical compression resistance must be very low, so the image view shrinks instead of having the stack view expand. Additionally, the image view’s aspect ratio constraint complicates the layout, because it allows the vertical and horizontal constraints to interact. This means that the text fields’ horizontal content hugging must also be very low, or they will prevent the image view from shrinking. In both cases, set the priority to a value of 48 or lower.

图像视图应该收缩,使其与包含行名称的堆栈的高度相同。但是,堆栈视图只是松散地拥抱它们的内容。这意味着,图像视图的垂直压缩阻力必须非常低,所以图像视图收缩而不是堆栈视图扩展。此外,图像视图的纵横比约束复杂的布局,因为它允许的垂直和水平的约束进行交互。这意味着文本字段的“水平内容拥抱”也必须非常低,否则会阻止图像视图的收缩。在这两种情况下,将优先级设置为48或更低的值。

Dynamic Stack View栈动态视图

This recipe demonstrates dynamically adding and removing items from a stack at runtime. All changes to the stack are animated. Additionally, the stack view is placed inside a scroll view, letting you scroll through the list if it is too long to fit on the screen.

此配方演示在运行时从堆栈中动态添加和移除项目。堆栈的所有更改都是动画。此外,堆栈视图放置在一个滚动视图中,让您滚动列表,如果它太长,以适应屏幕上。

image: ../Art/Dynamic_Stack_View_Screenshot_2x.png

NOTE

This recipe is only intended to demonstrate working dynamically with stack views, and working with stack views inside scroll views. In a real-world app, this recipe’s behaviors should be implemented using the UITableView class instead. In general, you should not use dynamic stack views to simply implement a scratch-built table view clone. Instead, use them to create dynamic user interfaces that you cannot easily build using any other technology.

此配方仅用于演示使用堆栈视图动态工作,以及在滚动视图中使用堆栈视图。在一个真实世界的应用程序,这个配方的行为应该使用UITableView类来实现。一般来说,不应该使用动态堆栈视图来简单地实现从头构建的表视图克隆。相反,使用它们来创建动态用户界面,您不能使用其他任何技术轻松构建。

Views and Constraints视图的观点和约束

The initial user interface is quite simple. Place a scroll view on your scene, and size it so that it fills the scene. Then, place a stack view inside the scroll view, and place the add item button inside the stack view. As soon as everything’s in place, set the following constraints:

初始用户界面非常简单。在你的场景中放置一个滚动视图,并将其大小以使场景充满。然后,将一个堆栈视图放入滚动视图中,并将“添加项”按钮放入堆栈视图中。一旦一切到位,设置以下约束:

image: ../Art/dynamic_stack_view_2x.png

  1. Scroll View.Leading = Superview.LeadingMargin

  2. Scroll View.Trailing = Superview.TrailingMargin

  3. Scroll View.Top = Superview.TopMargin

  4. Bottom Layout Guide.Top = Scroll View.Bottom + 20.0

  5. Stack View.Leading = Scroll View.Leading

  6. Stack View.Trailing = Scroll View.Trailing

  7. Stack View.Top = Scroll View.Top

  8. Stack View.Bottom = Scroll View.Bottom

  9. Stack View.Width = Scroll View.Width

Attributes属性

In the Attributes inspector, set the following stack view attributes:在属性视图中检查,设置以下属性:协议栈

 

Stack

Axis

Alignment

Distribution

Spacing

Stack View

Vertical

Fill

Equal Spacing

0

Code代码

This recipe requires a bit of code to add items to and remove them from the stack view. Create a custom view controller for your scene with outlets for both the scroll view and stack view.

此配方需要一些代码来将项添加到堆栈视图中并将它们移除。为您的场景创建一个自定义视图控制器,用于滚动视图和堆栈视图。

  1. class DynamicStackViewController: UIViewController {
  2. @IBOutlet weak private var scrollView: UIScrollView!
  3. @IBOutlet weak private var stackView: UIStackView!
  4. // Method implementations will go here...
  5. }

Next, override the viewDidLoad method to set the scroll view’s initial position. You want the scroll view’s content to start below the status bar.

接下来,重写viewDidLoad方法来设置滚动视图的初始位置。您希望滚动视图的内容在状态栏下面开始。

  1. override func viewDidLoad() {
  2. super.viewDidLoad()
  3. // setup scrollview
  4. let insets = UIEdgeInsetsMake(20.0, 0.0, 0.0, 0.0)
  5. scrollView.contentInset = insets
  6. scrollView.scrollIndicatorInsets = insets
  7. }

Now, add an action method for the add item button.现在,为“添加项”按钮添加一个动作方法。

  1. // MARK: Action Methods
  2. @IBAction func addEntry(sender: AnyObject) {
  3. let stack = stackView
  4. let index = stack.arrangedSubviews.count - 1
  5. let addView = stack.arrangedSubviews[index]
  6. let scroll = scrollView
  7. let offset = CGPoint(x: scroll.contentOffset.x,
  8. y: scroll.contentOffset.y + addView.frame.size.height)
  9. let newView = createEntry()
  10. newView.hidden = true
  11. stack.insertArrangedSubview(newView, atIndex: index)
  12. UIView.animateWithDuration(0.25) { () -> Void in
  13. newView.hidden = false
  14. scroll.contentOffset = offset
  15. }
  16. }

This method calculates a new offset for the scroll view, then creates a new entry view. The entry view is hidden, and added to the stack. Hidden views do not affect the appearance or layout of a stack—so the stack’s appearance remains unchanged. Then, in an animation block, the view is revealed and the scroll offset is updated, animating the view’s appearance.

此方法计算滚动视图的新偏移量,然后创建一个新的入口视图。入口视图被隐藏,并添加到堆栈中。隐藏视图不影响堆栈的外观或布局,因此堆栈的外观保持不变。然后,在动画块中,视图被显示,滚动偏移被更新,动画视图的外观。

Add a similar method to delete entries; however, unlike the addEntry method, this method is not linked to any controls in Interface Builder. Instead, the app will programmatically link each entry view to this method when the view is created.

添加一个类似的方法来删除条目;然而,不像addentry方法,这种方法是不与界面中的任何控件。相反,当视图创建时,应用程序将编程地将每个入口视图链接到该方法。

  1. func deleteStackView(sender: UIButton) {
  2. if let view = sender.superview {
  3. UIView.animateWithDuration(0.25, animations: { () -> Void in
  4. view.hidden = true
  5. }, completion: { (success) -> Void in
  6. view.removeFromSuperview()
  7. })
  8. }
  9. }

This method hides the view in an animation block. After the animation completes, it removes the view from the view hierarchy. This automatically removes the view from the stack’s list of arranged views.

此方法隐藏动画块中的视图。动画完成后,它将从视图层次结构中移除视图。这将自动从堆栈的排列视图中删除视图。

Although the entry view could be any view, this example uses a stack view that contains a date label, a label containing a random hex string, and a delete button.

虽然入口视图可以是任意视图,但这个例子使用了包含日期标签、包含随机十六进制字符串的标签和删除按钮的堆栈视图。

  1. // MARK: - Private Methods
  2. private func createEntry() -> UIView {
  3. let date = NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .ShortStyle, timeStyle: .NoStyle)
  4. let number = "\(randomHexQuad())-\(randomHexQuad())-\(randomHexQuad())-\(randomHexQuad())"
  5. let stack = UIStackView()
  6. stack.axis = .Horizontal
  7. stack.alignment = .FirstBaseline
  8. stack.distribution = .Fill
  9. stack.spacing = 8
  10. let dateLabel = UILabel()
  11. dateLabel.text = date
  12. dateLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody)
  13. let numberLabel = UILabel()
  14. numberLabel.text = number
  15. numberLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
  16. let deleteButton = UIButton(type: .RoundedRect)
  17. deleteButton.setTitle("Delete", forState: .Normal)
  18. deleteButton.addTarget(self, action: "deleteStackView:", forControlEvents: .TouchUpInside)
  19. stack.addArrangedSubview(dateLabel)
  20. stack.addArrangedSubview(numberLabel)
  21. stack.addArrangedSubview(deleteButton)
  22. return stack
  23. }
  24. private func randomHexQuad() -> String {
  25. return NSString(format: "%X%X%X%X",
  26. arc4random() % 16,
  27. arc4random() % 16,
  28. arc4random() % 16,
  29. arc4random() % 16
  30. ) as String
  31. }
  32. }

Discussion讨论

As this recipe demonstrates, views can be added or removed from stack views during runtime. The stack’s layout automatically adjusts to compensate for changes to its array of arranged views. There are, however, a couple of important points worth remembering:

由于该配方演示,视图可以在运行时从堆栈视图中添加或移除。堆栈的布局自动调整,以补偿其排列的视图的数组的变化。然而,有几个值得记住的要点:

  • Hidden views are still inside stack’s array of arranged views. However, they are not displayed and do not affect the layout of the other arranged views.隐藏视图仍在堆栈的排列视图的数组中。但是,它们不显示和不影响布局的其他布置视图。

  • Adding a view to the stack’s array of arranged views automatically adds it to the view hierarchy.向堆栈的排列视图添加视图将自动将其添加到视图层次结构中。

  • Removing a view from the stack’s array of arranged views does not automatically remove it from the view hierarchy; however, removing the view from the view hierarchy does removes it from the arranged views array.从堆栈的排列视图中移除视图不会自动从视图层次结构中移除它,但是,从视图层次结构中移除视图会将其从已排列的视图数组中移除。

  • In iOS, the view’s hidden property is normally not animatable. However, this property becomes animatable for views as soon as they are placed in a stack’s arranged views array. The actual animation is managed by the stack, not the view. Use the hidden property to animate adding views to or removing them from the stack.在iOS中,视图的隐藏属性通常是不动的。然而,这种财产成为动画的看法就被放置在一个堆栈的安排意见阵列。实际动画由堆栈管理,而不是视图。使用隐藏属性动画添加视图或从堆栈中移除它们。

This recipe also introduces the idea of using Auto Layout with scroll views. Here, the constraints between the stack and the scroll view set the size of the scroll view’s content area. An equal width constraint explicitly sets the stack (and thus the content size) to fill the scroll view horizontally. Vertically, the content size is based on the stack’s fitting size. The stack view grows longer as the user adds more entries. Scrolling is automatically enabled as soon as there is too much content to fit on the screen.

该配方还介绍了使用自动布局与滚动视图的想法。在这里,堆栈和滚动视图之间的约束设置了滚动视图内容区域的大小。相等的宽度约束显式设置堆栈(因此内容大小)以横向填充滚动视图。垂直,内容大小是基于堆栈的拟合大小。当用户添加更多条目时,堆栈视图变长。滚动是自动启用,只要有太多的内容,以适应屏幕上。

For more information, see Working with Scroll Views.有关更多信息,请参见使用滚动视图工作。

转载于:https://www.cnblogs.com/zyingn/p/AutoLayoutCookbook__StackViews.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值