0
votes

I have a UIPageViewController subclass that allows the user to swipe upward from the initial view controller to a second view controller. The initial view controller does not have a navigation bar (it's not connected to a UINavigationController), but the second one does. Currently, when I swipe up to present the second view controller, there is no space in the navigation bar for the status bar. When the transition is complete, the entire view controller layout updates instantly to add the status bar space. I want to make the second view controller anticipate that the status bar will be there and add the space for it so the view doesn't jolt after the transition.

Short video clip showing the jolt

Similar, but unanswered question

EDIT:

After closely looking at the way the view controller behaves during the transition, I was able to get a good look at what is going on here.

  1. When I swipe up, the second view controller moves upward and aligns the top edge of the navigation bar (no status bar) with the top of the screen. It appears that the size/layout of the content is correct, so there's whitespace at the bottom that's the height of the status bar. See the screenshot:

enter image description here

  1. When the transition is finished, space for the status bar is added and the view gets shifted downward.
1
please check this article first - blog.jaredsinclair.com/post/61507315630/… and post your code for transitionsignotusverum
@ignotusverum Thanks for the article. As for the code, the transitions are managed by UIPageViewController. My subclass only provides the two view controllers and implements the delegate's pageViewController(_:didFinishAnimating:previousViewControllers:transitionCompleted:)Greg Whatley

1 Answers

0
votes

I found a workaround that seems to work pretty well. I need to test this with the iPhone X to see if I need to make adjustments. If someone finds a better solution, I'll make it the accepted answer.

I basically shift my page view controller down by 20pt when it is loaded:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    let f = view.frame
    view.frame = CGRect(x: 0, y: 20, width: f.size.width, height: f.size.height)
    view.setNeedsLayout()
    view.layoutIfNeeded()
}

After the transition, I shift the page view controller back up to its original position at exactly the same time that the second view controller adds status bar space. This causes the second view controller to slide right below the status bar, where it should be. There's no noticeable jolt. I used this in my page view controller's delegate:

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    guard previousViewControllers.count > 0 else { return }
    // if the transition completed and the view controller we transitioned from is the first view controller
    if completed && viewControllers!.index(of: previousViewControllers.first!) == 0 {
        let f = view.frame
        view.frame = CGRect(x: 0, y: 0, width: f.size.width, height: f.size.height)
        view.setNeedsLayout()
        view.layoutIfNeeded()
    }
}