swift 将uiviewcontroller视图替换为自定义视图是否正确?

wyyhbhjk  于 2023-09-30  发布在  Swift
关注(0)|答案(2)|浏览(111)

我试图在运行时更新uivewicontroller视图层次结构。它工作得很好,但我不确定是否是正确的做法。
正如我所看到的,UIViewController的根视图属性有setter。
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621460-view
下面是代码示例:

@IBAction func showUserDetailsScreen() {
    let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
    let controller = storyboard.instantiateViewController(withIdentifier: "UserDetailsVC")
    
    /* The basic idea is to replace "UIViewController root view" to
     "my custom message view" and then adding initial "UIViewController root view" as
     subview to "my custom message view".
     So view hierarchy will be like as follow:
     
     Old: UserDetailsVC >> view
     New: UserDetailsVC >> SecureView >> view
     
     Is it a safe and correct practice to do this?
     */
    
    if let secureView = createSecureView() {
        
        let bgView = UIView()
        bgView.backgroundColor = .blue
        secureView.frame = self.view.bounds
        secureView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        
        bgView.addSubview(secureView)
        
        let controllerView = controller.view
        
        bgView.frame = controller.view.bounds
        bgView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        
        // Exchanging UserDetailsVC's view to Custom view.
        controller.view = bgView
        
        if let view = controllerView {
            
            view.frame = controller.view.bounds
            view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            
            // Adding initial UserDetailsVC's view as subview to secure view.
            secureView.addSubview(view)
        }
    }
    
    navigationController?.pushViewController(controller, animated: true)
}

private func createSecureView() -> UIView? {
    
    if let view = Bundle.main.loadNibNamed("SecureView", owner: nil, options: nil)?.first as? SecureView {
        return view
    }
    
    return nil
}

与任何现有项目一样,UIViewContoller可以有非常复杂的视图层次结构。因此,这是一个快速而简单的解决方案,可以控制所有屏幕。
任何建议或反馈都是非常欢迎的。

d5vmydt9

d5vmydt91#

您不应该在loadView()之外更改UIViewController.view。不确定它是否能正常运行,但无论哪种方式,这都是一个坏主意,因为它可能会导致混淆view是什么。
相反,您应该让所有这些SecureView层次结构都发生在UserDetailsVC中。例如,在viewDidLoad()中:

self.view.addSubview(self.bgView)
self.bgView.addSubview(self.secureView)
self.secureView.addSubview(self.contentView) // content view could be what you were putting as `UserDetailsVC.view`

或者,如果你需要在应用程序中使用不同的通用视图控制器来更好地重用它,一个简单的方法(许多方法中的一个)是拥有一个SecureViewController类,其他视图控制器(如UserDetailsVC)继承自这个类。

class SecureViewController: UIViewController {

    let secureView = SecureView()

    override func loadView() {
        self.view = self.secureView
    }
}

class UserDetailsVC: SecureViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.view.addSubview(AnyViewYouWant()) // since self.view refers to secureView, you're adding to the secureView
    
        // This is the same as:
        self.secureView.addSubview(AnyViewYouWant())
    }
}
zengzsys

zengzsys2#

您只需使用容器视图来实现此目的
他们已经内置到iOS / UIKit为15+?年
你经常使用容器视图来做iOS中的所有事情。
在故事板中,只需单击即可添加容器视图...

因为它可能是每个iOS布局的最基本的构建块,所以你可以找到无数的教程等。
这里有一个很长的详细的一个,也清楚地解释了如何在代码(这是容易的),如果你喜欢。

相关问题