问题
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 NSLayoutConstraint
s and frame
s. 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