From 4a4bdb0738c83eb9f8122ad9a0315cf6e4da888b Mon Sep 17 00:00:00 2001 From: Dylan Nagler Date: Tue, 9 Apr 2024 21:24:47 -0400 Subject: [PATCH] In UIViewLazyList's UITableView, adding special-case handling for programmatic scroll-to-top calls (#1944) --- CHANGELOG.md | 2 +- .../lazylayout/uiview/UIViewLazyList.kt | 26 ++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6106d3ad26..6b7ffeec11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ New: - Nothing yet! Changed: -- Nothing yet! +- In `UIViewLazyList`'s `UITableView`, adding special-case handling for programmatic scroll-to-top calls. Fixed: - Work around a problem with our memory-leak fix where our old LazyList code would crash when its placeholders were unexpectedly removed. diff --git a/redwood-lazylayout-uiview/src/commonMain/kotlin/app/cash/redwood/lazylayout/uiview/UIViewLazyList.kt b/redwood-lazylayout-uiview/src/commonMain/kotlin/app/cash/redwood/lazylayout/uiview/UIViewLazyList.kt index f988d36293..4afe75237f 100644 --- a/redwood-lazylayout-uiview/src/commonMain/kotlin/app/cash/redwood/lazylayout/uiview/UIViewLazyList.kt +++ b/redwood-lazylayout-uiview/src/commonMain/kotlin/app/cash/redwood/lazylayout/uiview/UIViewLazyList.kt @@ -37,6 +37,8 @@ import kotlinx.cinterop.CValue import kotlinx.cinterop.ObjCClass import kotlinx.cinterop.convert import kotlinx.cinterop.readValue +import kotlinx.cinterop.useContents +import platform.CoreGraphics.CGPoint import platform.CoreGraphics.CGRect import platform.CoreGraphics.CGRectZero import platform.CoreGraphics.CGSize @@ -56,17 +58,29 @@ import platform.UIKit.UITableViewDataSourceProtocol import platform.UIKit.UITableViewDelegateProtocol import platform.UIKit.UITableViewRowAnimationNone import platform.UIKit.UITableViewScrollPosition +import platform.UIKit.UITableViewStyle import platform.UIKit.UIView import platform.UIKit.indexPathForItem import platform.UIKit.item import platform.darwin.NSInteger import platform.darwin.NSObject -internal open class UIViewLazyList( - internal val tableView: UITableView = UITableView( +internal open class UIViewLazyList() : LazyList, ChangeListener { + internal val tableView: UITableView = object : UITableView( CGRectZero.readValue(), - ), -) : LazyList, ChangeListener { + UITableViewStyle.UITableViewStylePlain, + ) { + override fun setContentOffset(contentOffset: CValue, animated: Boolean) { + // If the caller is requesting a contentOffset with y == 0, + // and the current contentOffset.y is not 0, + // assume that it's a programmatic scroll-to-top call. + if (contentOffset.useContents { y } == 0.0 && this.contentOffset.useContents { y } != 0.0) { + isDoingProgrammaticScroll = true + } + super.setContentOffset(contentOffset, animated) + } + } + override var modifier: Modifier = Modifier override val value: UIView @@ -185,6 +199,10 @@ internal open class UIViewLazyList( override fun scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) { isDoingProgrammaticScroll = false } + + override fun scrollViewDidScrollToTop(scrollView: UIScrollView) { + isDoingProgrammaticScroll = false + } } init {