CollectionLayouts
我们产品独特之处在于我们对应用自定义所付出的努力。
此仓库包含一系列用于自定义 UICollectionView 行为的 UICollectionViewLayout 子类。
此仓库中包含目前在 Saks 5th Avenue 应用中使用的 3 种布局
- LNZSnapToCenterCollectionViewLayout
- LNZInfiniteCollectionViewLayout
- LNZCarouselCollectionViewLayout
所有布局均可通过界面构建器进行自定义。可以通过代理模式获取其焦点元素的更新通知,其中焦点元素是指目前居中的元素。
请注意
v1.1.4 与 xCode 9.3 以上版本兼容。
LNZSnapToCenterCollectionViewLayout
此布局是一个简单的水平布局,将元素吸附到中心。默认情况下,第一个项目将居中,左侧留出空白。通过将 centerFirstItem
变量设置为 false 来关闭此行为。
LNZInfiniteCollectionViewLayout
此布局是一个 LNZZSnapToCenterCollectionViewLayout,在滚动时重新组织属性,以便它们可以无限水平滚动。每个单元格都保持其 indexPath,布局不会修改数据源顺序。可以通过将 snapToCenter
变量修改为 false 来关闭 snapToCenter 行为。
为了支持无限滚动,数据源必须包含足够多的项目,使得 collectionView 的大小至少是屏幕大小的 1.5 倍。布局不会重复元素,因此同一元素不会在同一时间内两次出现在屏幕上。如果数据源不适合无限滚动行为,则 LNZInfiniteCollectionViewLayout 将回退到 LNZSnapToCenterCollectionViewLayout 行为。(如果 snap to center 关闭,则保持关闭)
LNZCarouselCollectionViewLayout
这是一个 LNZZSnapToCenterCollectionViewLayout,不同之处在于,处于焦点的项将以全尺寸显示,而所有其他不在焦点项将按比例缩小到 collectionView 的中心距离。可以通过将 isInfiniteScrollEnabled
和 snapToCenter
属性设置为 false 来关闭无限滚动以及 snapToCenter 行为。可以通过更改 scalingOffset
和 minimumScaleFactor
属性值来自定义缩放行为,以获得所需的不在焦点项的缩放比例。
scalingOffset
表示距离中心多远之后,所有项目都将按 minimumScaleFactor
缩放。中心的项目始终具有缩放因子 1。
LNZSafariLayout
这是一个模拟 Safari 应用程序标签行为的 collection view。您可以通过向左滑动删除一个磁贴,就像在 Safari 中一样,并嵌入一个自定义动画器,可在当前 collectionViewController 之间触发转换到表示所选标签的视图控制器。
此布局不接受类型为 UICollectionViewDelegateFlowLayout
的代理,因为在 LNZSafariLayout 中 它不是 一个 Flow 布局。如果将此类型代理传递给 collectionView,则只会调用 UICollectionViewDelegate
的方法。
要启用删除功能,您的代理必须遵守UICollectionViewDelegateSafariLayout
协议,该协议继承自UICollectionViewDelegate
,就像众所周知的UICollectionViewDelegateFlowLayout
一样,并实现collectionView(_:layout:canDeleteItemAt:)
方法来决定哪些单元格可以删除,以及collectionView(_:layout:didDeleteItemAt:)
方法来响应删除操作。这个模式与UITableView
通过实现tableView(_:commit:forRowAt:)
方法删除单元格的模式相同。因此,在这个方法中,您必须相应地更新数据源。
要为每个项目指定大小,您必须遵守UICollectionViewDelegateSafariLayout
,并在未实现的情况下实现可选方法collectionView(_ : layout: sizeForItemAt:)
。如果未实现,则将使用存储在属性itemSize
中的默认大小作为集合中每个单元格的大小。
如果在单元格的didSelect事件中,您想使用自定义动画器显示视图控制器,那么包含LNZSafariLayout
的CollectionView的当前视图控制器(包含视图控制器的视图控制器)必须遵守SafariLayoutContaining
协议,然后在控制器创建时,您应该执行以下操作
viewController.modalPresentationStyle = .custom
viewController.transitioningDelegate = self
通过将切换代理设置为self,您可以选择用于此控制器显示和消失的动画器。
遵守UIViewControllerTransitioningDelegate
将使您有机会决定要使用的动画器。
public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
guard let indexPath = collectionView?.indexPathsForSelectedItems?.first,
let safariLayout = collectionView?.collectionViewLayout as? LNZSafariLayout else { return nil }
return safariLayout.animator(forItem: indexPath)
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
guard let element = (dismissed as? SafariModalViewController)?.presentedElement,
let item = elements.index(of: element),
let safariLayout = collectionView?.collectionViewLayout as? LNZSafariLayout else { return nil }
let indexPath = IndexPath(item: item, section: 0)
let animator = safariLayout.animator(forItem: indexPath)
animator?.reversed = true
return animator
}
LNZSafariLayout可以配置一个动画器,以便能够为当前索引路径的过渡动画。