一、 Using the Flow Layout
You can arrange items in your collection views using a concrete layout object, the UICollectionViewFlowLayout class. The flow layout implements a line-based breaking layout, which means that the layout object places cells on a linear path and fits as many cells along that line as it can. When the layout object runs out of room on the current line, it creates a new line and continues the layout process there. Figure 3-1 shows what this looks like for a flow layout that scrolls vertically. In this case, lines are laid out horizontally with each new line positioned below the previous line. The cells in a single section can be optionally surrounded with section header and section footer views.
Figure 3-1 Laying out sections and cells using the flow layout
你可以使用具体的布局对象(UICollectionViewFlowLayout类)在你的集合视图中排列items。流布局实现了基于行的中断布局,这意味着布局对象将cells放置在线性路径上,并尽可能多地沿着该线填充cells。当布局对象在当前行的空间不足时,将创建一个新行并继续布局过程。图3-1显示了垂直滚动的流布局的样子。在这种情况下,线被水平放置,每条新线位于前一行的下方。单个section中的cells可以选择性地被section header and section footer视图包围。
Figure 3-1 Laying out sections and cells using the flow layout
You can use the flow layout to implement grids, but you can also use it for much more. The idea of a linear layout can be applied to many different designs. For example, rather than having a grid of items, you can adjust the spacing to create a single line of items along the scrolling dimension. Items can also be different sizes, which yields something more asymmetrical than a traditional grid but that still has a linear flow to it. There are many possibilities.
你可以使用流布局来实现网格,但你也可以使用它实现更多效果。线性布局的想法可以应用于许多不同的设计。例如,除了可以使用网格布局items,你可以调整间距以沿着滚动方向创建单行items。items也可以是不同的大小,产生比传统的网格更不对称的东西,但仍然是一个线性的流水布局。这里可以有很多可能性。
You can configure the flow layout either programmatically or using Interface Builder in Xcode. The steps for configuring the flow layout are as follows:
- Create a flow layout object and assign it to your collection view.
- Configure the width and height of cells.
- Set the spacing options (as needed) for the lines and items.
- If you want section headers or section footers,specify their size.
- Set the scroll direction for the layout.
你可以以编程方式或使用Xcode中的Interface Builder配置流布局。配置流程布局的步骤如下:
- 创建一个流布局对象,并将其分配给你的集合视图。
- 配置cells的宽度和高度。
- 设置行间距和items的间距(根据需要)。
- 如果你想要section headers 或 section footers,请指定它们的大小。
- 设置布局的滚动方向。
Important: At a minimum, you must specify the width and height of cells. If you don’t, your items are assigned a width and height of 0 and will never be visible.
重要说明: 至少你必须指定cell的宽度和高度。如果你不这样做,你的items的宽度和高度都被设置为0,并将永远不可见。
二、 Customizing the Flow Layout Attributes
The flow layout object exposes several properties for configuring the appearance of your content. When set, these properties are applied to all items equally in the layout. For example, setting the cell size using the itemSize property of the flow layout object causes all cells to have the same size.
If you want to vary the spacing or size of items dynamically, you can do so using the methods of the UICollectionViewDelegateFlowLayout protocol. You implement these methods on the same delegate object you assigned to the collection view itself. If a given method exists, the flow layout object calls that method instead of using the fixed value it has. Your implementation must then return appropriate values for all of the items in the collection view.
流布局对象公开了几个用于配置内容外观的属性。当设置时,这些属性将每一个item都相同的大小应用于布局中的所有items。例如,使用itemSize属性设置cell大小会导致所有cell具有相同的大小。
如果要动态改变项目的间距或大小,可以使用UICollectionViewDelegateFlowLayout
协议的方法来完成。你可以在赋值给集合视图本身的同一个delegate对象上实现这些方法。如果给定的方法存在,则流布局对象将调用该方法,而不是使用它的固定值。然后,你的实现必须返回集合视图中所有项目的适当值。
Specifying the Size of Items in the Flow Layout
If all of the items in the collection view are the same size, assign the appropriate width and height values to the itemSize property of the flow layout object. (Always specify the size of items in points.) This is the fastest way to configure the layout object for content whose size does not vary.
If you want to specify different sizes for your cells, you must implement the collectionView:layout:sizeForItemAtIndexPath: method on the collection view delegate. You can use the provided index path information to return the size of the corresponding item. During layout, the flow layout object centers items vertically on the same line, as shown in Figure 3-2. The overall height or width of the line is then determined by the largest item in that dimension.
如果集合视图中的所有items的大小相同,则使用itemSize属性配置流布局对象相应的宽度和高度。(始终以点为单位指定项目的大小。)这是配置布局对象(大小不变的内容)的最快方法。
如果要为cells指定不同的大小,则必须实现集合视图delegate对象的collectionView:layout:sizeForItemAtIndexPath:
方法。你可以使用提供的索引路径信息返回相应item的大小。在布局过程中,流布局对象一中心为线垂直放置在同一行上,如图3-2所示。行的总高度或宽度由该方向上的最大item确定。
Figure 3-2 Items of different sizes in the flow layout
Note: When you specify different sizes for cells, the number of items on a single line can vary from line to line.
注意: 当为cell指定不同的大小时,单个行上的item数可能因行而异。
Specifying the Space Between Items and Lines
Using the flow layout, you can specify the minimum spacing between items on the same line and the minimum spacing between successive lines. Keep in mind that the spacing you provide is only the minimum spacing. Because of how it lays out content, the flow layout object may increase the spacing between items to a value greater than the one you specified. The layout object may similarly increase the actual line-spacing when the items being laid out are different sizes.
During layout, the flow layout object adds items to the current line until there is not enough space left to fit an entire item. If the line is just big enough to fit an integral number of items with no extra space, then the space between the items would be equal to the minimum spacing. If there is extra space at the end of the line, the layout object increases the interitem spacing until the items fit evenly within the line boundaries, as shown in Figure 3-3. Increasing the spacing improves the overall look of the items and prevents large gaps at the end of each line.
使用流布局,可以指定同一行上的items之间的最小间距和连续行之间的最小间距。请记住,你提供的间距只是最小间距。由于其布局内容的方式,流布局对象可能会将items之间的间距增加到大于你指定的值。当布置的items是不同尺寸时,布局对象可能会同样地增加实际行间距。
在布局过程中,流布局对象会将items添加到当前行,直到没有足够的空间来放置整个item。如果这条线足够大,可以放入整个数量的物品而没有额外的空间,那么物品之间的空间就等于最小间距。如果在行尾有额外的空间,布局对象将增加interitem间距,直到items在行边界内均匀匹配,如图3-3所示。增加间距可以改善item的整体外观,并防止每条线的末端出现大的间隙。
Figure 3-3 Actual spacing between items may be greater than the minimum
For interline spacing, the flow layout object uses the same technique that it does for inter-item spacing. If all items are the same size, the flow layout is able to respect the minimum line spacing value absolutely and all items in one line appear to be spaced evenly from the items in the next line. If the items are of different sizes, the actual spacing between individual items can vary.
Figure 3-4 demonstrates what happens with the minimum line spacing when items are of different sizes. With differently sized items, the flow layout object picks the item from each line whose dimension in the scrolling direction is the largest. For example, in a vertically scrolling layout, it looks for the item in each line with the greatest height. It then sets the spacing between those items to the minimum value. If the items are on different parts of the line, as shown in the figure, the actual line spacing appears to be greater than the minimum.
对于interline间距,流布局对象使用与项间间距(inter-item)相同的技术。如果所有items大小相同,则流程布局能够绝对地遵守最小行间距值,并且一行中的所有items看起来与下一行中的项目均匀分隔。如果items的尺寸不同,单个item之间的实际间距可能会有所不同。
图3-4演示了当项目大小不同时,最小行间距会发生什么情况。对于不同大小的项目,流布局对象将从滚动方向上维度最大的每行中选取item。例如,在垂直滚动布局中,它会查找每个高度最大的行中的item。然后将这些items之间的间距设置为最小值。如果items位于线条的不同部分,如图所示,实际的线条间距似乎大于最小值。
Figure 3-4 Line spacing varies if items are of different sizes
As with other flow layout attributes, you can use fixed spacing values or vary the values dynamically. Line and item spacing is handled on a section-by-section basis. Thus, the line and interitem spacing is the same for all of the items in a given section but may vary between sections. You set the spacing statically using the minimumLineSpacing and minimumInteritemSpacing properties of the flow layout object or using the collectionView:layout:minimumLineSpacingForSectionAtIndex: and collectionView:layout:minimumInteritemSpacingForSectionAtIndex: methods of your collection view delegate.
与其他流布局属性一样,你可以使用固定间距值或动态值。line space和item space是在section与section的基础上处理的。因此,给定section中的所有item的line space和interitem相同,但部分之间可能会有所不同。你可以设置静态间距使用流动布局对象的minimumLineSpacing和minimumInteritemSpacing属性,或使用collectionView:layout:minimumLineSpacingForSectionAtIndex:
与collectionView:layout:minimumInteritemSpacingForSectionAtIndex:
代理方法。
Using Section Insets to Tweak the Margins of Your Content
Section insets are a way to adjust the space available for laying out cells. You can use insets to insert space after a section’s header view and before its footer view. You can also use insets to insert space around the sides of the content. Figure 3-5 demonstrates how insets affect some content in a vertically scrolling flow layout.
Section insets是调整已经被放置cell的空间的一种方法。你可以使用insets属性在section的 header view之后和section的 footer view之前插入空间。你也可以使用insets属性在内容的周围插入空间。图3-5演示了insets如何影响垂直滚动流布局中的某些内容。
Figure 3-5 Section insets change the available space for laying out cells
Because insets reduce the amount of space available for laying out cells, you can use them to limit the number of cells in a given line. Specifying insets in the nonscrolling direction is one way to constrict the space for each line. If you combine that information with an appropriate cell size, you can control the number of cells on each line.
由于insets减少了可用于布置cell的空间量,因此可以使用它们来限制给定行中的cells数量。在非滚动方向上指定insets是缩小每行的空间的一种方法。如果将这些信息与适当的cell大小相结合,则可以控制每行上的cells数量。
三、 Knowing When to Subclass the Flow Layout
Although you can use the flow layout very effectively without subclassing, there are still times when you might need to subclass to get the behavior you need. Table 3-1 lists some of the scenarios for which subclassing UICollectionViewFlowLayout is necessary to achieve the desired effect.
尽管不用子类化就可以很方便的使用流水布局,但仍然有时候需要子类化来实现你想要的行为。表格3-1列出了一些场景,要实现希望的效果,子类化UICollectionViewFlowLayout是必须。
Snip20180108_6.pngThere are also instances in which the right thing to do is to create a custom layout from scratch. Before you decide to do this, take the time to consider whether or not it is really necessary. The flow layout provides a lot of customizable behavior that is appropriate for many different kinds of layouts, and because it is provided to you, it is easy to use and contains numerous optimizations to make it efficient. However, all this is not to say that you should never create a custom layout, because there are circumstances in which doing so make absolute sense. The flow layout limits the scroll direction to one direction, so if your layout contains content that stretches farther than the bounds of the screen in both directions, a custom layout makes more sense to implement. Creating a custom layout is the right decision if your layout is not a grid or a line-based breaking layout, as described above, or if the items within your layout move so frequently that subclassing the flow layout is more compicated than creating your own.
For more on creating a custom layout, see Creating Custom Layouts.
还有一些情况下,正确的做法是从头开始创建自定义布局。在你决定这样做之前,花点时间考虑一下是否真的有必要。流布局提供了许多适合于许多不同类型布局的可定制行为,并且因为它提供给你,所以它易于使用并包含许多优化以使其更高效。然而,这并不是说你永远不应该创建一个自定义的布局,因为在某些情况下,这样做是绝对有意义的。流布局将滚动方向限制为一个方向,因此如果你的布局包含的内容比屏幕边界更远并且是两个方向的,则自定义布局更有意义。
有关创建自定义布局的更多信息,请参阅《Creating Custom Layouts》。
网友评论