Layout constraints not working with view.frame.size.height

ε祈祈猫儿з 提交于 2021-01-29 07:43:52

问题


I'm creating my UI programmatically and I want to make my UITextfield topAnchor to be based off the height of its containing UIView but it's not working.

My UITextfield is inside a UIView and I want its topAnchor to be 0.15 the height of the UIView as such - containerView.frame.size.height * 0.15 but it seems the value is not picking up. All this is done in a UIView subclass and called in the ViewController

        let containerView: UIView
        containerView.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(containerView)

        NSLayoutConstraint.activate([
            containerView.centerXAnchor.constraint(equalTo: self.centerXAnchor),
            containerView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.9),
            containerView.topAnchor.constraint(equalTo: stepTitleLabel.bottomAnchor, constant: 50),
            containerView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.65)
            ])


        let userTextField: UITextField
        userTextField?.tag = 1
        userTextField?.translatesAutoresizingMaskIntoConstraints = false
        containerView.addSubview(userTextField)

        userTextField.setNeedsLayout()
        print("containerView.frame.size.height * 0.15:\(containerView.frame.size.height * 0.15)")
        NSLayoutConstraint.activate([
            (userTextField.centerXAnchor.constraint(equalTo: containerView.centerXAnchor))!,
            (userTextField.widthAnchor.constraint(equalTo: containerView.widthAnchor, multiplier: 0.8))!,
            userTextField.topAnchor.constraint(equalTo: containerView.topAnchor, constant: containerView.frame.size.height * 0.15),
            userTextField.heightAnchor.constraint(equalToConstant: 40)
            ])

I expect the topAnchor of my UITextField to appear similar across all devices at 0.15 the height of it container view but what I'm getting is 0


回答1:


Don't mix NSLayoutConstraints and frames. The frames are static and don't update when you use them for the constant in a constraint. So when Auto Layout uses the other constraints to update the height of containerView, your constraint that looks at containerView's frame height will be based upon the height of the containerView at the time of the constraint's creation (which is likely 0) and not at the time Auto Layout uses the constraints to establish the height of containerView.

Instead, you want to base the top of userTextField on the bottom of containerView with a multiplier. Unfortunately, you can't do that with layout anchors, and you'll have to use NSLayoutContraint to create it:

Replace:

userTextField.topAnchor.constraint(equalTo: containerView.topAnchor,
    constant: containerView.frame.size.height * 0.15)

with:

NSLayoutConstraint(item: userTextField, attribute: .top, relatedBy: .equal,
    toItem: containerView, attribute: .bottom, multiplier: 0.15, constant: 0)



回答2:


You need to make it with self not container as container's height is not yet calculated

userTextField.topAnchor.constraint(equalTo: containerView.topAnchor,  
     constant: self.frame.size.height * 0.15 * 0.65 )

Given that the height of container = 0.65 * from self here

self.heightAnchor, multiplier: 0.65


来源:https://stackoverflow.com/questions/56020632/layout-constraints-not-working-with-view-frame-size-height

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!