UICollectionViewSplitLayout 使得集合视图更加响应。
这是什么?
UICollectionViewSplitLayout 是 UICollectionViewLayout 的子类。它将分区分为一列或两列。
集合视图有 "分区" 用于组织项集合。UICollectionViewFlowLayout 从顶部到底部排列它们。
另一方面,UICollectionViewSplitLayout 将分区分为两列。您可以动态更新它们的宽度以及每个分区所在的列。
例如,使用 UICollectionViewSplitLayout 的集合视图根据设备方向改变列数。您只需要在改变屏幕大小时设置 leftSideRatio
的值。此图描述了一个有三个分区(红色、蓝色和绿色)的集合视图和 UICollectionViewSplitLayout 将它们布局在左侧或右侧。
如果您无法想象它是如何工作的,请运行 EmojiCollectionViewController。
要求
- iOS 9.0+
- Swift 4.2
安装
Carthage
1. 创建 Cartfile
github "https://github.com/yahoojapan/UICollectionViewSplitLayout"
2. 安装
> carthage update
CocoaPods
1. 创建 Podfile
platform :ios, '8.0'
use_frameworks!
pod "UICollectionViewSplitLayout", :git => 'https://github.com/yahoojapan/UICollectionViewSplitLayout.git'
2. 安装
> pod install
入门指南
从将 UICollectionViewFlowLayout 替换为 UICollectionViewSplitLayout 开始是个不错的选择。
1. 创建 UICollectionViewController
在 Storyboard 上设置 UICollectionViewController。
添加构建集合视图的实现。
import UIKit
private let reuseIdentifier = "Cell"
class BasicCollectionViewController: UICollectionViewController {
@IBOutlet weak var layout: UICollectionViewSplitLayout!
var dataSource: [[UIColor]] = [
(0..<20).map { _ in .red },
(0..<20).map { _ in .blue },
(0..<20).map { _ in .green }
]
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
}
// MARK: UICollectionViewDataSource
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return dataSource.count
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataSource[section].count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.backgroundColor = dataSource[indexPath.section][indexPath.row]
return cell
}
}
构建代码。
显示三个部分,其项目具有不同的颜色。
2. 将 UICollectionViewSplitLayout 输入到自定义布局类
将布局属性更改为 "Custom",然后在类和模块属性中输入 "UICollectionViewSplitLayout"。
3. 设置 UICollectionViewSplitLayout 的参数
将故事板中的布局类连接到源代码。在 viewDidLoad() 中设置参数。
@IBOutlet weak var layout: UICollectionViewSplitLayout!
override func viewDidLoad() {
super.viewDidLoad()
//...
//...
layout.minimumItemLineSpacing = 8
layout.minimumInterItemSpacing = 8
layout.sectionInset = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
layout.splitSpacing = 0.4
collectionView.collectionViewLayout = layout
//...
//...
}
4. 实现 UICollectionViewSplitLayout 的布局代理
实现 UICollectionViewDelegateTwoColumnLayout。以下方法是必需的。
extension BasicCollectionViewController: UICollectionViewDelegateSectionSplitLayout {
// Fix the size of each item as UICollectionViewDelegateFlowLayout does. calculateFixedWidthRaughly() is utility method UICollectionViewSplitLayout has.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath, width: CGFloat, side: UICollectionViewSplitLayoutSide) -> CGSize {
let width = layout.calculateFixedWidthRaughly(
to: 3,
of: side,
minimumInterItemSpacing: layout.minimumInterItemSpacing,
sectionInset: layout.sectionInset)
return CGSize(width: width, height: 100)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sideForSection section: Int) -> UICollectionViewSplitLayoutSide {
// when a section number is odd, the items are placed into left side.
return section % 2 == 0 ? .left : .right
}
}
它将每个分区分为左侧或右侧。
查看 BasicCollectionViewController 以运行上面的示例。
架构
它是 UICollectionViewLayout 之一。因此,您可以在不更新 UICollectionViewDelegate 和 UICollectionViewDataSource 中的代码的情况下更改布局。这是应用新布局的合理方式。您需要做的就是学习布局类和代理。
用法
如何分割
UICollectionViewSplitLayout 使用以下参数计算左右两侧的宽度。
leftSideRatio = 0.4
它包含一个浮点值,表示左边宽度与整个宽度的比例。此外,左右两侧之间还有间隔。
splitSpacing = 10
如果集合视图宽度为110pt,上述设置需要左侧40pt的宽度,右侧60pt的宽度。当左边比例(leftSideRatio)为0.0时,splitSpacing作为例外会被忽略。
您可以选择每个部分在哪一侧。UICollectionViewDelegateSectionSplitLayout提供了一个方法来实现这一点。
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sideForSection section: Int) -> UICollectionViewSplitLayoutSide
UICollectionViewSplitLayout在每次集合视图调用invalidateLayout()时都会挂钩委托。
边距
UICollectionViewSplitLayout有这些参数来确定边距。
/// The minimum spacing to use between items in the same row.
open var minimumInterItemSpacing: CGFloat
/// The minimum spacing to use between lines of items in the grid.
open var minimumItemLineSpacing: CGFloat
/// The margins used to lay out content in a section
open var sectionInset: UIEdgeInsets
它们通过部分(可选)有对应委托方法。
// section inset to each section
@objc optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int, side: UICollectionViewSplitLayoutSide) -> UIEdgeInsets
// minimumInterItemSpacing to each section
@objc optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInterItemSpacingForSectionAtIndex section: Int, side: UICollectionViewSplitLayoutSide) -> CGFloat
// minimumItemLineSpacing to each section
@objc optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumItemLineSpacingForSectionAtIndex section: Int, side: UICollectionViewSplitLayoutSide) -> CGFloat
固定(iOS 11~)
UICollectionViewSplitLayout像UICollectionViewFlowLayout一样固定部分标题。该功能从iOS 11开始支持。sectionPinToVisibleBounds
允许其工作。
设置属性
UICollectionViewSplitLayout使用三种属性:项目(item)、辅助视图(supplementary view)和装饰视图(decoration view)。
项目
您需要实现单元格-sizing。UICollectionViewSplitLayout提供了一个委托来实现它。
func collectionView(
_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: IndexPath,
width: CGFloat,
side: UICollectionViewSplitLayoutSide) -> CGSize
您可以使用实用方法均匀地分配大小。
open func calculateFixedWidthRaughly(
to num: Int,
of side: UICollectionViewSplitLayoutSide,
minimumInterItemSpacing: CGFloat,
sectionInset: UIEdgeInsets) -> CGFloat
标题和页脚的辅助视图
您可以实现标题和页脚的大小。UICollectionViewSplitLayout提供了一个委托来实现它。如果大小为零,则忽略标题和页脚。
// header
@objc optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int, width: CGFloat, side: UICollectionViewSplitLayoutSide) -> CGSize
// footer size
@objc optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int, width: CGFloat, side: UICollectionViewSplitLayoutSide) -> CGSize
为backgroundColor的装饰视图
UICollectionSplitLayout有一个特殊的装饰视图。它的大小与部分相同。你可以通过以下代理确定每个部分的backgroundColor。
@objc optional func collectionView(
_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
itemsBackgroundColorFor section: Int,
side: UICollectionViewSplitLayoutSide) -> UIColor?
行高标准化
如果该属性为true,则项目高度调整为行轮廓高度(默认:false)。
open var isNormalizingLineHeight: Bool
许可证
MIT许可证(MIT)
版权所有(c)2018 Yahoo Japan Corporation
允许任何人在不支付费用的前提下使用此软件及其相关文档(“软件”),包括但不限于使用、复制、修改、合并、发布、分发、再许可或出售软件的副本,并允许向获取软件的个人提供使用软件的权利,但前提是遵守以下条件
本版权声明和本许可声明应包含在软件的所有副本或主要部分。
软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、特定用途适用性和非侵权性保证。在任何情况下,无论因合同、侵权或其他行为提起何种诉讼或诉讼原因,作者或版权持有者均不对任何索赔、损害或其他责任承担责任,无论是否基于软件或其使用或其他方式。