微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ios – 将UIViewController视图属性设置为不带有storyboard / nib的自定义UIView类

我有一个名为LoginViewController的UIViewController.我想在一个名为LoginView的自定义UIView类中完全以编程方式构建该LoginViewController的视图,而不是构建我的LoginViewController中的所有元素.这样我就阻止了Controller类(MVC)中的“View”代码.

在下面的代码中,我将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

结果:

解决方法

看来这里真的有两个问题.一,以编程方式设置ViewController的最佳方法是什么.另一种,如何以编程方式设置View.

首先,以编程方式使用不同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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐