0

So I have a UIView near the bottom of the superview, with a textfield inside of it. When the user taps inside the textfield to begin editing, I am bringing up the entire UIView with the keyboard. One problem with this, is that if you have constraints on said UIView, when you start typing in the textfield, the UIView conforms to its constraints and goes back down to its original spot, hidden by the keyboard. I created a work around by overriding updateViewContraints(), removing the default constraint (the one I set in storyboard), when the textfield is being edited, and adding a new constraint to keep it where I want it. Then, when the editing ends, the code is supposed to bring the UIView back down, and remove the new constraint, and replace it with the original. Here's that code:

override func updateViewConstraints() {
    
    // The new constraint, active when the keyboard is shown
    let constraintWhenKeyboardShown = NSLayoutConstraint(item: searchRadiusView!, attribute: .bottom, relatedBy: .equal, toItem: super.view, attribute: .bottom, multiplier: 1.0, constant: -310.0)
    
    // The default constraint, active at all other times
    let defaultConstraint = NSLayoutConstraint(item: searchRadiusView!, attribute: .bottom, relatedBy: .equal, toItem: super.view, attribute: .bottom, multiplier: 1.0, constant: -30.0)
    
    if radiusTextfield.isEditing {
        view.removeConstraint(defaultConstraint)
        view.addConstraint(constraintWhenKeyboardShown)
        print("new")
    } else {
        view.removeConstraint(constraintWhenKeyboardShown)
        view.addConstraint(defaultConstraint)
        print("default")
    }
    
    self.view.layoutIfNeeded()
    super.view.updateConstraints()
}

I call the updateViewConstraints in each of my textfield methods:

// Raises the searchRadiusView upon editing
func textFieldDidBeginEditing(_ textField: UITextField) {
    let newSearchRadiusViewYValue = self.searchRadiusView.center.y - 280
    searchRadiusView.center.y = newSearchRadiusViewYValue
    
    print(searchRadiusView.constraints)
    self.updateViewConstraints()
    }

// Lowers the searchRadiusView upon dismissal
func textFieldDidEndEditing(_ textField: UITextField) {
    let newSearchRadiusViewYValue = self.searchRadiusView.center.y + 280
    searchRadiusView.center.y = newSearchRadiusViewYValue
    
    print("ended")
    print(searchRadiusView.constraints)
    self.updateViewConstraints()
}

However, upon ending editing, my UIView is not moving back down to its original position, and the debugger says

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(
"<NSLayoutConstraint:0x607000071590 UIView:0x61300002f280.bottom == UIView:0x613000071380.bottom - 310   (active)>",
"<NSLayoutConstraint:0x607000297f80 UIView:0x61300002f280.bottom == UIView:0x613000071380.bottom - 30   (active)>"
)

It seems that the 'constraintWhenKeyboardShown' constraint is still there (the one ending in -310), even though I have 'view.removeConstraint(constraintWhenKeyboardShown) ' in the updateViewConstraints() function. Is that what's causing my problem? Does anyone know how to fix this? Thanks

  • When you enter `updateViewConstraints` you create a new constraint called `constraintWhenKeyboardShown` and then try to remove it. But it was never added...you need to remove the one you created on the previous trip through that code. What you probably should do is create both constraints only once, apply them, and then control them by changing which is active. – Phillip Mills Sep 14 '20 at 19:36
  • but it was added? I literally have 'view.addConstraint(constraintWhenKeyboardShown)' –  Sep 14 '20 at 19:46
  • 2
    No, you may have previously added a constraint with the same properties, but not the constraint *instance* that you have just created. This is the wrong way to go about keyboard adjustment anyway. You should have a single constraint and animate a change in its `constant` alongside the keyboard appearance. You can observe the keyboardWillShow/Hide notifications. This notification also lets you get the actual keyboard frame as it is dynamic; the QuickType bar may or may not be present and a hardware keyboard may be attached, in which case the onscreen keyboard will not appear. – Paulw11 Sep 14 '20 at 19:53
  • See https://stackoverflow.com/questions/37875973/how-to-write-keyboard-notifications-in-swift-3 and https://stackoverflow.com/questions/41718520/nsnotificationcenter-swift-3-0-on-keyboard-show-and-hide/41719198 – Paulw11 Sep 14 '20 at 19:57
  • will check it out thanks –  Sep 14 '20 at 20:00

0 Answers0