如何创建一个带有子视图的自定义 UIView,以编程方式使用 AutoLayout 设置其大小/位置?

发布于 2025-01-13 02:42:02 字数 3067 浏览 2 评论 0原文

我想创建一个自定义 UIView,例如 TestLabelView,其中包含一个边距为 16px 的标签。

它看起来像这样:

在此处输入图像描述

这是我尝试创建此自定义 UIView 并在视图控制器中实例化它的方法:

TestLabelView

class TestLabelView: UIView {
    private var label = UILabel()
    
    var text: String = "" { didSet { updateUI() } }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        internalInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        internalInit()
    }
    
    private func internalInit() {
        backgroundColor = .red
        label.numberOfLines = 0
        translatesAutoresizingMaskIntoConstraints = false
        addSubview(label)
    }
    
    private func updateUI() {
        label.text = text
        NSLayoutConstraint(item: label,
                           attribute: .leading,
                           relatedBy: .equal,
                           toItem: self,
                           attribute: .leading,
                           multiplier: 1,
                           constant: 24).isActive = true
        NSLayoutConstraint(item: self,
                           attribute: .trailing,
                           relatedBy: .equal,
                           toItem: label,
                           attribute: .trailing,
                           multiplier: 1,
                           constant: 24).isActive = true
        NSLayoutConstraint(item: label,
                           attribute: .top,
                           relatedBy: .equal,
                           toItem: self,
                           attribute: .top,
                           multiplier: 1,
                           constant: 24).isActive = true
        NSLayoutConstraint(item: self,
                           attribute: .bottom,
                           relatedBy: .equal,
                           toItem: label,
                           attribute: .bottom,
                           multiplier: 1,
                           constant: 24).isActive = true
        setNeedsUpdateConstraints()
    }
}

ViewController

class ViewController: UIViewController {
    @IBOutlet weak var testLabelView: TestLabelView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        testLabelView?.text = "This is a test view with a test label, contained in multiple lines"
    }
}

在情节提要中

在此处输入图像描述

我设置了占位符固有大小以消除故事板错误,并且底部边距大于或等于 24px,所以视图高度应根据内容大小设置

但是,通过这样做,我看不到标签出现。我做错了什么?

输入图片此处描述

感谢您的帮助

I would like to create a custom UIView, say TestLabelView, which contains a label whose margin would be 16px.

It would look like this:

enter image description here

Here is how I tried to create this custom UIView and instantiated it in a view controller:

TestLabelView

class TestLabelView: UIView {
    private var label = UILabel()
    
    var text: String = "" { didSet { updateUI() } }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        internalInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        internalInit()
    }
    
    private func internalInit() {
        backgroundColor = .red
        label.numberOfLines = 0
        translatesAutoresizingMaskIntoConstraints = false
        addSubview(label)
    }
    
    private func updateUI() {
        label.text = text
        NSLayoutConstraint(item: label,
                           attribute: .leading,
                           relatedBy: .equal,
                           toItem: self,
                           attribute: .leading,
                           multiplier: 1,
                           constant: 24).isActive = true
        NSLayoutConstraint(item: self,
                           attribute: .trailing,
                           relatedBy: .equal,
                           toItem: label,
                           attribute: .trailing,
                           multiplier: 1,
                           constant: 24).isActive = true
        NSLayoutConstraint(item: label,
                           attribute: .top,
                           relatedBy: .equal,
                           toItem: self,
                           attribute: .top,
                           multiplier: 1,
                           constant: 24).isActive = true
        NSLayoutConstraint(item: self,
                           attribute: .bottom,
                           relatedBy: .equal,
                           toItem: label,
                           attribute: .bottom,
                           multiplier: 1,
                           constant: 24).isActive = true
        setNeedsUpdateConstraints()
    }
}

ViewController

class ViewController: UIViewController {
    @IBOutlet weak var testLabelView: TestLabelView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        testLabelView?.text = "This is a test view with a test label, contained in multiple lines"
    }
}

In the storyboard

enter image description here

I have set a placeholder intrinsic size to remove the storyboard error, and the bottom margin is greater than or equal to 24px, so the view height should be set depending on the content size

However by doing so, I don't see the label appearing. What am I doing wrong?

enter image description here

Thank you for your help

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一张白纸 2025-01-20 02:42:02

您可以在 TestLabelView 视图中尝试此代码

class TestLabelView: UIView {
    private var label : UILabel = {
        let l = UILabel()
        l.translatesAutoresizingMaskIntoConstraints = false
        l.numberOfLines = 0
        return l
    }()
    
    var text: String = "" { didSet { self.label.text = self.text } }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        internalInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        internalInit()
    }
    
    private func internalInit() {
        backgroundColor = .red
        translatesAutoresizingMaskIntoConstraints = false
        addSubview(label)
        setConstraints()
    }
    
    private func setConstraints() {
        NSLayoutConstraint.activate([
            self.label.topAnchor.constraint(equalTo: self.topAnchor, constant: 16),
            self.label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 16),
            self.label.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -16),
            self.label.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -16),
        ])
    }
}

You can try this code for your TestLabelView view

class TestLabelView: UIView {
    private var label : UILabel = {
        let l = UILabel()
        l.translatesAutoresizingMaskIntoConstraints = false
        l.numberOfLines = 0
        return l
    }()
    
    var text: String = "" { didSet { self.label.text = self.text } }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        internalInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        internalInit()
    }
    
    private func internalInit() {
        backgroundColor = .red
        translatesAutoresizingMaskIntoConstraints = false
        addSubview(label)
        setConstraints()
    }
    
    private func setConstraints() {
        NSLayoutConstraint.activate([
            self.label.topAnchor.constraint(equalTo: self.topAnchor, constant: 16),
            self.label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 16),
            self.label.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -16),
            self.label.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -16),
        ])
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文