TableViewLiaison 2.0.1

TableViewLiaison 2.0.1

Dylan ShineDylan Shine 维护。



  • 作者
  • Dylan Shine

Build Status Pods Version


UITableView 简化了!🙌

主要功能
🙉 跳过 UITableViewDataSourceUITableViewDelegate 的样板代码,直接构建您的 UITableView
🌀 基于闭包的 API 用于分区和行配置
📄 内建分页功能
单元测试
🐤 使用 Swift 5.0 编写

TableViewLiaison🔨❤️📱 @ Shine Labs 设计。

需求

  • Xcode 10.2+
  • iOS 10.0+

安装

CocoaPods

首选安装方法是使用 CocoaPods。将以下内容添加到您的 Podfile 中

pod 'TableViewLiaison'

示例

要运行示例项目,首先克隆仓库,然后在 Example 目录中运行 pod install

使用方法

TableViewLiaison 允许您更轻松地填充和处理 UITableView 的行和部分。

入门

要开始使用,您只需要将一个实例的 UITableView 与一个 TableViewLiaison 进行连接。

let liaison = TableViewLiaison()
let tableView = UITableView()

liaison.liaise(tableView: tableView)

通过将您的 UITableView 连接到 TableViewLiaisonTableViewLiaison 成为它的 UITableViewDataSourceUITableViewDelegateUITableViewDataSourcePrefetching。如果您想从 TableViewLiaison 中移除 UITableView,只需调用 liaison.detach()

TableViewLiaison 实现了多个辅助方法来帮助您管理 UITableView

TableViewLiaison 使用两种主要类型填充部分和行。

部分

struct TableViewSection

为了为我们的 UITableView 创建部分,创建一个 TableViewSection 的实例并将其添加到 TableViewLiaison 中。

let one = TableViewSection()
let two = TableViewSection(id: "ID")


let liaison = TableViewLiaison(sections: [one, two])

或者

let section = TableViewSection()

liaison.append(section: section)

补充部分的视图

为了通知 TableViewLiaison 您的 TableViewSection 将显示头部和/或尾部视图,您必须在初始化期间提供一个 TableViewSectionComponentDisplayOption 实例。

TableViewSectionComponentDisplayOption 是一个枚举,告诉联络器为给定的部分应显示哪些辅助视图。头部/尾部视图由

class TableViewSectionComponent<View: UITableViewHeaderFooterView>

let header = TableViewSectionComponent<UITableViewHeaderFooterView>()
let section = TableViewSection(option: .header(component: header))

您可以通过使用 CGFloat 值或闭包来设置 TableViewSectionComponent 的静态高度

header.set(.height, 55)

header.set(.height) {
	// Some arbitrary user you pass into the closure...
    return user.username == "dylan" ? 100 : 75
}

header.set(.estimatedHeight, 125)

如果未为 TableViewSectionComponent 提供高度,TableViewLiaison 会假定辅助视图是自动大小的,并返回 .heightUITableView.automaticDimension。请确保您提供 .estimatedHeight 以避免布局问题。

可以使用 set(_ command: TableViewSectionComponentCommand, with closure: @escaping (View, Int) -> Void) 在所有以下的生命周期事件中对 TableViewSectionComponent 视图进行自定义

  • 配置
  • didEndDisplaying
  • willDisplay
header.set(.configuration) { view, section in
    view.textLabel?.text = "Section \(section)"
}

header.set(.willDisplay) { view, section in
    print("Header: \(view) will display for Section: \(section)")
}

class TableViewRow>Cell: UITableViewCell, Data

要为某个部分添加行,请创建 TableViewRow 的实例并将其传递给 TableViewSection 的初始化器。如果行在实例化后添加,则可以通过 TableViewLiaison 执行该操作。

let row = TableViewRow<RowTableViewCell, Int>(data: 1)
let statelessRow = StatelessTableViewRow<RowTableViewCell>()
let section = TableViewSection(rows: [row, statelessRow])
liaison.append(section: section)

或者

let row = TableViewRow()
let section = TableViewSection()
liaison.append(section: section)
liaison.append(row: row)

TableViewRow 的高度配置类似于 TableViewSection

row.set(.height, 300)

row.set(.estimatedHeight, 210)

row.set(.height) { data in
	switch data.type {
	case .large:
		return 400
	case .medium:
		return 200
	case .small:
		return 50
	}
}

如果未提供高度,则 TableViewLiaison 假设单元格是自动大小的,并返回 UITableView.automaticDimension

可以使用 func set(_ command: TableViewRowCommand, with closure: @escaping (TableViewLiaison, Cell, Data, IndexPath) -> Void) 在以下所有生命周期事件中自定义 TableViewRow

  • accessoryButtonTapped
  • 配置
  • delete
  • didDeselect
  • didEndDisplaying
  • didEndEditing
  • didHighlight
  • didSelect
  • didUnhighlight
  • insert
  • move
  • reload
  • willBeginEditing
  • willDeselect
  • willDisplay
  • willSelect
row.set(.configuration) { liaison, cell, data, indexPath in
	cell.label.text = "Cell: \(cell) at IndexPath: \(indexPath) with \(data)"
	cell.label.font = .systemFont(ofSize: 13)
	cell.contentView.backgroundColor = .blue
	cell.selectionStyle = .none
}

row.set(.didSelect) { liaison, cell, data, indexPath in
	print("Cell: \(cell) selected at IndexPath: \(indexPath) with \(data)")
}

TableViewRow 还可以通过 func set(prefetchCommand: TableViewPrefetchCommand, with closure: @escaping (IndexPath) -> Void) 使用 UITableViewDataSourcePrefetching

row.set(.prefetch) { cellViewModel, indexPath in
	cellViewModel.downloadImage()
}

row.set(.cancel) { cellViewModel, indexPath in
    cellViewModel.cancelImageDownload()
}

单元格/视图注册

TableViewLiaison 利用你的部分/行 TableViewRegistrationType<T> 代理为你处理单元格和视图的注册,以便在你的 UITableView 视图重用方面。

TableViewRegistrationType 通知代理是否应通过 NibClass 注册可重用的视图。

默认情况下,TableViewRow 使用 TableViewRegistrationType<Cell>.defaultClassType 实例化。

TableViewSection 补充视图注册被封装在其 TableViewSectionComponentDisplayOption 中。默认情况下,TableViewSection 选项使用 .none 实例化。

分页

TableViewLiaison 搭载了处理分页需求的工具。要为分页配置代理,只需将它的 paginationDelegate 设置为 TableViewLiaisonPaginationDelegate 的实例。

TableViewLiaisonPaginationDelegate 声明三个方法

func isPaginationEnabled() -> Bool,通知代理是否在用户滚动到最后一行后显示分页指示器。

func paginationStarted(indexPath: IndexPath),传递经过联络者管理的最后一个TableViewRow的indexPath。

func paginationEnded(indexPath: IndexPath),传递联络者附加的第一个新的TableViewRow的indexPath。

为了在分页期间更新联络者的结果,简单地使用append(sections: [AnyTableViewSection])func append(rows: [AnyTableViewRow]),然后联络者将自动处理分页加载器的移除。

要使用自定义的分页加载器,你可以在初始化你的TableViewLiaison时传递一个AnyTableViewRow实例。默认情况下,它使用框架提供的PaginationTableViewRow

技巧与窍门

由于TableViewSectionTableViewRow使用了泛型类型并管理视图/单元格类型的注册,创建多个不同的配置的章节和行可能会变得冗长。利用类型别名和/或实现静态工厂可能是有用的。

public typealias ImageRow= TableViewRow<ImageTableViewCell, UIImage>

static func imageRow(with image: UIImage) -> AnyTableViewRow {
	let row = ImageRow(data: image)

	row.set(.height, 225)

	row.set(.configuration) { liaison, cell, image, indexPath in
		cell.contentImageView.image = image
		cell.contentImageView.contentMode = .scaleAspectFill
	}

	return row
}

贡献

TableViewLiaison处于初期阶段。它的实现还不够完美。并不是所有的UITableView功能都被liaised。如果你想帮助将TableViewLiaison带到更佳之地,请随意提交拉取请求。

作者

✌️Dylan Shine,[email protected]

授权协议

TableViewLiaison在MIT授权协议下可用。有关更多信息,请参阅LICENSE文件。