简体   繁体   中英

How to Programmatically Change an Auto-Layout constraint, set in IB?

This question seems to come close to what I need, but not quite...

I have a UIView (UITableView, to be precise) that has an assigned set of AL constraints, usually from IB (It's supposed to be a reusable class, so that's why "usually").

I need to nudge the bottom when the keyboard pops up. I know how to get the keyboard events and the keyboard size, so getting the number and the execution thread isn't a problem.

Nudging the bottom is. Since this is a reusable class, and the controller's purview does not extend outside the UITableView (which is where the table's lower AL constraint lives), I can't do the "tie the constraint to the controller" thing that I'd otherwise do.

This means that I need to get the constraint programmatically. If there's no constraint, then I need to know that, so I can tell the view to hitch up its skirts the old-fashioned way.

If there is a layout constraint, then I need to get the one that anchors the bottom of the table view.

Since there could be all kinds of junk there (like people assigning multiple constraints), I can't just grab the first constraint in the anchor.

I have a feeling that there's no actual solution to this, and I'll end up extending the bottom of the table view's scrollable content size, and hitching the contentOffset. That will work, but it won't be as "cool." :)

Any ideas?

You can link the constraint from IB to your code file just like you link your views.

  • open the document outline
  • Look for your tableView
  • expand its constraints
  • right-click drag from the constraint to your code file to create an outlet to the constraint

after that you can do this in code

constraintOutletName.constant = 100.0 //set the value of the constraint
override func viewDidLoad() {
    super.viewDidLoad()            
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)    
}

@objc func keyboardWillShow(notification: NSNotification) {        
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {

        self.tableViewBotCon.constant = -1 * keyboardSize.height

        self.view.layoutIfNeeded()

    }        
}

@objc func keyboardWillHide(notification: NSNotification) {

      self.tableViewBotCon.constant = 0

      self.view.layoutIfNeeded()
}

And the answer is... can I have the envelope, please? ...

"Yew Cain't Git Thar F'm Here." -At least, not in a sane manner.

Mainly because of the chaotic number of constraints that can be attached to an anchor point (including none that fit the bill).

I'm solving the issue much more simply, using the technique I already was working on (and alluded by the answers above).

I'll greencheck the answer, even though it basically said to do what I'm already doing, since it was the correct way to address the issue.

[UPDATE] Well, this is annoying. Apparently, on the iPad, it already does this in the OS, so I'm going to need to add a dratted “idiom” check.

[UPDATE 2] It's not that simple. It appears as if the iPad describes a keyboard twice the height of the one on the screen.

[UPDATE 3] Well... lookee here what I found .

[UPDATE 4] Turns out the issue is about the opening animation. I needed to look a bit further at the keyboard record. I was looking at the Y origin, when I should have been looking at the height.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM