feat: make diffable data source works with category picker

This commit is contained in:
CMK 2021-03-06 14:46:04 +08:00
parent 8568debab0
commit 893dc2a668
8 changed files with 64 additions and 145 deletions

View File

@ -25,6 +25,22 @@ extension CategoryPickerSection {
cell.categoryView.titleLabel.font = .systemFont(ofSize: 28)
}
cell.categoryView.titleLabel.text = item.title
cell.observe(\.isSelected, options: [.initial, .new]) { cell, _ in
if cell.isSelected {
cell.categoryView.bgView.backgroundColor = Asset.Colors.lightBrandBlue.color
cell.categoryView.bgView.applyShadow(color: Asset.Colors.lightBrandBlue.color, alpha: 1, x: 0, y: 0, blur: 4.0)
if case .all = item {
cell.categoryView.titleLabel.textColor = Asset.Colors.lightWhite.color
}
} else {
cell.categoryView.bgView.backgroundColor = Asset.Colors.lightWhite.color
cell.categoryView.bgView.applyShadow(color: Asset.Colors.lightBrandBlue.color, alpha: 0, x: 0, y: 0, blur: 0.0)
if case .all = item {
cell.categoryView.titleLabel.textColor = Asset.Colors.lightBrandBlue.color
}
}
}
.store(in: &cell.observations)
return cell
}
}

View File

@ -21,16 +21,18 @@ extension PickServerSection {
static func tableViewDiffableDataSource(
for tableView: UITableView,
dependency: NeedsDependency,
pickServerCategoriesCellDelegate: PickServerCategoriesCellDelegate,
pickServerSearchCellDelegate: PickServerSearchCellDelegate,
pickServerCellDelegate: PickServerCellDelegate
) -> UITableViewDiffableDataSource<PickServerSection, PickServerItem> {
UITableViewDiffableDataSource(tableView: tableView) { [weak pickServerSearchCellDelegate, weak pickServerCellDelegate] tableView, indexPath, item -> UITableViewCell? in
UITableViewDiffableDataSource(tableView: tableView) { [weak pickServerCategoriesCellDelegate, weak pickServerSearchCellDelegate, weak pickServerCellDelegate] tableView, indexPath, item -> UITableViewCell? in
switch item {
case .header:
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PickServerTitleCell.self), for: indexPath) as! PickServerTitleCell
return cell
case .categoryPicker(let items):
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PickServerCategoriesCell.self), for: indexPath) as! PickServerCategoriesCell
cell.delegate = pickServerCategoriesCellDelegate
cell.diffableDataSource = CategoryPickerSection.collectionViewDiffableDataSource(
for: cell.collectionView,
dependency: dependency
@ -48,19 +50,6 @@ extension PickServerSection {
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PickServerCell.self), for: indexPath) as! PickServerCell
PickServerSection.configure(cell: cell, server: server, attribute: attribute)
cell.delegate = pickServerCellDelegate
// cell.server = server
// if expandServerDomainSet.contains(server.domain) {
// cell.mode = .expand
// } else {
// cell.mode = .collapse
// }
// if server == viewModel.selectedServer.value {
// tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
// } else {
// tableView.deselectRow(at: indexPath, animated: false)
// }
//
// cell.delegate = self
return cell
}
}

View File

@ -9,16 +9,17 @@ import UIKit
class PickServerCategoryCollectionViewCell: UICollectionViewCell {
var observations = Set<NSKeyValueObservation>()
var categoryView: PickServerCategoryView = {
let view = PickServerCategoryView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override var isSelected: Bool {
didSet {
categoryView.selected = isSelected
}
override func prepareForReuse() {
super.prepareForReuse()
observations.removeAll()
}
override init(frame: CGRect) {

View File

@ -122,6 +122,7 @@ extension MastodonPickServerViewController {
viewModel.setupDiffableDataSource(
for: tableView,
dependency: self,
pickServerCategoriesCellDelegate: self,
pickServerSearchCellDelegate: self,
pickServerCellDelegate: self
)
@ -398,6 +399,28 @@ extension MastodonPickServerViewController: UITableViewDelegate {
viewModel.selectedServer.send(nil)
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let diffableDataSource = viewModel.diffableDataSource else { return }
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
switch item {
case .categoryPicker:
guard let cell = cell as? PickServerCategoriesCell else { return }
guard let diffableDataSource = cell.diffableDataSource else { return }
let snapshot = diffableDataSource.snapshot()
let item = viewModel.selectCategoryItem.value
guard let section = snapshot.indexOfSection(.main),
let row = snapshot.indexOfItem(item) else { return }
cell.collectionView.selectItem(at: IndexPath(item: row, section: section), animated: false, scrollPosition: .centeredHorizontally)
case .search:
guard let cell = cell as? PickServerSearchCell else { return }
cell.searchTextField.text = viewModel.searchText.value
default:
break
}
}
}
extension MastodonPickServerViewController {
@ -409,38 +432,15 @@ extension MastodonPickServerViewController {
emptyStateView.topPaddingViewTopLayoutConstraint.constant = rectInTableView.maxY
}
}
//extension MastodonPickServerViewController: UITableViewDataSource {
// func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//
// let section = Self.Section.allCases[indexPath.section]
// switch section {
// case .title:
//
// case .categories:
//
// case .search:
//
// case .serverList:
// let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PickServerCell.self), for: indexPath) as! PickServerCell
// let server = viewModel.servers.value[indexPath.row]
// // cell.server = server
//// if expandServerDomainSet.contains(server.domain) {
//// cell.mode = .expand
//// } else {
//// cell.mode = .collapse
//// }
// if server == viewModel.selectedServer.value {
// tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
// } else {
// tableView.deselectRow(at: indexPath, animated: false)
// }
//
// cell.delegate = self
// return cell
// }
// }
//}
// MARK: - PickServerCategoriesCellDelegate
extension MastodonPickServerViewController: PickServerCategoriesCellDelegate {
func pickServerCategoriesCell(_ cell: PickServerCategoriesCell, collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let diffableDataSource = cell.diffableDataSource else { return }
let item = diffableDataSource.itemIdentifier(for: indexPath)
viewModel.selectCategoryItem.value = item ?? .all
}
}
// MARK: - PickServerSearchCellDelegate
extension MastodonPickServerViewController: PickServerSearchCellDelegate {
@ -465,41 +465,7 @@ extension MastodonPickServerViewController: PickServerCellDelegate {
// expand attribute change do not needs apply snapshot to diffable data source
// but should I block the viewModel data binding during tableView.beginUpdates/endUpdates?
}
// func pickServerCell(modeChange server: Mastodon.Entity.Server, newMode: PickServerCell.Mode, updates: (() -> Void)) {
// if newMode == .collapse {
// expandServerDomainSet.remove(server.domain)
// } else {
// expandServerDomainSet.insert(server.domain)
// }
//
// tableView.beginUpdates()
// updates()
// tableView.endUpdates()
//
// if newMode == .expand, let modeChangeIndex = self.viewModel.servers.value.firstIndex(where: { $0 == server }), self.tableView.indexPathsForVisibleRows?.last?.row == modeChangeIndex {
// self.tableView.scrollToRow(at: IndexPath(row: modeChangeIndex, section: 3), at: .bottom, animated: true)
// }
// }
}
//extension MastodonPickServerViewController: PickServerCategoriesDataSource, PickServerCategoriesCellDelegate {
// func numberOfCategories() -> Int {
// return viewModel.categories.count
// }
//
// func category(at index: Int) -> MastodonPickServerViewModel.Category {
// return viewModel.categories[index]
// }
//
// func selectedIndex() -> Int {
// return viewModel.selectCategoryIndex.value
// }
//
// func pickServerCategoriesCell(_ cell: PickServerCategoriesCell, didSelect index: Int) {
// return viewModel.selectCategoryIndex.send(index)
// }
//}
// MARK: - OnboardingViewControllerAppearance
extension MastodonPickServerViewController: OnboardingViewControllerAppearance { }

View File

@ -12,12 +12,14 @@ extension MastodonPickServerViewModel {
func setupDiffableDataSource(
for tableView: UITableView,
dependency: NeedsDependency,
pickServerCategoriesCellDelegate: PickServerCategoriesCellDelegate,
pickServerSearchCellDelegate: PickServerSearchCellDelegate,
pickServerCellDelegate: PickServerCellDelegate
) {
diffableDataSource = PickServerSection.tableViewDiffableDataSource(
for: tableView,
dependency: dependency,
pickServerCategoriesCellDelegate: pickServerCategoriesCellDelegate,
pickServerSearchCellDelegate: pickServerSearchCellDelegate,
pickServerCellDelegate: pickServerCellDelegate
)

View File

@ -89,9 +89,11 @@ extension PickServerCategoriesCell {
// MARK: - UICollectionViewDelegateFlowLayout
extension PickServerCategoriesCell: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: indexPath: %s", ((#file as NSString).lastPathComponent), #line, #function, indexPath.debugDescription)
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .centeredHorizontally)
// delegate.pickServerCategoriesCell(self, didSelect: indexPath.row)
delegate?.pickServerCategoriesCell(self, collectionView: collectionView, didSelectItemAt: indexPath)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
@ -106,27 +108,5 @@ extension PickServerCategoriesCell: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 60, height: 80)
}
}
//extension PickServerCategoriesCell: UICollectionViewDataSource {
// func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// return dataSource.numberOfCategories()
// }
//
// func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// let category = dataSource.category(at: indexPath.row)
// let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: PickServerCategoryCollectionViewCell.self), for: indexPath) as! PickServerCategoryCollectionViewCell
// cell.category = category
//
// // Select the default category by default
// if indexPath.row == dataSource.selectedIndex() {
// // Use `[]` as the scrollPosition to avoid contentOffset change
// collectionView.selectItem(at: indexPath, animated: false, scrollPosition: [])
// cell.isSelected = true
// }
// return cell
// }
//
//
//}

View File

@ -38,7 +38,7 @@ class PickServerSearchCell: UITableViewCell {
return view
}()
private var searchTextField: UITextField = {
let searchTextField: UITextField = {
let textField = UITextField()
textField.translatesAutoresizingMaskIntoConstraints = false
textField.font = .preferredFont(forTextStyle: .headline)

View File

@ -9,16 +9,6 @@ import UIKit
import MastodonSDK
class PickServerCategoryView: UIView {
// var category: MastodonPickServerViewModel.Category? {
// didSet {
// updateCategory()
// }
// }
var selected: Bool = false {
didSet {
// updateSelectStatus()
}
}
var bgShadowView: UIView = {
let view = UIView()
@ -53,6 +43,7 @@ class PickServerCategoryView: UIView {
}
extension PickServerCategoryView {
private func configure() {
addSubview(bgView)
addSubview(titleLabel)
@ -70,32 +61,6 @@ extension PickServerCategoryView {
])
}
// private func updateCategory() {
// guard let category = category else { return }
// titleLabel.text = category.title
// switch category {
// case .all:
// titleLabel.font = UIFont.systemFont(ofSize: 17)
// case .some:
// titleLabel.font = UIFont.systemFont(ofSize: 28)
// }
// }
//
// private func updateSelectStatus() {
// if selected {
// bgView.backgroundColor = Asset.Colors.lightBrandBlue.color
// bgView.applyShadow(color: Asset.Colors.lightBrandBlue.color, alpha: 1, x: 0, y: 0, blur: 4.0)
// if case .all = category {
// titleLabel.textColor = Asset.Colors.lightWhite.color
// }
// } else {
// bgView.backgroundColor = Asset.Colors.lightWhite.color
// bgView.applyShadow(color: Asset.Colors.lightBrandBlue.color, alpha: 0, x: 0, y: 0, blur: 0.0)
// if case .all = category {
// titleLabel.textColor = Asset.Colors.lightBrandBlue.color
// }
// }
// }
}
#if DEBUG && canImport(SwiftUI)