Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UIScrollView contentOffset reset when going back to Tabman VC #194

Closed
3 tasks done
rnystrom opened this issue Nov 28, 2017 · 5 comments
Closed
3 tasks done

UIScrollView contentOffset reset when going back to Tabman VC #194

rnystrom opened this issue Nov 28, 2017 · 5 comments

Comments

@rnystrom
Copy link

New Issue Checklist

Issue Description

When navigating back to a Tabman controller, the VC view is being laid out, triggering viewDidLayoutSubviews. When Tabman performs its auto insetting, it is recalculating the contentOffset and discarding the original y position. This results in the scroll view "jumping" back to the top whenever you navigate back to a VC using Tabman.

tabman-bug

Other useful things

It's very easy to reproduce in my GitHawk project via:

  • Search for repo "githawk"
  • Tap repo
  • Tap "Issues" tab
  • Scroll down
  • Tap issue
  • Tap back button

Here's a stack trace of the operations.

Stack trace
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
    frame #0: 0x0000000103b108df UIKit`-[UIScrollView setContentOffset:]
  * frame #1: 0x0000000103913e0a Tabman`AutoInsetEngine.inset(childViewController=0x00007f8c9f04b600, requiredInsets=Tabman.TabmanBar.Insets @ 0x00007fff5e2171c0, self=0x0000600000230aa0) at AutoInsetEngine.swift:67
    frame #2: 0x00000001039611b4 Tabman`TabmanViewController.setNeedsChildAutoInsetUpdate(childViewController=0x00007f8c9f04b600, self=0x00007f8c9f024c00) at TabmanViewController+AutoInsetting.swift:24
    frame #3: 0x0000000103960f78 Tabman`TabmanViewController.setNeedsChildAutoInsetUpdate(self=0x00007f8c9f024c00) at TabmanViewController+AutoInsetting.swift:15
    frame #4: 0x0000000103964a31 Tabman`TabmanViewController.viewDidLayoutSubviews(self=0x00007f8c9f024c00) at TabmanViewController.swift:75
    frame #5: 0x0000000103964cb4 Tabman`@objc TabmanViewController.viewDidLayoutSubviews() at TabmanViewController.swift:0
    frame #6: 0x0000000103b02871 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1819
    frame #7: 0x00000001077993ee QuartzCore`-[CALayer layoutSublayers] + 153
    frame #8: 0x000000010779d4dd QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 401
    frame #9: 0x0000000103aec735 UIKit`-[UIView(Hierarchy) layoutBelowIfNeeded] + 662
    frame #10: 0x0000000103c1e0ae UIKit`-[UINavigationController _layoutViewController:] + 1691
    frame #11: 0x0000000103c17db1 UIKit`-[UINavigationController _layoutTopViewController] + 368
    frame #12: 0x0000000103c41c8d UIKit`-[UITabBarController animationDidStop:finished:context:] + 976
    frame #13: 0x0000000103c4397e UIKit`__56-[UITabBarController _showBarWithTransition:isExplicit:]_block_invoke.713 + 223
    frame #14: 0x0000000104795612 UIKit`-[_UIViewControllerTransitionCoordinator _applyBlocks:releaseBlocks:] + 294
    frame #15: 0x00000001047911c1 UIKit`-[_UIViewControllerTransitionContext _runAlongsideCompletions] + 155
    frame #16: 0x0000000104790e99 UIKit`-[_UIViewControllerTransitionContext completeTransition:] + 118
    frame #17: 0x0000000103a1a61b UIKit`__53-[_UINavigationParallaxTransition animateTransition:]_block_invoke.124 + 832
    frame #18: 0x0000000103af4e35 UIKit`-[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 859
    frame #19: 0x0000000103ac799d UIKit`-[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 354
    frame #20: 0x0000000103ac7fde UIKit`-[UIViewAnimationState animationDidStop:finished:] + 293
    frame #21: 0x0000000103ac8092 UIKit`-[UIViewAnimationState animationDidStop:finished:] + 473
    frame #22: 0x00000001077a8a2b QuartzCore`CA::Layer::run_animation_callbacks(void*) + 323
    frame #23: 0x000000010884343c libdispatch.dylib`_dispatch_client_callout + 8
    frame #24: 0x000000010884e6f0 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 628
    frame #25: 0x0000000106afaee9 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
    frame #26: 0x0000000106abf592 CoreFoundation`__CFRunLoopRun + 2402
    frame #27: 0x0000000106abe9b9 CoreFoundation`CFRunLoopRunSpecific + 409
    frame #28: 0x000000010ce7d9c6 GraphicsServices`GSEventRunModal + 62
    frame #29: 0x0000000103a315e8 UIKit`UIApplicationMain + 159
    frame #30: 0x00000001019ec1c7 Freetime`main at AppDelegate.swift:16
    frame #31: 0x00000001088bfd81 libdyld.dylib`start + 1
@rnystrom rnystrom changed the title UIScrollView contentOffset set to .zero when UIScrollView contentOffset reset when going back to Tabman VC Nov 28, 2017
@msaps msaps added the bug label Nov 28, 2017
@msaps
Copy link
Member

msaps commented Nov 28, 2017

@rnystrom cheers for all the detail, will get it fixed ASAP 👍

@msaps msaps added the high label Nov 28, 2017
@msaps
Copy link
Member

msaps commented Nov 28, 2017

This seems to be limited to the iPhone X, does not occur on 'regular' devices on iOS 10/11

@rnystrom
Copy link
Author

I think layout is occurring because of safe area insets. I saw some weird behavior with UIWebView before too causing unnecessary layouts.

Sent with GitHawk

@msaps
Copy link
Member

msaps commented Nov 28, 2017

@rnystrom yeah it looks as though the safeArea is updating, and causing the insets that Tabman calculates to be updated. As they don't match the current contentInset from the previous layout pass it updates and resets the contentOffset.

The actual top inset remains the same, it's the bottom inset that differs. But the contentOffset should not need updating unless the top inset has changed; I'm going to update so that it only changes in that scenario.

@msaps
Copy link
Member

msaps commented Nov 28, 2017

@rnystrom

1.1.1 is now available, which features the above fix. 🍾

@msaps msaps closed this as completed Jan 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants