From 90de95cc4e84f42bf90a5e4c4454aa88bb90e0ca Mon Sep 17 00:00:00 2001 From: pkurchatov Date: Wed, 5 Oct 2022 17:08:30 +0300 Subject: [PATCH] added state change support in DivKitSample --- .../ios/Sample/DivKitSample/DivHostView.swift | 66 ++++++++++++++----- .../DivKitSample/DivHostViewController.swift | 6 +- client/ios/Sample/DivKitSample/div_json.json | 2 +- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/client/ios/Sample/DivKitSample/DivHostView.swift b/client/ios/Sample/DivKitSample/DivHostView.swift index 2d5c7b1a9..253a0e8d1 100644 --- a/client/ios/Sample/DivKitSample/DivHostView.swift +++ b/client/ios/Sample/DivKitSample/DivHostView.swift @@ -6,7 +6,7 @@ import LayoutKit final class DivHostView: UICollectionView { private let components: DivKitComponents - private var blocks: [Block] = [] + private var items: [Item] = [] init(components: DivKitComponents) { self.components = components @@ -24,22 +24,46 @@ final class DivHostView: UICollectionView { fatalError("init(coder:) has not been implemented") } - func setCards(_ cards: [DivData]) { - self.blocks = cards.compactMap { card in - let context = components.makeContext( - cardId: DivCardID(rawValue: card.logId), - cachedImageHolders: [] - ) - return try? card.makeBlock(context: context) + func setData(_ items: [DivData]) { + self.items = items.compactMap { makeItem(data: $0) } + } + + func reloadItem(cardId: String) { + guard let index = items.firstIndex(where: { $0.data.logId == cardId }) else { + return } + + let item = items[index] + items[index] = makeItem( + data: item.data, + cachedImageHolders: item.block.getImageHolders() + ) + + reloadItems(at: [IndexPath(item: index, section: 0)]) } + private func makeItem( + data: DivData, + cachedImageHolders: [ImageHolder] = [] + ) -> Item { + let context = components.makeContext( + cardId: DivCardID(rawValue: data.logId), + cachedImageHolders: cachedImageHolders + ) + return Item(data: data, block: try! data.makeBlock(context: context)) + } + + private struct Item { + let data: DivData + let block: Block + } + private class Cell: UICollectionViewCell { static let reuseIdentifier = "cell" struct State { - var block: Block - var view: BlockView + let block: Block + let view: BlockView } var state: State? @@ -66,21 +90,31 @@ final class DivHostView: UICollectionView { } extension DivHostView: UICollectionViewDataSource { - func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - return blocks.count + func collectionView( + _ collectionView: UICollectionView, + numberOfItemsInSection section: Int + ) -> Int { + return items.count } - func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + func collectionView( + _ collectionView: UICollectionView, + cellForItemAt indexPath: IndexPath + ) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Cell.reuseIdentifier, for: indexPath) as! Cell - let block = blocks[indexPath.row] + let block = items[indexPath.row].block cell.setBlock(block) return cell } } extension DivHostView: UICollectionViewDelegateFlowLayout { - func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { - let block = blocks[indexPath.row] + func collectionView( + _ collectionView: UICollectionView, + layout collectionViewLayout: UICollectionViewLayout, + sizeForItemAt indexPath: IndexPath + ) -> CGSize { + let block = items[indexPath.row].block let height = block.heightOfVerticallyNonResizableBlock(forWidth: bounds.width) return CGSize(width: bounds.width, height: height) } diff --git a/client/ios/Sample/DivKitSample/DivHostViewController.swift b/client/ios/Sample/DivKitSample/DivHostViewController.swift index 75b25a950..eb919d2f1 100644 --- a/client/ios/Sample/DivKitSample/DivHostViewController.swift +++ b/client/ios/Sample/DivKitSample/DivHostViewController.swift @@ -2,9 +2,8 @@ import UIKit import DivKit import LayoutKit -import Serialization -class DivHostViewController: UIViewController { +final class DivHostViewController: UIViewController { private var divHostView: DivHostView! private var components: DivKitComponents! @@ -18,7 +17,7 @@ class DivHostViewController: UIViewController { if let cards = try? DivJson.loadCards() { view.addSubview(divHostView) - divHostView.setCards(cards) + divHostView.setData(cards) } } @@ -33,6 +32,7 @@ extension DivHostViewController: UIActionEventPerforming { switch event.payload { case let .divAction(params): components.handleActions(params: params) + divHostView.reloadItem(cardId: params.cardId) case .empty, .url, .menu, diff --git a/client/ios/Sample/DivKitSample/div_json.json b/client/ios/Sample/DivKitSample/div_json.json index ed0d6a44f..e20470f13 100644 --- a/client/ios/Sample/DivKitSample/div_json.json +++ b/client/ios/Sample/DivKitSample/div_json.json @@ -241,7 +241,7 @@ "avatar": "https://habrastorage.org/r/w32/getpro/habr/avatars/ba8/258/251/ba825825164ffb969217c5bd71ebcc3e.png", "username": "danis_gaiazov", "time": "6 июля в 10:59", - "title": "Как люди помогают технологиям в Яндекс Картах\n", + "title": "Как люди помогают технологиям в Яндекс Картах", "votes": "+20", "comments": "19 +19", "views": "4.7K",