_adjustContentOffsetIfNecessary - UIScrollView 自动滚动到顶部
Posted
技术标签:
【中文标题】_adjustContentOffsetIfNecessary - UIScrollView 自动滚动到顶部【英文标题】:_adjustContentOffsetIfNecessary - UIScrollView automatically scrolls to top 【发布时间】:2014-05-23 07:58:02 【问题描述】:在 ios 7 上。 我有导航控制器,并在堆栈顶部推送了一个新的 VC。
那个新的 VC 有一个 UIScrollView 填充 VC 的根视图并垂直滚动。如果我向下滚动一点,然后尝试使用“滑动返回”/“滑动弹出”手势,垂直滚动视图首先滚动到顶部,然后识别 interactivePopGesture,我可以拖动顶部的 VC左右堆叠。
为什么会这样? 我希望防止我的滚动视图在识别“滑动返回”手势之前自动滚动到顶部。 我该怎么做?
更新#1:
当我创建一个新的 xcode 项目时,我似乎无法重现这个错误,所以这肯定是我在原始项目中的错误。找到原因后会更新。
更新 #2:
当 interactivePopGesture 被识别时,setContentOffset
方法在我的垂直滚动视图上被调用。在调试时,我看到setContentOffset
是从UIScrollViewInternal _adjustContentOffsetIfNecessary
调用的。
更新 #3:
同样的问题发生在以下场景中:
我在垂直 UIScrollView 中有 UITextFields。当按下某个 UITextField 时,会出现一个键盘。当我想以交互方式关闭键盘时(通过在键盘上拖动滚动视图),在我释放拖动后,会发生故障。 UIScrollView 的内容偏移量暂时设置为零,然后设置回原始内容偏移量并继续动画。 contentOffset
这个不需要的设置也被UIScrollViewInternal _adjustContentOffsetIfNecessary
调用。
我继续用我自己的 UIScrollView 子类替换了这两种情况下的 UIScrollView。在该子类中,我将私有方法 -(void) _adjustContentOffsetIfNecessary
重写为空的 void 方法。我的两个问题都解决了,我找不到任何负面后果。这不是一个解决方案,我不会使用这种方法,因为我不知道我到底做了什么。
【问题讨论】:
可能与iOS7上UIViewController的setAutomaticallyAdjustsScrollViewInsets api有关 我自动设置AdjustsScrollViewInsets = NO;在我认为可能与情况相关的每个视图控制器上。它没有帮助。 我也遇到了这个问题。我手动将 contentOffset 设置为 (0,-64),但 _adjustContentOffsetIfNecessary 再次将其更改为 -108。使困惑。有更新吗? 不,还没有更新...如果我有时间,我会尝试在示例应用程序中重新创建问题,然后在此处发布指向 git 存储库的链接... 你解决了这个问题了吗?我在使用自动布局时也遇到了这个问题... 【参考方案1】:我在 Twitter 上找到了一个关于此的 interesting discussion。虽然这不是我的情况,但它可能会对某人有所帮助:
Is there some trick to bring UINavigationController to not mess with a UIScrollView (_adjustContentOffsetIfNecessary)?
@steipete Searching for the same thing and came across your tweet. I set contentOffset but it resets back to -64 (ios7). Did you find a fix?
@errthling Add a dummy view as first subview. It won’t look further.
@steipete Wow – that worked. I've been struggling with it for days. Thanks for that and everything else you put out there! :)
@errthling happy to help!
@steipete did you find an answer to this, 2 years ago? =D my scrollview's contentOffset is reset when I push a new viewcontroller..
@manuelmaly Yeah. Changed the view hierarchy so the scroll view is not the main view and not the first subview, and UIKit stops messing.
@steipete oO i hacked it in the meantime by blocking setContentOffset before pushViewController is called. your solution seems cleaner tho
【讨论】:
这似乎不适用于 iOS 12.3。尝试在 UICollectionView 周围的所有位置添加虚拟视图(这样它就不是主要的,也不是第一个,不是最后一个,...),但是每次重新加载 collectionView 时都会调用 _adjustContentOffsetIfNecessary。【参考方案2】:我在 iOS 14 中遇到了同样的问题。看起来没有正常的方法来阻止_adjustContentOffsetIfNecessary
的调用。在问题视图中覆盖 didMoveToWindow()
对我有帮助
override func didMoveToWindow()
super.didMoveToWindow()
// window == nil when new screen pushed
if window == nil
// Set correct offset that was before
【讨论】:
或者您可以覆盖 contentOffset 属性保护窗口!= nil else return super.contentOffset = newValue @clatt 是的,如果你已经使用了继承 UIScrollView 的类,那也可以。我提供的解决方案允许使用标准 UIScrollView 并在指定的 UIView 元素中定义偏移行为【参考方案3】:将 UIViewController 与 UITableView 一起使用,而不是 UITableViewController。它解决了我的问题:)
【讨论】:
以上是关于_adjustContentOffsetIfNecessary - UIScrollView 自动滚动到顶部的主要内容,如果未能解决你的问题,请参考以下文章