ios - ViewController 包含子类化
问题描述
为了提高我的“远离大型视图控制器”,我正在尝试一些包含视图控制器的东西。
这就是我想要的:
- 有一个带有滚动视图和嵌入式堆栈视图的基类
- 从那个类继承我想要的场景的实现
- 能够根据需要向我的实现添加子视图控制器
我期待这样的事情:
这是我试图实现这一目标的代码:
import UIKit
/**
Base class
*/
class PrototypeStackViewController: UIViewController {
private let scrollView: UIScrollView = {
let s = UIScrollView()
s.translatesAutoresizingMaskIntoConstraints = false
s.contentMode = .scaleToFill
return s
}()
private let stackView: UIStackView = {
let s = UIStackView()
s.translatesAutoresizingMaskIntoConstraints = false
s.axis = .vertical
s.alignment = .fill
s.distribution = .fill
s.contentMode = .scaleToFill
return s
}()
override func loadView() {
view = UIView()
view.backgroundColor = .systemGray
view.addSubview(scrollView)
scrollView.addSubview(stackView)
let nstraint = stackView.heightAnchor.constraint(equalTo: scrollView.frameLayoutGuide.heightAnchor)
stackViewHeightConstraint.priority = .defaultLow
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor),
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
stackViewHeightConstraint
])
}
override func viewDidLoad() {
super.viewDidLoad()
}
func add(child: UIViewController) {
addChild(child)
stackView.addArrangedSubview(child.view)
child.didMove(toParent: self)
}
func remove(child: UIViewController) {
guard child.parent != nil else { return }
child.willMove(toParent: nil)
stackView.removeArrangedSubview(child.view)
child.view.removeFromSuperview()
child.removeFromParent()
}
}
/**
Implementation of my scene
*/
class PrototypeContainmentViewController: PrototypeStackViewController {
lazy var topViewController: PrototypeSubViewController = {
let t = PrototypeSubViewController()
t.view.backgroundColor = .systemRed
t.label.text = "Top View Controller"
return t
}()
lazy var centerViewController: PrototypeSubViewController = {
let t = PrototypeSubViewController()
t.view.backgroundColor = .systemGreen
t.label.text = "Center View Controller"
return t
}()
lazy var bottomViewController: PrototypeSubViewController = {
let t = PrototypeSubViewController()
t.view.backgroundColor = .systemBlue
t.label.text = "Bottom View Controller"
return t
}()
override func loadView() {
super.loadView()
add(child: topViewController)
add(child: centerViewController)
add(child: bottomViewController)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
/**
Sample View Controller
*/
class PrototypeSubViewController: UIViewController {
lazy var label: UILabel = {
let l = UILabel()
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
override func loadView() {
view = UIView()
view.backgroundColor = .systemRed
view.addSubview(label)
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 12),
label.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -12),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor),
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
])
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
这是我得到的:
如果你仔细看,你甚至可以看到“底部视图控制器”标签——但在绿色中心视图控制器的顶部。
在我与自动布局的爱恨交织关系中,我在这里遗漏了一些东西,这是肯定的......
解决方案
您缺少确保堆栈视图填充滚动视图宽度的宽度约束:
stackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor)
另外我会以这种方式设置您的标签约束:
NSLayoutConstraint.activate([
label.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 12),
label.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -12),
label.top.constraint(equalTo: view.topAnchor),
label.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
推荐阅读
- c++ - 在 C++ 中查找内存中某个类的对象布局的算法
- dc.js - 行未按预期归零
- python - 如何在一个脚本中处理多个图像?
- arduino - ESP8266 上显示旧 WiFi SSID
- node.js - 如何在节点 Js 中使用相同的表单代码进行添加和更新?
- c# - 确定模型中哪个嵌套属性为空?
- javascript - 无法读取未定义的属性“类型”提交表单后出现此错误
- apache-spark-sql - 如何从 spark sql join 中选择第一行
- c++ - 这两个代码之间的区别(为什么我的数组占用了额外的空间,即使我给了它一个限制)
- react-native - 将数据保存在 Expo 应用程序中并通过 AWS Amplify 发送