Skip to content

Commit 311acab

Browse files
committed
Defer SectionModel calculateElementFramesIfNecessary
1 parent 273ea60 commit 311acab

1 file changed

Lines changed: 21 additions & 4 deletions

File tree

MagazineLayout/LayoutCore/SectionModel.swift

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ struct SectionModel {
3838
numberOfRows = 0
3939

4040
updateIndexOfFirstInvalidatedRowIfNecessary(toProposedIndex: 0)
41-
calculateElementFramesIfNecessary()
41+
42+
if !MagazineLayout._enableExperimentalOptimizations {
43+
calculateElementFramesIfNecessary()
44+
}
4245
}
4346

4447
// MARK: Internal
@@ -257,15 +260,22 @@ struct SectionModel {
257260
}
258261

259262
mutating func removeFooter() -> Bool {
260-
guard let indexOfFooter = indexOfFooterRow() else {
263+
guard footerModel != nil else {
261264
return false
262265
}
263-
updateIndexOfFirstInvalidatedRowIfNecessary(toProposedIndex: indexOfFooter)
266+
// `indexOfFooterRow()` is `nil` if the section hasn't been laid out yet (deferred layout
267+
// calculation). In that case the whole section is already invalidated from row 0, so there's no
268+
// additional row to invalidate.
269+
if let indexOfFooter = indexOfFooterRow() {
270+
updateIndexOfFirstInvalidatedRowIfNecessary(toProposedIndex: indexOfFooter)
271+
}
264272
footerModel = nil
265273
return true
266274
}
267275

268276
mutating func updateItemHeight(toPreferredHeight preferredHeight: CGFloat, atIndex index: Int) {
277+
calculateElementFramesIfNecessary()
278+
269279
// Accessing this array using an unsafe, untyped (raw) pointer avoids expensive copy-on-writes
270280
// and Swift retain / release calls.
271281
itemModels.withUnsafeMutableBufferPointer { directlyMutableItemModels in
@@ -292,6 +302,8 @@ struct SectionModel {
292302
}
293303

294304
mutating func updateHeaderHeight(toPreferredHeight preferredHeight: CGFloat) {
305+
calculateElementFramesIfNecessary()
306+
295307
headerModel?.preferredHeight = preferredHeight
296308

297309
if let indexOfHeaderRow = indexOfHeaderRow(), let headerModel = headerModel {
@@ -312,6 +324,8 @@ struct SectionModel {
312324
}
313325

314326
mutating func updateFooterHeight(toPreferredHeight preferredHeight: CGFloat) {
327+
calculateElementFramesIfNecessary()
328+
315329
footerModel?.preferredHeight = preferredHeight
316330

317331
if let indexOfFooterRow = indexOfFooterRow(), let footerModel = footerModel {
@@ -393,7 +407,10 @@ struct SectionModel {
393407
}
394408

395409
private func indexOfFooterRow() -> Int? {
396-
guard footerModel != nil else { return nil }
410+
// `numberOfRows` is 0 until the section's element frames have been calculated. With deferred
411+
// layout calculation, the footer's row index isn't known yet in that state, so we return `nil`
412+
// rather than a bogus `numberOfRows - 1` (which would be -1).
413+
guard footerModel != nil, numberOfRows > 0 else { return nil }
397414
return numberOfRows - 1
398415
}
399416

0 commit comments

Comments
 (0)