Move Button When Keyboard Appears Swift

Move button when keyboard appears swift

The typical way to address this would be to move the keyboard with code like this:

in ViewController class:

  func keyboardWillShow(notification: NSNotification) {

if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
if view.frame.origin.y == 0{
let height = keyboardSize.height

self.view.frame.origin.y += height
}

}

}

func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
if view.frame.origin.y != 0 {
let height = keyboardSize.height
self.view.frame.origin.y -= height
}

}
}

in ViewDidLoad method:

  NotificationCenter.default.addObserver(self, selector: Selector("keyboardWillShow:"), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: Selector("keyboardWillHide:"), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

Please Read This:
The way you are trying to solve your problem is not allowed. In the code above, if you change view to your button variable name, the button will shoot up and then fall back down. This is because Auto Layout and Programmatic layout do not work together, it is one or the other. The way you fix this is by programmatically creating that button (with CGRect), then using the code above to move only that button on keyboard press. (Do that by changing view to your button variable name.

   func keyboardWillShow(notification: NSNotification) {

if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if view.frame.origin.y == 0{
let height = keyboardSize.height
self.yourBtn.frame.origin.y += height
}
}
}

func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if view.frame.origin.y != 0 {
let height = keyboardSize.height
self.yourBtn.frame.origin.y -= height
}
}
}

To programmatically create the button you would use code similar to this:

myButton.frame = CGRect(...)

Move view with keyboard using Swift

Here is a solution, without handling the switch from one textField to another:

override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)
}

func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() {
self.view.frame.origin.y -= keyboardSize.height
}
}

func keyboardWillHide(notification: NSNotification) {
self.view.frame.origin.y = 0
}

To solve this, replace the two functions keyboardWillShow/Hide with these:

func keyboardWillShow(notification: NSNotification) {        
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() {
if view.frame.origin.y == 0 {
self.view.frame.origin.y -= keyboardSize.height
}
}
}

func keyboardWillHide(notification: NSNotification) {
if view.frame.origin.y != 0 {
self.view.frame.origin.y = 0
}
}

Swift 3.0:

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?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y == 0 {
self.view.frame.origin.y -= keyboardSize.height
}
}
}

@objc func keyboardWillHide(notification: NSNotification) {
if self.view.frame.origin.y != 0 {
self.view.frame.origin.y = 0
}
}

Swift 4.0:

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?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y == 0 {
self.view.frame.origin.y -= keyboardSize.height
}
}
}

@objc func keyboardWillHide(notification: NSNotification) {
if self.view.frame.origin.y != 0 {
self.view.frame.origin.y = 0
}
}

Swift 4.2:

override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}

@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y == 0 {
self.view.frame.origin.y -= keyboardSize.height
}
}
}

@objc func keyboardWillHide(notification: NSNotification) {
if self.view.frame.origin.y != 0 {
self.view.frame.origin.y = 0
}
}

Moving button up when keyboard is enabled

First add the textfield delegate method in your class after that simply put this code and change it according to you :-

func textFieldDidBeginEditing(_ textField: UITextField) {
switch textField {
case txtFldSponsorID:
moveTextfield(textfield: txtFldSponsorID, moveDistance: 0, up: true)
case txtFldFullName:
moveTextfield(textfield: txtFldFullName, moveDistance: -10, up: true)
case txtFldEmail:
moveTextfield(textfield: txtFldEmail, moveDistance: -10, up: true)
case txtFldMobile:
moveTextfield(textfield: txtFldMobile, moveDistance: -10, up: true)
case txtFldAddress:
moveTextfield(textfield: txtFldAddress, moveDistance: -80, up: true)
case txtFldCity:
moveTextfield(textfield: txtFldCity, moveDistance: -80, up: true)
default:
break
}
}

func textFieldDidEndEditing(_ textField: UITextField) {
switch textField {
case txtFldSponsorID:
moveTextfield(textfield: txtFldSponsorID, moveDistance: 0, up: true)
case txtFldFullName:
moveTextfield(textfield: txtFldFullName, moveDistance: 10, up: true)
case txtFldEmail:
moveTextfield(textfield: txtFldEmail, moveDistance: 10, up: true)
case txtFldMobile:
moveTextfield(textfield: txtFldMobile, moveDistance: 10, up: true)
case txtFldAddress:
moveTextfield(textfield: txtFldAddress, moveDistance: 80, up: true)
case txtFldCity:
moveTextfield(textfield: txtFldCity, moveDistance: 80, up: true)
default:
break
}
}

Move Button & View when Keyboard Appears in Swift

  1. First of write the below code into the ui view extension.

extension UIView {

func bindToKeyboard() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}

@objc func keyboardWillChange(_ notification: NSNotification) {
let duration = notification.userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as! UInt
let begginingFrame = (notification.userInfo![UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let endFrame = (notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = endFrame.origin.y - begginingFrame.origin.y

UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIView.KeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
}

}


  1. Then use that function like i have used below.

    override func viewDidLoad() {

        super.viewDidLoad()
    yourButtonName.bindToKeyboard()
    }

Hope it will be the right solution for you.

Swift: Move button above keyboard and stay

The problem you have is that you are mixing using auto-layout ant trying to manually position the button. Initially you set the position and size of the button by setting up some constraints in your viewDidLoad. Then when the keyboard appears you manually change the origin of the button which initially appears to work (it moves to where you want it). However what then happens is that when the layout of the owning view is updated the constraints are applied again thus moving the button back to where it should be. Typing text is probably enough to force the layout to happen.

To overcome this you need to adjust the constraint instead of manually setting the frame. Here is an example test class:

class ViewController: UIViewController {
@IBOutlet var testTextField: UITextField!

var testButton: UIButton!
var buttonConstraint: NSLayoutConstraint!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

testButton = UIButton(type: .custom)
testButton.backgroundColor = .green
self.view.addSubview(testButton)
testButton.translatesAutoresizingMaskIntoConstraints = false
testButton.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)

testButton.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 40).isActive = true
testButton.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -40).isActive = true

buttonConstraint = testButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10)
buttonConstraint.isActive = true

testButton.heightAnchor.constraint(equalToConstant: 50).isActive = true

self.view.layoutIfNeeded()
subscribeToShowKeyboardNotifications()
testTextField.becomeFirstResponder()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

@objc func keyboardWillShow(_ notification: Notification) {
let userInfo = notification.userInfo
let keyboardSize = userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue
let keyboardHeight = keyboardSize.cgRectValue.height
buttonConstraint.constant = -10 - keyboardHeight
}

@objc func keyboardWillHide(_ notification: Notification) {
buttonConstraint.constant = -10
}

func subscribeToShowKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: .UIKeyboardWillHide, object: nil)
}

@objc func buttonAction() {
testTextField.resignFirstResponder()
}
}

Now you will probably want to do something better than hardcoding the original position to -10 but that is up to you.

Note I have used .UIKeyboardWillShow and .UIKeyboardWillHide to make it all look good. Also to have it animate you can do this:

@objc func keyboardWillShow(_ notification: Notification) {
let userInfo = notification.userInfo
let keyboardSize = userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue
let keyboardHeight = keyboardSize.cgRectValue.height
buttonConstraint.constant = -10 - keyboardHeight

let animationDuration = userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! Double
UIView.animate(withDuration: animationDuration) {
self.view.layoutIfNeeded()
}
}

@objc func keyboardWillHide(_ notification: Notification) {
buttonConstraint.constant = -10

let userInfo = notification.userInfo
let animationDuration = userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! Double
UIView.animate(withDuration: animationDuration) {
self.view.layoutIfNeeded()
}
}

which animates the button moving along with the keyboard.

Move textfield when keyboard appears swift

There are a couple of improvements to be made on the existing answers.

Firstly the UIKeyboardWillChangeFrameNotification is probably the best notification as it handles changes that aren't just show/hide but changes due to keyboard changes (language, using 3rd party keyboards etc.) and rotations too (but note comment below indicating the keyboard will hide should also be handled to support hardware keyboard connection).

Secondly the animation parameters can be pulled from the notification to ensure that animations are properly together.

There are probably options to clean up this code a bit more especially if you are comfortable with force unwrapping the dictionary code.

 class MyViewController: UIViewController {

// This constraint ties an element at zero points from the bottom layout guide
@IBOutlet var keyboardHeightLayoutConstraint: NSLayoutConstraint?

override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(self.keyboardNotification(notification:)),
name: UIResponder.keyboardWillChangeFrameNotification,
object: nil)
}

deinit {
NotificationCenter.default.removeObserver(self)
}

@objc func keyboardNotification(notification: NSNotification) {
guard let userInfo = notification.userInfo else { return }

let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let endFrameY = endFrame?.origin.y ?? 0
let duration:TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)

if endFrameY >= UIScreen.main.bounds.size.height {
self.keyboardHeightLayoutConstraint?.constant = 0.0
} else {
self.keyboardHeightLayoutConstraint?.constant = endFrame?.size.height ?? 0.0
}

UIView.animate(
withDuration: duration,
delay: TimeInterval(0),
options: animationCurve,
animations: { self.view.layoutIfNeeded() },
completion: nil)
}
}

moving View up with textfield and Button when keyboard appear Swift

Here is solution, Create bottom layout constraint reference of send button view

@IBOutlet weak var bottomConstraint: NSLayoutConstraint!
@IBOutlet weak var sendbuttonView: UIView!

override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self)
}

@objc func handleKeyboardNotification(_ notification: Notification) {

if let userInfo = notification.userInfo {

let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue

let isKeyboardShowing = notification.name == NSNotification.Name.UIKeyboardWillShow

bottomConstraint?.constant = isKeyboardShowing ? -keyboardFrame!.height : 0

UIView.animate(withDuration: 0.5, animations: { () -> Void in
self.view.layoutIfNeeded()
})
}
}

Demo example

Move button with Keyboard, Swift

Firstly if you want to add buttons that will stick above the keyboard i recommend using "UIToolbar".

and about your P.S its pretty simple:

@objc func crossButtonTapped(_ sender:UIButton) {
self.textView.isFirstResponder ? self.textView.resignFirstResponder() :
self.textView.becomeFirstResponder()
}

Hope it helps :)

Move menu when the keyboard opens (Swift)

you can set the constraints according to the size of your screen

if self.view.height >= 800{ //For bigger screens (X ,11)
self.keyboardConstrains.constant = keyboardFrame.size.height - 50
} else {
self.keyboardConstrains.constant = keyboardFrame.size.height
}


Related Topics



Leave a reply



Submit