PullToDismiss icon indicating copy to clipboard operation
PullToDismiss copied to clipboard

ios 11 jerky on trying to dismiss

Open vargarobert opened this issue 7 years ago • 7 comments

There is an issue on ios11. The nav bar gets jerky when pulling to dismiss. Can be seen in the demo as well.

vargarobert avatar Sep 24 '17 19:09 vargarobert

I have been looking into this, but haven't been able to fix it yet. @vargarobert did you end up trying to fix this when you were looking at it?

ChrisRicca avatar Nov 16 '17 17:11 ChrisRicca

No. Sorry. Haven't tried to fix it. I might end up building the functionality internally part of the app.

On 16 Nov 2017, at 17:59, Chris Ricca [email protected] wrote:

I have been looking into this, but haven't been able to fix it yet. @vargarobert did you end up trying to fix this when you were looking at it?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

vargarobert avatar Nov 16 '17 18:11 vargarobert

I think I might take a crack at it soon. I think it has something to do with safe zones. I have been seeing this a lot on my iPhoneX in testing and when I do the drag super slow it looks like when the animation starts dragging down the height of the object you are dragging gets shorter (specifically at the top on my device by the height of the safe zone above my top element constraint) causing the jerky feeling. At least that is what I am planning to look at as a possible cause.

tklucher avatar Dec 14 '17 17:12 tklucher

In my xp, this is to do with safe area layout guides, if I manually take safe area off and just put a larger constraint for the iPhone x it works.

matthewweldon avatar Dec 21 '17 18:12 matthewweldon

I found an (unanswered) bug related to this on StackOverflow. I am taking another crack at this but posting here for tracking purposes: https://stackoverflow.com/questions/47638767/ios-11-uinavigationbar-position-loses-status-bar-height-during-transition

Also this Apple forum Post (login required?): https://forums.developer.apple.com/thread/93444

ChrisRicca avatar Jan 10 '18 20:01 ChrisRicca

I'm not really sure how I would implement this as a fix in PullToDismiss, but if anyone else is looking to work around this:

setting scrollView.contentInsetAdjustmentBehavior = .never on my scroll view did help with the worst of the jumpiness, but the UINavigationController was still shrinking (by the height of the status bar) whenever I started to drag down due to the behavior in the links above.

To deal with this, I wrapped the UINavigationController in a parent view controller, and added a view in that parent view controller that was the same color as my navigationBar. That way, when that slice of the UINavigationController would disappear, you don't see the presenting view behind the status bar suddenly appear.

ChrisRicca avatar Jan 16 '18 20:01 ChrisRicca

As far as I could investigate the 'jumpiness' is caused by two things when drag animation starts:

  • the safeAreaLayoutGuide.topAnchor decreases by the height of the status bar (causing the tableView/collectionView/scrollView content to slightly jump up)

  • the navigationBar height shrinks by the height of the status bar (causing the navigationBar content to slightly jump up)

To solve the first issue I override the viewSafeAreaInsetsDidChange() method inside my viewController to compensate for lost safeArea topAnchor height by increasing additionalSafeAreaInsets.top value, like this:

    var navBarHeight: CGFloat {
        return self.navigationController?.navigationBar.frame.size.height ?? 0.0
    }

    var statusBarHeight: CGFloat {
        let statusBarSize = UIApplication.shared.statusBarFrame.size
        return min(statusBarSize.width, statusBarSize.height)
    }
    
    @available(iOS 11, *)
    override func viewSafeAreaInsetsDidChange() {
        super.viewSafeAreaInsetsDidChange()
        
        let totalNavBarHeight = navBarHeight + statusBarHeight
        
        if (self.view.safeAreaInsets.top < totalNavBarHeight) {
            self.additionalSafeAreaInsets.top = totalNavBarHeight - self.view.safeAreaInsets.top
        }
        else if (self.view.safeAreaInsets.top > totalNavBarHeight) {
            self.additionalSafeAreaInsets.top = 0
        }
    }

To solve the navigationBar shrinking height problem, I've modified updateViewPosition(offset: CGFloat) method inside PullToDismiss.swift file, and changed values where it says avoid statusbar gone like this:

    if viewPositionY >= 0 && viewPositionY < 0.005 {
        addOffset = min(max(-0.001, addOffset), 0.001)
    }

To avoid triggering navBar shrinking, I made the drag animation move even more slowly in the beginning, I've changed value 0.05 to 0.005, and values -0.01 and 0.01 to -0.001 and 0.001.

This could probably be fixed more elegantly but for now this is what works for me.

ElectroBuddha avatar May 24 '18 07:05 ElectroBuddha