看起来这里确实有两个问题。第一,以编程方式设置 ViewController 的最佳方法是什么。另一个是如何以编程方式设置视图。
首先,让 ViewController 以编程方式使用不同的 UIView 子类的最佳方法是在loadView
方法。根据苹果的docs https://developer.apple.com/reference/uikit/uiviewcontroller/1621454-loadview:
您可以重写此方法以手动创建视图。
如果您选择这样做,请将视图层次结构的根视图分配给
视图属性。您创建的视图应该是唯一的实例并且
不应与任何其他视图控制器对象共享。你的
此方法的自定义实现不应调用 super。
这看起来像这样:
class LoginViewController: UIViewController {
override func loadView() {
// Do not call super!
view = LoginView()
}
}
这样你就不必处理它的大小问题,因为视图控制器本身应该处理它(就像它处理它自己的 UIView 一样)。
记住,不要打电话super.loadView()
否则控制器会感到困惑。另外,我第一次尝试这个时,我遇到了黑屏,因为我忘记打电话window.makeKeyAndVisible()
在我的应用程序代理中。在这种情况下,视图甚至从未添加到窗口层次结构中。您始终可以使用 Xcode 中的“查看内省器”按钮来查看发生了什么。
其次,您需要致电self.addSubview(_:)
在你的 UIView 子类中以便让它们出现。将它们添加为子视图后,您可以使用以下命令添加约束NSLayoutConstraint
.
private func setupLabels(){
// Initialize labels and set their text
usernameLabel = UILabel()
usernameLabel.text = "Username"
usernameLabel.translatesAutoresizingMaskIntoConstraints = false // Necessary because this view wasn't instantiated by IB
addSubview(usernameLabel)
passwordLabel = UILabel()
passwordLabel.text = "Password"
passwordLabel.translatesAutoresizingMaskIntoConstraints = false // Necessary because this view wasn't instantiated by IB
addSubview(passwordLabel)
NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|-10-[view]", options: [], metrics: nil, views: ["view":usernameLabel]))
NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|-20-[view]", options: [], metrics: nil, views: ["view":passwordLabel]))
NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[view]", options: [], metrics: nil, views: ["view":usernameLabel]))
NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-20-[view]", options: [], metrics: nil, views: ["view":passwordLabel]))
}
有关用于创建约束的视觉格式语言的更多信息,请参阅视觉FL指南 https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage.html#//apple_ref/doc/uid/TP40010853-CH27-SW1