IGListKit, Instagram . . ViewController. . , , .
IGListKit
IGListKit UICollectionView. :
- ;
- ViewController;
- UICollectionViewCell.
, :
- SectionController – ;
- SectionControllerModel – ;
- UICollectionViewCellModel – , .
.
, , . , IGListKit Objective-C.
final class Company {
let id: String
let title: String
let logo: UIImage
let logoSymbol: UIImage
var isExpanded: Bool = false
init(id: String, title: String, logo: UIImage, logoSymbol: UIImage) {
self.id = id
self.title = title
self.logo = logo
self.logoSymbol = logoSymbol
}
}
ListDiffable.
extension Company: ListDiffable {
func diffIdentifier() -> NSObjectProtocol {
return id as NSObjectProtocol
}
func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
guard let object = object as? Company else { return false }
return id == object.id
}
}
ListDiffable , UICollectionView.
:
func diffIdentifier() -> NSObjectProtocol
, .
func isEqual(toDiffableObject object: ListDiffable?) -> Bool
.
IGListKit SectionController. , . .
. , ExpandingCell. IGListKit ListBindable.
extension ExpandingCell: ListBindable {
func bindViewModel(_ viewModel: Any) {
guard let model = viewModel as? ExpandingCellModel else { return }
logoImageView.image = model.logo
titleLable.text = model.title
upDownImageView.image = model.isExpanded
? UIImage(named: "up")
: UIImage(named: "down")
}
}
func bindViewModel(_ viewModel: Any). .
– SectionController
, , . SectionController.
final class InfoSectionController: ListBindingSectionController<ListDiffable> {
weak var delegate: InfoSectionControllerDelegate?
override init() {
super.init()
dataSource = self
}
}
ListBindingSectionController<ListDiffable>
, SectionController , ListDiffable.
SectionController ListBindingSectionControllerDataSource.
extension InfoSectionController: ListBindingSectionControllerDataSource {
func sectionController(_ sectionController: ListBindingSectionController<ListDiffable>, viewModelsFor object: Any) -> [ListDiffable] {
guard let sectionModel = object as? InfoSectionModel else {
return []
}
var models = [ListDiffable]()
for item in sectionModel.companies {
models.append(
ExpandingCellModel(
identifier: item.id,
isExpanded: item.isExpanded,
title: item.title,
logo: item.logoSymbol
)
)
if item.isExpanded {
models.append(
ImageCellModel(logo: item.logo)
)
}
}
return models
}
func sectionController(_ sectionController: ListBindingSectionController<ListDiffable>, cellForViewModel viewModel: Any, at index: Int) -> UICollectionViewCell & ListBindable {
let cell = self.cell(for: viewModel, at: index)
return cell
}
func sectionController(_ sectionController: ListBindingSectionController<ListDiffable>, sizeForViewModel viewModel: Any, at index: Int) -> CGSize {
let width = collectionContext?.containerSize.width ?? 0
var height: CGFloat
switch viewModel {
case is ExpandingCellModel:
height = 60
case is ImageCellModel:
height = 70
default:
height = 0
}
return CGSize(width: width, height: height)
}
}
3 :
func sectionController(_ sectionController: ListBindingSectionController<ListDiffable>, viewModelsFor object: Any) -> [ListDiffable]
UICollectionView.
func sectionController(_ sectionController: ListBindingSectionController<ListDiffable>, cellForViewModel viewModel: Any, at index: Int) -> UICollectionViewCell & ListBindable
. , .
func sectionController(_ sectionController: ListBindingSectionController<ListDiffable>, sizeForViewModel viewModel: Any, at index: Int) -> CGSize
.
ViewController
ViewController ListAdapter , . ListAdapter UICollectionView .
class ViewController: UIViewController {
var companies: [Company]
private lazy var adapter = {
ListAdapter(updater: ListAdapterUpdater(), viewController: self)
}()
required init?(coder: NSCoder) {
self.companies = [
Company(
id: "ss",
title: "SimbirSoft",
logo: UIImage(named: "ss_text")!,
logoSymbol: UIImage(named: "ss_symbol")!
),
Company(
id: "mobile-ss",
title: "mobile SimbirSoft",
logo: UIImage(named: "mobile_text")!,
logoSymbol: UIImage(named: "mobile_symbol")!
)
]
super.init(coder: coder)
}
override func viewDidLoad() {
super.viewDidLoad()
configureCollectionView()
}
private func configureCollectionView() {
adapter.collectionView = collectionView
adapter.dataSource = self
}
}
ViewController ListAdapterDataSource.
extension ViewController: ListAdapterDataSource {
func objects(for listAdapter: ListAdapter) -> [ListDiffable] {
return [
InfoSectionModel(companies: companies)
]
}
func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController {
let sectionController = InfoSectionController()
return sectionController
}
func emptyView(for listAdapter: ListAdapter) -> UIView? {
return nil
}
}
3 :
func objects(for listAdapter: ListAdapter) -> [ListDiffable]
SectionController.
func listAdapter(_ listAdapter: ListAdapter, sectionControllerFor object: Any) -> ListSectionController
SectionController.
func emptyView(for listAdapter: ListAdapter) -> UIView?
, , .
– UICollectionView . , , .
SectionController ListBindingSectionControllerSelectionDelegate .
dataSource = self
extension InfoSectionController: ListBindingSectionControllerSelectionDelegate {
func sectionController(_ sectionController: ListBindingSectionController<ListDiffable>, didSelectItemAt index: Int, viewModel: Any) {
guard let cellModel = viewModel as? ExpandingCellModel
else {
return
}
delegate?.sectionControllerDidTapField(cellModel)
}
}
:
func sectionController(_ sectionController: ListBindingSectionController<ListDiffable>, didSelectItemAt index: Int, viewModel: Any)
.
protocol InfoSectionControllerDelegate: class {
func sectionControllerDidTapField(_ field: ExpandingCellModel)
}
ViewController ExpandingCellModel Company isOpened. UICollectionView, SectionController :
func sectionController(_ sectionController: ListBindingSectionController<ListDiffable>, viewModelsFor object: Any) -> [ListDiffable]
extension ViewController: InfoSectionControllerDelegate {
func sectionControllerDidTapField(_ field: ExpandingCellModel) {
guard let company = companies.first(where: { $0.id == field.identifier })
else { return }
company.isExpanded.toggle()
adapter.performUpdates(animated: true, completion: nil)
}
}
IGListKit . , :
- ;
- ViewController, ;
- .
! .
gif