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

问题描述 投票:0回答:2

我正在尝试在运行时更新我的 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 可以具有非常复杂的视图层次结构。因此,这是一个快速且简单的解决方案,可以控制所有屏幕。

欢迎任何建议或反馈。

ios swift iphone uiview uiviewcontroller
2个回答
1
投票

您不应该在

UIViewController.view
之外更改
loadView()
。不确定它是否会正常运行,但无论如何这都是一个坏主意,因为它可能会导致混淆
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())
    }
}

0
投票

您只需使用 容器视图来达到这个目的

它们已内置到 15+ 的 iOS / UIKit 中?年。

您经常使用容器视图来完成 iOS 中的所有操作。

在故事板中只需单击即可添加容器视图...

由于它可能是每个 iOS 布局最基本的构建块,因此您可以找到无数的教程等。

这里有一个详细的内容,如果您愿意的话,它还清楚地解释了如何在代码中执行此操作(这很简单)。

© www.soinside.com 2019 - 2024. All rights reserved.