forked from zelo72/mastodon-ios
feat: make diffable data source works with category picker
This commit is contained in:
parent
8568debab0
commit
893dc2a668
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 { }
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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
|
||||
// }
|
||||
//
|
||||
//
|
||||
//}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
@ -69,33 +60,7 @@ extension PickServerCategoryView {
|
|||
titleLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor),
|
||||
])
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
|
Loading…
Reference in New Issue