首页 > 其他分享 >iOS Modern Collection View

iOS Modern Collection View

时间:2023-04-09 11:44:54浏览次数:48  
标签:layout collectionView section Modern iOS Collection cell item 创建

TL;DR

  • 使用的技术: Compositional layout + Diffable data source。iOS 14+。
  • 创建 layout 以描述布局;
  • 创建 dataSource 以提供数据和 view:
    • 使用 CellRegistration 和 dequeueConfiguredReusableCell 来获取 cell;
    • 使用 SupplementaryRegistration 和 dequeueConfiguredReusableSupplementary 来获取 header、footer 等 supplementary views。

Compositional Layout

explain

如上图所示,一个 compositional layout 由若干个 section 组成,每个 section 又由若干个 group 组成,每个 group 又包含若干个 item,因此,创建一个 layout 的过程即先创建最小展示单元 item 开始,再创建 group,创建 section,创建 layout:

func createBasicListLayout() -> UICollectionViewLayout {
  let itemSize = NSCollectionLayoutSize(
    widthDimension: .fractionalWidth(1.0),
    heightDimension: .fractionalHeight(1.0)
  )
  let item = NSCollectionLayoutItem(layoutSize: itemSize)

  let groupSize = NSCollectionLayoutSize(
    widthDimension: .fractionalWidth(1.0),
    heightDimension: .absolute(44)
  )
  let group = NSCollectionLayoutGroup.horizontal(
    layoutSize: groupSize,
    subitems: [item]
  )

  let section = NSCollectionLayoutSection(group: group)

  let layout = UICollectionViewCompositionalLayout(section: section)
  return layout
}

SectionProvider

如果需要多个布局不同的 sections,可以用下面的构造函数来创建 layout:

// UICollectionViewCompositionalLayout
init(
    sectionProvider: @escaping UICollectionViewCompositionalLayoutSectionProvider,
    configuration: UICollectionViewCompositionalLayoutConfiguration
)

其中闭包 sectionProvider 用于创建并返回 layout 的各个 secitons,声明如下:

typealias UICollectionViewCompositionalLayoutSectionProvider = (Int, NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection?
// arguments meaning: { sectionIndex, layoutEnvironment in ... }

该闭包也会在一些系统事件触发时被调用,如横竖屏切换、系统字体变更、iPad multitasking 引发的 size class 变更等,可以访问 layoutEnvironment 来获取相关信息,以适配这些场景。

LayoutConfiguration

UICollectionViewCompositionalLayoutConfiguration

  • scrollDirection: UICollectionView.ScrollDirection
    • 滚动方向:.vertical | .horizontal
  • interSectionSpacing: CGFloat
    • Sections 之间的间距
  • contentInsetsReference: UIContentInsetsReference
    • 定义 content inset 时的参考边界
    • .automatic | .none | .safeArea | .layoutMargins | .readableContent
      • img
      • 红色为 safeArea,绿色为 layoutMargins,蓝色为 readableContent
  • boundarySupplementaryItems: [NSCollectionLayoutBoundarySupplementaryItem]
    • 在整个 layout 边界处的一些附加 items,如全局 header、全局 footer、badge 等

LayoutEnvironment

包含 layout container 和 environment traits 的信息

  • container: NSCollectionLayoutContainer
    • contentSize: CGSize
    • effectiveContentSize: CGSize:content insets 生效之后的 size
    • contentInsets: NSDirectionalEdgeInsets
    • effectiveContentInsets: NSDirectionalEdgeInsets
  • traitCollection: UITraitCollection

List layout

Compositional layout 专门提供了一个接口来创建 list layout:

static func list(using: UICollectionLayoutListConfiguration) -> UICollectionViewCompositionalLayout

UICollectionLayoutListConfiguration 用于配置 list layout 的一些属性,构造函数中需要指定一个 appearance,如 .plain.sidebar.grouped 等。参见 Apple 文档 来查看可配置的属性,下面列出几种。

  • headerMode
    • .none:不展示 header;
    • .supplementary:使用 supplementary views 来展示 headers;
    • .firstItemInSection:使用 section 中的第一个 item 来作为 header。

Cell view 和 supplementary view 的获取

创建 dataSource 的时候,需要传入一个 cellProvider 来提供 cell view:

dataSource = UICollectionViewDiffableDataSource<Int, UUID>(collectionView: collectionView) {
    (collectionView: UICollectionView, indexPath: IndexPath, itemIdentifier: UUID) -> UICollectionViewCell? in
    // Configure and return cell.
}

之前我们需要调用 register 方法来注册所需要的 cell 类,然后在 cellProvider 中调用 dequeueReusableCell 方法来获取复用的 cell。iOS 14 提供了一组新的方法,通过 CellRegistration 来配置 cell,然后使用 dequeueConfiguredReusableCell 方法来获取复用的 cell,在调用该方法的时候会自动将 cell 注册到 collectionView 上。如:

let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, Int> { cell, indexPath, item in
    var contentConfiguration = cell.defaultContentConfiguration()
    
    contentConfiguration.text = "\(item)"
    contentConfiguration.textProperties.color = .lightGray
    
    cell.contentConfiguration = contentConfiguration
}

dataSource = UICollectionViewDiffableDataSource<Section, Int>(collectionView: collectionView) {
    (collectionView: UICollectionView, indexPath: IndexPath, itemIdentifier: Int) -> UICollectionViewCell? in
    
    return collectionView.dequeueConfiguredReusableCell(using: cellRegistration,
                                                        for: indexPath,
                                                        item: itemIdentifier)
}

注意不要在 cellProvider 里面创建 cell registration,会造成 cell 无法复用,且在 iOS 15+ 上直接报异常

对 cell 的配置通过 UIListContentConfiguration 来完成,调用 cell 的 defaultContentConfiguration 来获取一个包含一些预设属性的 configuration,根据传入的数据对其进行配置,然后再赋值回 cell 的 contentConfiguration。设置 contentConfiguration 会替换掉 cell 现有的 contentView。Cell configuration 具体可参见 Modern cell configuration (WWDC20 10027)

Header、footer 等 supplementary views 的配置和 cell 类似,设置 dataSource 的 supplementaryViewProvider 属性来提供用于创建 view 的闭包,在闭包里面调用 dequeueConfiguredReusableSupplementary 来获取一个复用的 view,该方法接受一个闭包参数 SupplementaryRegistration 来配置 view。

References

标签:layout,collectionView,section,Modern,iOS,Collection,cell,item,创建
From: https://www.cnblogs.com/jerrywossion/p/17300076.html

相关文章

  • 看到这个案例,突然醒悟axios的使用方法
    案例--点击按钮改变文本内容源代码:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>测试界面</title></head><body><divid="app"><p>{{message}}</p......
  • java -- 异常处理、Collection、Iterator迭代器、泛型
    异常处理Java异常处理的五个关键字:try、catch、finally、throw、throws抛出异常throw在编写程序时,我们必须要考虑程序出现问题的情况当调用方法使用接受到的参数时,首先需要先对参数数据进行合法的判断,数据若不合法,就应该告诉调用者,传递合法的数据进来。这时需要使用抛出异常的......
  • iOS开发_常用框架简要说明
    ①UIKit:用于构建iOS应用程序的框架,提供了应用程序的基本结构,例如UI类和控制器类。②Foundation:提供了一系列基于Cocoa的基本服务,如Unicode字符串、网络服务和数据管理。③CoreData:用于管理应用程序中的数据对象和关系图。④CloudKit:提供一个云端数据存储和......
  • SDL_AudioSpec 解析以及使用说明
    前言SDL_AudioSpec是包含音频输出格式的结构体,同时它也包含当音频设备需要更多数据时调用的回调函数。解析头文件说明typedefstructSDL_AudioSpec{intfreq;/**<DSPfrequency--samplespersecond*/SDL_AudioFormatformat;/**<Audiod......
  • ios17更新后打不开视频
    有些小伙伴在手机更新之后打不开视频了,这是怎么回事呢,应该是更新之后把相机的兼容性关闭了,所以导致了视频看不了的,那么现在就让我们看一下如何解决吧。ios17更新后打不开视频:1、首先我们打开设置。2、然后找到视频。3、接着我们找到无线局域网。4、然后我们选择设置为良......
  • Vue中axios请求后res返回204,no content,res.data为undefind
    一直以为后台只要返回200-299之间的状态码就没问题,就是这个错误认知,花了三个小时终于想到解决办法附上axios 地址  axios中文文档|axios中文网|axios(axios-js.com)前面一直想着后台能接收处理请求,肯定不是后台问题,一直花时间配置前端请求指令,以及设置响应拦截器查看情况......
  • JQ插件:radiosToSlider
    demo:http://rubentd.com/radios-to-slider/用法:<scriptsrc="js/jquery-1.10.2.min.js"></script><scriptsrc="js/jquery.radios-to-slider.js"></script><script> $(document).ready(funct......
  • IOS 发展史各个ipone的发布时间(二)
      iPhone7iPhone7是Apple(苹果公司)第10代手机,北京时间2016年9月8日凌晨1点在美国旧金山比尔·格雷厄姆市政礼堂2016年苹果秋季新品发布会上发布。 [1-3] iPhone7拥有金色、银色、玫瑰金色、黑色、亮黑色、红色(特别版,后增加)六种颜色。 [4] Home键有了全新的设计,添加了振动......
  • ios::sync_with_stdio(false);
    在阅读学习别人的代码的过程中,我们有时会发现这么一行:std::ios::sync_with_stdio(false);这是由于cin比scanf要慢很多,在需要大量读入时,用此行代码可以使cin更快。为什么cin比scanf更慢呢?标准C++流与标准C流在每次输入/输出操作后同步,同步的C++流为无缓冲,而每次C++流上......
  • ios17如何更新
    相信大家已经迫不及待的想要更新ios17了吧,ios17拥有更多的功能可以给我们使用,今天我们就来看一下如何更新ios17版本,下面跟着步骤一起做就好了。ios17如何更新:1、首先我们打开手机的设置。2、然后我们在设置中找到通用。3、接着我们就可以找到软件更新。4、最后手机就可以自......