Heightanchor.Constraint Not Change Height of View

heightAnchor.constraint not change height of view

First declare constraints

var heightArchonWhenShow = view.heightAnchor.constraint(equalToConstant: view.frame.height - 300)
var heightArchonWhenHide = view.heightAnchor.constraint(equalToConstant: view.frame.height + 300)

After init your constraints on ViewDidLoad

func setConstraints(){
view.translatesAutoresizingMaskIntoConstraints = false
view.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
view.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
view.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
heightArchonWhenShow.isActive = true
}

And simple active them , don't overwrite. Like this:

func show(){
heightArchonWhenShow.isActive = true
heightArchonWhenHide.isActive = false
}

func hide(){
heightArchonWhenShow.isActive = false
heightArchonWhenHide.isActive = true
}

If u want u can also animate changes, like that :

func hide(){
heightArchonWhenShow.isActive = false
heightArchonWhenHide.isActive = true

UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}

change heightAnchor of higher size then current size is not working

At the moment, you are creating a new rule about the view's height every time. iOS doesn't understand how to make a view both 10, 20 and 30 pixels high, so it will do the lowest one. To avoid creating conflicting heights, you need to have one height rule and change that one's constant when needed. Here's a somewhat contained example.

class CoolView: UIViewController {

lazy var myView = UIView()
lazy var myViewHeightAnchor = myView.heightAnchor.constraint(equalToConstant: 10)

override func viewDidLoad() {
super.viewDidLoad()

myView.backgroundColor = .black//livesMatters
myView.translatesAutoresizingMaskIntoConstraints = false

view.addSubview(myView)
NSLayoutConstraint.activate([
myView.topAnchor.constraint(equalTo: view.topAnchor),
myView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
myView.widthAnchor.constraint(equalToConstant: 10),
myViewHeightAnchor
])
}

@objc func someButtonTapped() {
myViewHeightAnchor.constant = 20
view.layoutIfNeeded()
}

@objc func anotherButtonTapped() {
myViewHeightAnchor.constant = 30
view.layoutIfNeeded()
}
}

Swift: Changing HeightAnchor Programmatically

The part you failed to do properly happens starting at 16:50 in the video. But we can figure out the problem from the code you posted. These lines are fishy:

inputContainerView.heightAnchor.constraint(equalToConstant: 150)
inputsContainerHeightAnchor?.isActive = true

The first of those lines creates an instance of NSLayoutConstraint, but doesn't activate it and doesn't store it in a variable. So the constraint is immediately destroyed. It has no effect aside from wasting time and battery power.

The second of those lines mentions the variable inputsContainerHeightAnchor, which looks a lot like it should reference the constraint created in the prior line. But the prior line didn't assign anything to that variable. If nothing else assigned a value to that variable, then the variable is nil. Since it's dereferenced using ? instead of !, the second statement does nothing if the variable contains nil.

You probably meant to write this:

inputsContainerHeightAnchor = inputContainerView.heightAnchor.constraint(equalToConstant: 150)
inputsContainerHeightAnchor?.isActive = true

The first line stores the new constraint in the variable, and the second line activates the new constraint. This is what happens in the video starting around 16:50. What you probably missed is at about 17:15, he says “we'll get rid of the let” while he copies the variable name from his instance variable declaration and pastes it over the text let constraint. The line wraps on his screen, his indentation is incorrect, and he does the copy and paste with keyboard shortcuts, so it's hard to follow. You probably thought he just deleted the text let constraint =. (This is why when I make videos I try to avoid keyboard shortcuts.)

However, it would be even better to write these two lines like this:

inputsContainerHeightAnchor = inputContainerView.heightAnchor.constraint(equalToConstant: 150)
inputsContainerHeightAnchor!.isActive = true

When you are sure that a variable should not be nil, and being nil is a programming error, then use ! to dereference it. The program will stop (in the debugger if running under Xcode) on that line if the variable contains nil. If you (and the author of the video) had written it this way, you might have found the error much sooner, because the program would never have gotten past that second line until you fixed the error.

Why does my function to adjust view according to keyboard height behave erratically?

Seems like this is a known issue raised here and other SO questions too..

Two points to make:-

1) Use UIResponder.keyboardFrameEndUserInfoKey instead of UIResponder.keyboardFrameBeginUserInfoKey at:

if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {

in keyboardWillShow()

2) Doing so, you will get the total height of the keyboard including the toolbar. Which means:

However, when I dismiss the keyboard and re-click on any textfield, it
goes up as intended: Only until the top textfield reaches the top of
the screen.

This is the buggy behaviour where you get an incorrect height excluding the toolbar and:

The issue is that the very first time a user clicks on a textfield to
type (no matter which one), the screen moves way too far up, such that
the email textfield at the top ends up going beyond the screen size on
top.

This is actually the intended behaviour with actual height. You could calculate the height of the toolbar and reduce it from this height to achieve your goal! If your VC is embedded in a navigation controller, you could use this

Hope this helps.

How can I change height of UIView that already has height anchor?

Additionally to @Mukesh answer is simply updating the constraint:

var heightAnchor:NSLayoutConstraint!

override func viewDidLoad() {
super.viewDidLoad()
heightAnchor = autoCompleteViewController.view.heightAnchor.constraint(equalToConstant:44.0)
heightAnchor.isActive = true
}

func changeMyHeight(numberOfSuggestions: Int) {
heightAnchor.constant = 44.0 + CGFloat(numberOfSuggestions * 45)
}

Notes:

  • You cannot fully declare this variable at the class level, as autoCompleteViewController.view is not yet instantiated.
  • You cannot set up the constraint and set isActive = true at the same time. I've always gotten a build error.


Related Topics



Leave a reply



Submit