William Loke
William Loke

Reputation: 377

moving View up with textfield and Button when keyboard appear Swift

I know there are a few posted questions on this topic, but none of them worked. I have a tableview and under it there's a UIView that contains a textfield and button. When my keyboard appears, it covers the whole UIView, making me unable to click "Send". The image to show how my app looks like :

enter image description here

at the moment, my codes are:

 override func viewDidLoad() {
    super.viewDidLoad()
    inputTextField.delegate = self
    inputTextField.layer.cornerRadius = 5
    inputTextField.clipsToBounds = true
    sendButton.layer.cornerRadius = 5
    sendButton.clipsToBounds = true
    self.tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "TableViewCell")
    loadMsg()
    self.hideKeyboardWhenTappedAround()

}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    inputTextField.becomeFirstResponder()
}

How should I move the UIView up along with the textfield and button that is contained by the UIView when my keyboard appears?

Upvotes: 4

Views: 13908

Answers (7)

Gökhan Sayılgan
Gökhan Sayılgan

Reputation: 164

with one extension to use in all ViewControllers. Create a empty swift file copy this code inside file

import UIKit

extension UIViewController {

    func keyboardCheck() {
        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.keyboardFrameBeginUserInfoKey] 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
        }
    }

}

Then call the function inside ViewDidLoad Usage:

override func viewDidLoad() {
        super.viewDidLoad()

       self.keyboardCheck()
    }

Upvotes: 0

IOS Singh
IOS Singh

Reputation: 617

Swift 4.2

in viewDidLoad()

NotificationCenter.default.addObserver(self, selector: #selector(self.keyboard(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboard(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboard(notification:)), name:UIResponder.keyboardWillChangeFrameNotification, object: nil)

and Method

@objc func keyboard(notification:Notification) {
        guard let keyboardReact = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else{
            return
        }

        if notification.name == UIResponder.keyboardWillShowNotification ||  notification.name == UIResponder.keyboardWillChangeFrameNotification {
            self.view.frame.origin.y = -keyboardReact.height
        }else{
            self.view.frame.origin.y = 0
        }

    }

Upvotes: 3

aBilal17
aBilal17

Reputation: 3142

Just add this library into your project using POD and thats it. It will automatically do it. You have not to do anything else.

Add pod like that

pod 'IQKeyboardManagerSwift'

In AppDelegate.swift, just import IQKeyboardManagerSwift framework and enable IQKeyboardManager.

import IQKeyboardManagerSwift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

  IQKeyboardManager.shared.enable = true

  return true
 }
}

For reference please have a look on this url, https://github.com/hackiftekhar/IQKeyboardManager

Upvotes: 7

Abdelahad Darwish
Abdelahad Darwish

Reputation: 6067

You can do it by move View up with constraint here actionBarPaddingBottomConstranit is Constraint connect to your Input View Bottom constraint Check image

enter image description here

In ViewDidload :

 override func viewDidLoad() {
        super.viewDidLoad()
         self.keybordControl()
    }

Extension :

extension ViewController{

    func keybordControl(){
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

    }


    @objc func keyboardWillShow(notification: Notification) {
        self.keyboardControl(notification, isShowing: true)
    }



    @objc func keyboardWillHide(notification: Notification) {
        self.keyboardControl(notification, isShowing: false)
    }



     private func keyboardControl(_ notification: Notification, isShowing: Bool) {

        /* Handle the Keyboard property of Default, Text*/

        var userInfo = notification.userInfo!
        let keyboardRect = (userInfo[UIKeyboardFrameEndUserInfoKey]! as AnyObject).cgRectValue
        let curve = (userInfo[UIKeyboardAnimationCurveUserInfoKey]! as AnyObject).uint32Value

        let convertedFrame = self.view.convert(keyboardRect!, from: nil)
        let heightOffset = self.view.bounds.size.height - convertedFrame.origin.y
        let options = UIViewAnimationOptions(rawValue: UInt(curve!) << 16 | UIViewAnimationOptions.beginFromCurrentState.rawValue)
        let duration = (userInfo[UIKeyboardAnimationDurationUserInfoKey]! as AnyObject).doubleValue


        var  pureheightOffset : CGFloat = -heightOffset

        if isShowing {
           if #available(iOS 11.0, *) {
               pureheightOffset = pureheightOffset + view.safeAreaInsets.bottom
            }
        }
        self.actionBarPaddingBottomConstranit?.update(offset:pureheightOffset)

        UIView.animate(
            withDuration: duration!,
            delay: 0,
            options: options,
            animations: {
                self.view.layoutIfNeeded()

        },
            completion: { bool in

        })

    }
}

Upvotes: 1

iVarun
iVarun

Reputation: 6621

Call below method in ViewDidLoad:

func keyboardSettings(){
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardNotification(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
        self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
        let swipeDown = UISwipeGestureRecognizer(target: self.view , action : #selector(UIView.endEditing(_:)))
        swipeDown.direction = .down
        self.view.addGestureRecognizer(swipeDown)
    }

Then add below method for keyboard configuration:

@objc func keyboardNotification(notification: NSNotification) {

        if let userInfo = notification.userInfo {
            if let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue{
                if let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue{

                    let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
                    let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
                    let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)

                    if (endFrame.origin.y) >= UIScreen.main.bounds.size.height {
                        self.const_ViewMessage_Bottom?.constant = 0.0
                    } else {
                        self.const_ViewMessage_Bottom?.constant = endFrame.size.height
                    }

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

self.const_ViewMessage_Bottom is bottom constraint of UIView with textfield.

Upvotes: 0

iParesh
iParesh

Reputation: 2368

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

Upvotes: 4

Musavir Parambil
Musavir Parambil

Reputation: 120

Try the following code

//Declare a delegate, assign your textField to the delegate and then include these methods

-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
    return YES;
}


- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];

    [self.view endEditing:YES];
    return YES;
}


- (void)keyboardDidShow:(NSNotification *)notification
{
    // Assign new frame to your view 
    [self.view setFrame:CGRectMake(0,-110,320,460)]; //here taken -110 for example i.e. your view will be scrolled to -110. change its value according to your requirement.

}

-(void)keyboardDidHide:(NSNotification *)notification
{
    [self.view setFrame:CGRectMake(0,0,320,460)];
}

Upvotes: 1

Related Questions