提问人:Mohd Haider 提问时间:9/29/2022 更新时间:9/18/2023 访问量:306
将 uiviewcontroller 视图替换为自定义视图是否正确?
Is it correct to replace uiviewcontroller view to custom view?
问:
我正在尝试在运行时更新我的 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 可以具有非常复杂的视图层次结构。因此,这是一个快速简便的修复程序,可以控制所有屏幕。
欢迎任何建议或反馈。
答:
不应在 之外进行更改。不确定它是否会正常运行,但无论哪种方式,这都是一个坏主意,因为它可能会导致混淆是什么。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())
}
}
您只需使用容器视图即可实现此目的。
它们已经内置到 iOS / UIKit 中 15+?年。
您始终使用容器视图来执行 iOS 中的所有操作。
在情节提要中,只需单击即可添加容器视图...
由于它可能是每个iOS布局中最基本的构建块,因此您可以找到无数的教程等。
这是一个很长的细节,如果你愿意,它还清楚地解释了如何在代码中做到这一点(这很容易)。
上一个:从核心数据传递值
评论
UIViewController.view
loadView()
SecureViewDecoratorController<VC: UIViewController>
addChild