在下面的代码中,我将LoginViewController的视图设置为我的LoginView,为简单起见,它只包含2个UILabels
class LoginViewController: UIViewController { override func loadView() { super.loadView() self.view = LoginView(frame: CGRect.zero) }
LoginView类初始化两个标签,并应设置一些约束.
class LoginView: UIView { var usernameLabel: UILabel! var passwordLabel: UILabel! override init (frame : CGRect) { super.init(frame : frame) setupLabels() } convenience init () { self.init(frame:CGRect.zero) } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } private func setupLabels(){ //Init labels and set a simple text self.usernameLabel = UILabel() self.usernameLabel.text = "Username" self.passwordLabel = UILabel() self.passwordLabel.text = "Password" //Set constraints which aren't possible since there is no contentView,perhaps using the frame? } }
这不起作用,因为视图的边界是0.但是我找不到任何能够深入了解这是否可行的资源,所以我尝试了我的方法,但是没有用.
如何将UIViewController的视图设置为以编程方式创建的自定义UIView?或者上面的代码片段是推荐的吗?
This is the working solution based on Jadar’s answer:
06002
结果:
解决方法
首先,以编程方式使用不同UIView子类的ViewController的最佳方法是在loadView方法中初始化并分配它.按Apple docs:
You can override this method in order to create your views manually.
If you choose to do so,assign the root view of your view hierarchy to
the view property. The views you create should be unique instances and
should not be shared with any other view controller object. Your
custom implementation of this method should not call super.
这看起来像这样:
class LoginViewController: UIViewController { override func loadView() { // Do not call super! view = LoginView() } }
这样你就不必处理它的大小调整,因为View Controller本身应该处理它(就像它自己的UIView一样).
记住,不要调用super.loadView()或控制器会混淆.此外,我第一次尝试这个时,我得到一个黑屏,因为我忘了在我的App Delegate中调用window.makeKeyAndVisible().在这种情况下,视图从未添加到窗口层次结构中.您始终可以使用Xcode中的视图introspecter按钮来查看正在发生的事情.
其次,您需要在UIView子类中调用self.addSubview(_ :)才能显示它们.将它们添加为子视图后,可以使用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]",views: ["view":passwordLabel])) NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-10-[view]",views: ["view":usernameLabel])) NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-20-[view]",views: ["view":passwordLabel])) }
有关用于创建约束的可视格式语言的更多信息,请参阅VFL Guide