推送UIViewController时出现延迟

10
当我使用故事板segue时,屏幕上显示另一个视图控制器非常流畅。然而,当我不使用故事板,只是添加一行简单的代码navigationController?.pushViewController(UIViewController(), animated: true)时,转换有点延迟。
我也阅读了推送视图控制器时的延迟(iOS)。但即使我推送一个全新的视图控制器(内部没有额外的代码),转换仍然有点延迟,有什么想法吗?

enter image description here


2
检查一下你的viewDidLoad里是否有过于繁重的代码。 - Shehata Gamal
你检查过推送视图控制器的viewDidLoad调用了吗?如果viewDidLoad被调用了,那么尝试设置视图颜色。 - Manish Mahajan
您可能已经操作了视图的alpha值。您能否提供示例应用程序,以便我可以为您进行调试。 - dip
你可能在下一个视图控制器上在主线程上做很多工作。 - Sameh
它的推送非常正常。你看到的“滞后”是底层的前一个视图控制器的视图,而不是新的视图控制器。 - yesleon
6个回答

14

Swift 5.3,Xcode 12

我曾经遇到过同样的问题,尝试将其添加到主线程中,但显然问题是我在以编程方式创建的视图控制器中推送了它,并且其背景颜色为nil。 只需将pushedViewController中的颜色设置为其他颜色即可解决问题。

self.view.backgroundColor = yourColor

2
是的,这就是根本原因。self.view.backgroundColor = .systemBackground将支持暗模式。 - Zhou Haibo
对我来说,这是在被推送的VC的viewDidLoad上设置webView的isOpaque属性。 - Mishka

2
在应用程序委托中,将窗口的背景颜色设置为红色。
window?.backgroundColor = .red

在推送的视图控制器中,将其视图设置为红色。
view.backgroundColor = .red

当我在代码中将我的视图控制器嵌入UINavigationController时,我遇到了同样的问题。


2
视图控制器期望呈现视图,因此请添加以下视图背景颜色或设置标题。
override func viewDidLoad() {
            super.viewDidLoad()
            self.navigationItem.title = "Title"
            self.view.backgroundColor = .red
    
        }

1
我在模拟器上使用慢速动画进行调试。正如@yesleon所提到的那样,“滞后”是由于底层的前一个视图控制器的视图。当viewWillDisappear时,我将前一个视图的alpha设置为0,当viewWillAppear时设置为1。现在推到新控制器时看起来好多了,但是当返回到原始视图控制器时,仍然有一点不完美,有更好的解决方案吗?
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)
}

1

当我在编写UI时遇到了同样的问题。

在我的情况下,重写loadView函数解决了我的问题。

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
}

}


0

我遇到了同样的问题,将UI代码和其约束放在viewDidLoad中,然后放入loadView()中解决了这个问题。现在动画流畅地运行。

请参考这里:https://dev59.com/ak_Ta4cB1Zd3GeqPCJhd#3424052

loadView是实际设置视图(设置所有输出,包括self.view)的方法。

你可以从viewDidLoad的名称中推断出它的作用。它是一个委托方法,在视图加载完成后(所有输出都已设置)调用,通知控制器它现在可以开始使用输出。

viewDidLoad:“此方法在视图控制器将其关联的视图加载到内存中后调用。无论视图是存储在nib文件中还是在loadView方法中以编程方式创建,都会调用此方法。”

loadView:“如果手动创建视图,则必须重写此方法并使用它来创建视图。”

例如:

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)
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接