_adjustContentOffsetIfNeeded - UIScrollView автоматически прокручивается вверх

На iOS 7. У меня есть контроллер навигации, и я помещаю новый VC в стек.

Этот новый VC имеет UIScrollView, который заполняет корневой вид VC и прокручивает по вертикали. Если я прокручиваю немного вниз, а затем пытаюсь использовать жест "проведите назад" / "проведите пальцем по всплывающему", вертикальный вид прокрутки сначала прокручивается к вершине, а затем распознается interactivePopGesture, и я могу перетащить верхний ВК на стек влево и вправо.

Почему это происходит? Я хочу, чтобы мой вид прокрутки не прокручивался автоматически до тех пор, пока не будет распознан жест смахивания назад. Как мне это сделать?

ОБНОВЛЕНИЕ № 1:

Кажется, я не могу воспроизвести эту ошибку при создании нового проекта xcode, так что это, безусловно, ошибка с моей стороны в исходном проекте. Обновлю, когда найду причину.

ОБНОВЛЕНИЕ № 2:

Когда InteractivePopGesture распознается, setContentOffset метод вызывается в моем режиме вертикальной прокрутки. Во время отладки я вижу, что setContentOffset был вызван из UIScrollViewInternal _adjustContentOffsetIfNecessary,

ОБНОВЛЕНИЕ № 3:

Та же проблема происходит в следующем сценарии: у меня есть UITextFields внутри вертикального UIScrollView. При нажатии определенного UITextField появляется клавиатура. Когда я хочу отключить клавиатуру в интерактивном режиме (перетаскивая вид прокрутки поверх клавиатуры), после того, как я отпущу перетаскивание, возникает сбой. Смещение содержимого UIScrollView на мгновение было установлено равным нулю, а затем вернулось к исходному смещению содержимого и продолжило анимацию. Это нежелательный параметр contentOffset также вызывается UIScrollViewInternal _adjustContentOffsetIfNecessary,

Я пошел дальше и заменил UIScrollView в обоих сценариях своим собственным подклассом UIScrollView. В этом подклассе я переопределил закрытый метод -(void) _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
    }
}

Я нашел интересную дискуссию об этом в Twitter. Хотя это не мой случай, это может кому-то помочь:

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

обсуждение в твиттере

Используйте UIViewController с UITableView вместо UITableViewController. Это решило мою проблему:)

Другие вопросы по тегам