9

When I use storyboard segue, it is pretty smooth showing another viewcontroller onscreen. However, when I'm not using storyboard, just add a simple line of code with navigationController?.pushViewController(UIViewController(), animated: true), it's a little bit lagging in transition.

Also I read about Delay when pushing view controller (iOS). But even when I'm pushing an brand new viewcontroller (no extra code inside), the transition is still a little bit lagging, any idea?

enter image description here

Willjay
  • 6,381
  • 4
  • 33
  • 58

6 Answers6

12

Swift 5.3, Xcode 12

I was facing this same issue, tried adding to main thread, but apparently the problem was, I was pushing the viewController created programatically, and its backgroundColor was nil. Just by setting the color in pushedViewController to something else, solved the issue.

self.view.backgroundColor = yourColor
Kedar Sukerkar
  • 1,410
  • 1
  • 16
  • 22
  • 1
    Yeah, this is the root cause. `self.view.backgroundColor = .systemBackground` will support dark mode. – Zhou Haibo Nov 17 '20 at 11:22
  • For me it was on the viewDidLoad of the VC that is being pushed and setting isOpaque property on the webView. – Mishka Jul 07 '21 at 14:50
2

In app delegate, set your window's background color to red.

window?.backgroundColor = .red

Also in the the pushed view controller, set its view to red.

view.backgroundColor = .red

I experienced the same issue when programmatically embedding my view controller in a UINavigationController.

Brian Green
  • 215
  • 3
  • 14
1

I came across the same issue when I was drawing UI programmatically.

In my case, overriding loadView function solved my problem.

import UIKit

class MyViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationItem.title = "My tasks"
}

override func loadView() {
    // You can load your view here. For simplicity, I just give it a background color
    let v = UIView()
    v.backgroundColor = UIColor.orange

    view = v // This line does the magic
}

}

Abu-Bakr
  • 408
  • 6
  • 12
1

Viewcontroller is expecting to render view so add below view background color or set title

override func viewDidLoad() {
            super.viewDidLoad()
            self.navigationItem.title = "Title"
            self.view.backgroundColor = .red
    
        }
Darshan
  • 2,272
  • 3
  • 31
  • 43
0

I debug with slow animation on simulator. The "lagging" is the underlying previous view controller’s view as @yesleon mentioned. I set the previous view's alpha to 0 when viewWillDisappear, and 1 when viewWillAppear. It seems much better when pushing to the new controller now, but when pushing back to original view controller, it still a little bit not perfect, any better solution?

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.tabBarController?.tabBar.isHidden = false
    view.alpha = 1.0
}


override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.tabBarController?.tabBar.isHidden = true
    view.alpha = 0.0
}

@IBAction func barbuttonDidTapped(_ sender: UIBarButtonItem) {
    navigationController?.pushViewController(UIViewController(), animated: true)
}
Willjay
  • 6,381
  • 4
  • 33
  • 58
0

I met the same issue, put ui code and its constraints inside viewDidLoad into loadView() fix it. Now the animation is moving smoothly.

Refer here: https://stackoverflow.com/a/3424052/10158398

loadView is the method that actually sets up your view (sets up all the outlets, including self.view).

viewDidLoad you can figure out by its name. It's a delegate method called after the view has been loaded (all the outlets have been set) that just notifies the controller that it can now start using the outlets.

viewDidLoad: "This method is called after the view controller has loaded its associated views into memory. This method is called regardless of whether the views were stored in a nib file or created programmatically in the loadView method."

loadView: "If you create your views manually, you must override this method and use it to create your views."

For an example:

class DetailViewController: UIViewController {
    let imageView = UIImageView()
    var picture: Picture?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    override func loadView() {
        view = UIView()
        view.backgroundColor = .white
        
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .scaleAspectFit
        view.addSubview(imageView)
        
        NSLayoutConstraint.activate([
            imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
        
        if let picture = picture {
            let path = getDocumentDirectory().appendingPathComponent(picture.picture)
            imageView.image = UIImage(contentsOfFile: path.path)
        }
    }
Zhou Haibo
  • 1,681
  • 1
  • 12
  • 32