iOS开发:合并两个ViewController视图未正常渲染问题求助
解决视图未渲染及约束错误问题
问题根源
- 仅将子ViewController的view添加到父视图,但未将子VC注册为CommonViewController的子控制器,导致子VC的生命周期方法(如
viewDidLoad、viewWillAppear)无法正常触发,视图内容无法渲染。 - 添加子view后未设置任何布局约束,系统无法确定子view的位置和尺寸,因此出现约束错误。
解决方案
步骤1:将子VC注册为子控制器
在combineView方法中,创建子VC后必须调用addChild(_:)完成注册,添加view后调用didMove(toParent:)通知子VC完成挂载:
private func combineView() { let dvc = MovieDetailsViewController(viewModel: viewModel) let svc = SmiliarMovieViewController(viewModel: viewModel) // 注册子控制器 addChild(dvc) addChild(svc) view.addSubview(dvc.view) view.addSubview(svc.view) // 通知子VC完成挂载 dvc.didMove(toParent: self) svc.didMove(toParent: self) // 调用约束设置方法 setupSubviewConstraints(dvc: dvc, svc: svc) }
步骤2:添加布局约束
新增私有方法setupSubviewConstraints,给两个子view设置明确的布局规则(示例为垂直上下排列,可根据需求调整):
private func setupSubviewConstraints(dvc: MovieDetailsViewController, svc: SmiliarMovieViewController) { // 关闭自动约束转换,启用手动约束 dvc.view.translatesAutoresizingMaskIntoConstraints = false svc.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ // 详情视图:顶部、左右对齐父视图安全区,高度占屏幕1/3 dvc.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), dvc.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), dvc.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), dvc.view.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 1/3), // 相似电影视图:顶部接详情视图底部,左右、底部对齐父视图安全区 svc.view.topAnchor.constraint(equalTo: dvc.view.bottomAnchor), svc.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), svc.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), svc.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) }
完整修改后的CommonViewController代码
import UIKit class CommonViewController: UIViewController { private let viewModel: MoviesDetailsViewModel init(viewModel: MoviesDetailsViewModel) { self.viewModel = viewModel super.init(nibName: nil, bundle: nil) navigationItem.largeTitleDisplayMode = .never } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() combineView() navigationItem.leftBarButtonItem = UIBarButtonItem.backButton(target: self, action: #selector(didTapBack(_:))) } private func combineView() { let dvc = MovieDetailsViewController(viewModel: viewModel) let svc = SmiliarMovieViewController(viewModel: viewModel) addChild(dvc) addChild(svc) view.addSubview(dvc.view) view.addSubview(svc.view) dvc.didMove(toParent: self) svc.didMove(toParent: self) setupSubviewConstraints(dvc: dvc, svc: svc) } private func setupSubviewConstraints(dvc: MovieDetailsViewController, svc: SmiliarMovieViewController) { dvc.view.translatesAutoresizingMaskIntoConstraints = false svc.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ dvc.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), dvc.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), dvc.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), dvc.view.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 1/3), svc.view.topAnchor.constraint(equalTo: dvc.view.bottomAnchor), svc.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), svc.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), svc.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) } @objc private func didTapBack(_ sender: UIBarButtonItem) { navigationController?.popViewController(animated: true) } }
内容的提问来源于stack exchange,提问作者user23454452
相关产品推荐
相关产品推荐

