fix: update collection view with diffable data source

This commit is contained in:
Nikita Semenov 2022-08-04 16:44:19 +03:00
parent 7c479ff428
commit 0534d41bae
20 changed files with 90 additions and 45 deletions

View File

@ -21,6 +21,7 @@
//
import UIKit
import TIUIKitCore
@available(iOS 13, *)
public extension UICollectionViewLayout {
@ -55,12 +56,3 @@ public extension UICollectionViewLayout {
return UICollectionViewCompositionalLayout(section: section)
}
}
private extension NSDirectionalEdgeInsets {
init(insets: UIEdgeInsets) {
self.init(top: insets.top,
leading: insets.left,
bottom: insets.bottom,
trailing: insets.right)
}
}

View File

@ -20,7 +20,7 @@
// THE SOFTWARE.
//
public struct DefaultFilterModel: FilterRepresenter, Codable {
public struct DefaultFilterModel: FilterRepresenter {
public let id: String
public let property: DefaultFilterPropertyValue?
public let properties: [DefaultFilterPropertyValue]?

View File

@ -22,9 +22,7 @@
import UIKit
public struct DefaultFilterPropertyValue: FilterPropertyValueRepresenter,
Codable,
Identifiable {
public struct DefaultFilterPropertyValue: FilterPropertyValueRepresenter, Identifiable {
public let id: String
public let title: String

View File

@ -23,15 +23,28 @@
import TIUIKitCore
import UIKit
@available(iOS 13.0, *)
open class BaseFiltersCollectionView<CellType: UICollectionViewCell & ConfigurableView>: UICollectionView,
InitializableViewProtocol,
ConfigurableView,
FiltersCollectionHolder where CellType.ViewModelType: FilterCellViewModelProtocol {
FiltersCollectionHolder where CellType.ViewModelType: Hashable {
public enum Section {
case main
}
public typealias DataSource = UICollectionViewDiffableDataSource<Section, CellType.ViewModelType>
public typealias Snapshot = NSDiffableDataSourceSnapshot<Section, CellType.ViewModelType>
public var layout: UICollectionViewLayout
public weak var viewModel: DefaultFiltersViewModel?
public lazy var collectionViewDataSource = createDataSource()
open var cellsReusedIdentifier: String {
"filter-cells-identifier"
}
// MARK: - Init
public init(layout: UICollectionViewLayout, viewModel: DefaultFiltersViewModel? = nil) {
@ -54,8 +67,8 @@ open class BaseFiltersCollectionView<CellType: UICollectionViewCell & Configurab
}
open func bindViews() {
delegate = viewModel
dataSource = viewModel
// delegate = viewModel
// dataSource = viewModel
}
open func configureLayout() {
@ -70,16 +83,8 @@ open class BaseFiltersCollectionView<CellType: UICollectionViewCell & Configurab
// override in subclass
}
// MARK: - ConfigurableView
open func configure(with viewModel: DefaultFiltersViewModel) {
if viewModel == nil {
self.viewModel = viewModel
}
viewModel.filtersCollectionHolder = self
updateView()
open func viewDidLoad() {
register(CellType.self, forCellWithReuseIdentifier: cellsReusedIdentifier)
}
// MARK: - FiltersCollectionHolder
@ -92,10 +97,12 @@ open class BaseFiltersCollectionView<CellType: UICollectionViewCell & Configurab
configure(filterCell: cell, cellViewModel: change.viewModel)
}
applySnapshot()
}
open func updateView() {
reloadData()
applySnapshot()
}
open func configure(filterCell: UICollectionViewCell, cellViewModel: FilterCellViewModelProtocol) {
@ -109,4 +116,30 @@ open class BaseFiltersCollectionView<CellType: UICollectionViewCell & Configurab
open func registerCells() {
viewModel?.filters.forEach { self.register(CellType.self, forCellWithReuseIdentifier: $0.id) }
}
open func applySnapshot() {
guard let viewModel = viewModel else {
return
}
var snapshot = Snapshot()
snapshot.appendSections([.main])
snapshot.appendItems(viewModel.cellsViewModels as! [CellType.ViewModelType], toSection: .main)
collectionViewDataSource.apply(snapshot, animatingDifferences: true)
}
open func createDataSource() -> DataSource {
let cellProvider: DataSource.CellProvider = { [weak self] collectionView, indexPath, itemIdentifier in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self?.cellsReusedIdentifier ?? "",
for: indexPath) as? CellType
cell?.configure(with: itemIdentifier)
return cell
}
return DataSource(collectionView: self, cellProvider: cellProvider)
}
}

View File

@ -22,22 +22,16 @@
import UIKit
import TIUIKitCore
import TIUIElements
open class BaseFilterCollectionCell: ContainerCollectionViewCell<UILabel>,
ConfigurableView {
open class DefaultFilterCollectionCell: ContainerCollectionViewCell<UILabel>,
ConfigurableView {
public var viewModel: DefaultFilterCellViewModel?
open var isLabelHidden: Bool {
get {
wrappedView.isHidden
}
set {
wrappedView.isHidden = newValue
}
}
open override func configureAppearance() {
super.configureAppearance()
layer.round(corners: .allCorners, radius: 6)
}
@ -52,12 +46,6 @@ open class BaseFilterCollectionCell: ContainerCollectionViewCell<UILabel>,
setSelected(isSelected: viewModel.isSelected)
}
// MARK: - ContainerCollectionViewCell
open override func createView() -> UILabel {
UILabel()
}
// MARK: - Public methods
open func setSelected(isSelected: Bool) {

View File

@ -14,4 +14,6 @@ Pod::Spec.new do |s|
s.dependency 'TIFoundationUtils', s.version.to_s
s.dependency 'TINetworking', s.version.to_s
s.dependency 'TIUIKitCore', s.version.to_s
s.dependency 'TIUIElements', version.to_s
end

View File

@ -0,0 +1,32 @@
//
// Copyright (c) 2022 Touch Instinct
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the Software), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
import UIKit
public extension NSDirectionalEdgeInsets {
init(insets: UIEdgeInsets) {
self.init(top: insets.top,
leading: insets.left,
bottom: insets.bottom,
trailing: insets.right)
}
}