From 86f07b8e7c61e2433fbec1945330d288d265109d Mon Sep 17 00:00:00 2001 From: Ivan Zinovyev Date: Sun, 4 Nov 2018 08:28:50 +0300 Subject: [PATCH] Add AccurateCellHeightCalculator --- Sources/AccurateCellHeightCalculator.swift | 45 ++++++++++++++++++++++ TableKit.xcodeproj/project.pbxproj | 4 ++ 2 files changed, 49 insertions(+) create mode 100644 Sources/AccurateCellHeightCalculator.swift diff --git a/Sources/AccurateCellHeightCalculator.swift b/Sources/AccurateCellHeightCalculator.swift new file mode 100644 index 0000000..e266790 --- /dev/null +++ b/Sources/AccurateCellHeightCalculator.swift @@ -0,0 +1,45 @@ +import UIKit + +class AccurateCellHeightCalculator: RowHeightCalculator { + + private(set) weak var tableView: UITableView? + private var prototypes = [String: UITableViewCell]() + private var cachedHeights = [Int: CGFloat]() + + public init(tableView: UITableView?) { + self.tableView = tableView + } + + open func height(forRow row: Row, at indexPath: IndexPath) -> CGFloat { + + guard let tableView = tableView else { return 0 } + + let hash = row.hashValue ^ Int(tableView.bounds.size.width).hashValue + + if let height = cachedHeights[hash] { + return height + } + + var prototypeCell = prototypes[row.reuseIdentifier] + if prototypeCell == nil { + + prototypeCell = tableView.dequeueReusableCell(withIdentifier: row.reuseIdentifier) + prototypes[row.reuseIdentifier] = prototypeCell + } + + guard let cell = prototypeCell else { return 0 } + let height = row.height(for: cell) + + cachedHeights[hash] = height + + return height + } + + open func estimatedHeight(forRow row: Row, at indexPath: IndexPath) -> CGFloat { + return height(forRow: row, at: indexPath) + } + + open func invalidate() { + cachedHeights.removeAll() + } +} diff --git a/TableKit.xcodeproj/project.pbxproj b/TableKit.xcodeproj/project.pbxproj index 9afc02f..b30ee04 100644 --- a/TableKit.xcodeproj/project.pbxproj +++ b/TableKit.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 320C5280218EB9A7004EAD1C /* AccurateCellHeightCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 320C527F218EB9A7004EAD1C /* AccurateCellHeightCalculator.swift */; }; 50CF6E6B1D6704FE004746FF /* TableCellRegisterer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */; }; 50E858581DB153F500A9AA55 /* TableKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E858571DB153F500A9AA55 /* TableKit.swift */; }; DA9EA7AF1D0EC2C90021F650 /* ConfigurableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */; }; @@ -32,6 +33,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 320C527F218EB9A7004EAD1C /* AccurateCellHeightCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccurateCellHeightCalculator.swift; sourceTree = ""; }; 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableCellRegisterer.swift; sourceTree = ""; }; 50E858571DB153F500A9AA55 /* TableKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableKit.swift; sourceTree = ""; }; DA9EA7561D0B679A0021F650 /* TableKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TableKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -100,6 +102,7 @@ DA9EA7A71D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift */, DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */, DA9EA7A81D0EC2C90021F650 /* Operators.swift */, + 320C527F218EB9A7004EAD1C /* AccurateCellHeightCalculator.swift */, ); path = Sources; sourceTree = ""; @@ -233,6 +236,7 @@ 50CF6E6B1D6704FE004746FF /* TableCellRegisterer.swift in Sources */, DA9EA7AF1D0EC2C90021F650 /* ConfigurableCell.swift in Sources */, DA9EA7B31D0EC2C90021F650 /* TableDirector.swift in Sources */, + 320C5280218EB9A7004EAD1C /* AccurateCellHeightCalculator.swift in Sources */, DA9EA7B71D0EC2C90021F650 /* TableSection.swift in Sources */, DA9EA7B01D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift in Sources */, DA9EA7B51D0EC2C90021F650 /* TableRowAction.swift in Sources */,