daanyyaal
daanyyaal

Reputation: 301

Swift: Move UILabel up when keyboard appears

I'm having trouble finding out how to move a UILabel up when the keyboard appears.

Currently, the label sits about 140 pixels from the top and sits perfectly centre when the keyboard appears when I simulating using iPhone 7.

However, when using the smaller iPhone 5, I have this issue.

enter image description here

where the keyboard overlaps the UILabel.

What I'm trying to do is to centre the UILabel as the keyboard appears.

Most tutorials are showing how to move a UITextField up but I tried to apply the same aspect for the UILabel but failed.

Upvotes: 2

Views: 1581

Answers (4)

Jack G.
Jack G.

Reputation: 3941

One possible solution to move controls up when the keyboard appears is to add bottom constraints to the controls and define outlets to those constraints.

 @IBOutlet weak var controlBottomConstraint: NSLayoutConstraint!

In viewDidLoad register a keyboardWillShow method to receive the notification when the keyboard appears like:

NotificationCenter.default.addObserver(self, selector: #selector(MyViewController.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

Then in the keyboardWillShow method update the constraint (controlBottomConstraint) like this:

func keyboardWillShow(_ notification:Notification) {
  ...
    let userInfo:NSDictionary = (notification as NSNotification).userInfo! as NSDictionary
    let keyboardFrame:NSValue = userInfo.value(forKey: UIKeyboardFrameEndUserInfoKey) as! NSValue
    let keyboardRectangle = keyboardFrame.cgRectValue
    let keyboardHeight = keyboardRectangle.height
  // controlBottomConstraint outlet to the control you want to move up
  controlBottomConstraint.constant = keyboardHeight + 8
}

It also works when rotating the device.

Upvotes: 1

Amul4608
Amul4608

Reputation: 1448

First ViewController

  import UIKit

    class ViewController: UIViewController , UITableViewDelegate ,UITableViewDataSource, UITextViewDelegate {

        @IBOutlet weak var ViewSend: UIView!
        @IBOutlet weak var txtMessage: UITextView!
        @IBOutlet weak var ChatTable: UITableView!
        var chatArray:[String] = []
          var collect:String!
        override func viewDidLoad()
        {
            super.viewDidLoad()
            txtMessage.delegate = self
           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)
           print(self.ViewSend.frame.origin.y)

        }
        override func didReceiveMemoryWarning()
        {
            super.didReceiveMemoryWarning()
        }
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
        {
            return chatArray.count
        }
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "CellDemo") as! chatlableTableViewCell
            let obj = chatArray[indexPath.row]
            cell.lblchat.text = obj
            cell.lblchat.sizeToFit()
            cell.lblchat.layer.cornerRadius = 2
            cell.lblchat.clipsToBounds = true
            return cell
        }


        @IBAction func btnSendPresssed(_ sender: UIButton)
        {
                if txtMessage.text == ""
                {

                }
                else
                {

                    collect =  txtMessage.text
                    chatArray.append(collect)
                }
            ChatTable.reloadData()
            txtMessage.text = ""
        }
        func calcheight(strin:String) -> CGFloat
        {
            let label =  UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: CGFloat.greatestFiniteMagnitude))
            label.numberOfLines = 0
            label.text = strin
            label.sizeToFit()
            return label.frame.height + 2

        }
        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
        {
            let height = self.calcheight(strin: String(describing: chatArray[indexPath.row]))
            return height

        }
        func keyboardWillShow(notification: NSNotification) {

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

           if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
           {
                self.ViewSend.frame.origin.y += keyboardSize.height
            self.ChatTable.frame.size.height += (keyboardSize.height + ViewSend.frame.size.height)

           }   

        }

    }

TableView Cell

import UIKit

class chatlableTableViewCell: UITableViewCell {

    @IBOutlet weak var lblchat: UILabel!
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

Upvotes: 0

agscastaneda
agscastaneda

Reputation: 184

Try this: make an extension and add notification observers

class ViewController: UIViewController {
   var keyboardOnScreen = false

    @IBOutlet weak var searchBar: UISearchBar!
    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name:.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: .UIKeyboardWillHide, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: .UIKeyboardDidShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidHide), name: .UIKeyboardDidHide, object: nil)

        searchBar.delegate = self
    }

}
extension ViewController: UISearchBarDelegate {

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }


    func keyboardWillShow(_ notification: Notification) {
        if !keyboardOnScreen {
            view.frame.origin.y -= keyboardHeight(notification)        }
    }

    func keyboardWillHide(_ notification: Notification) {
        if keyboardOnScreen {
            view.frame.origin.y += keyboardHeight(notification)
        }
    }

    func keyboardDidShow(_ notification: Notification) {
        keyboardOnScreen = true
    }

    func keyboardDidHide(_ notification: Notification) {
        keyboardOnScreen = false
    }

    private func keyboardHeight(_ notification: Notification) -> CGFloat {
        let userInfo = (notification as NSNotification).userInfo
        let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue
        return keyboardSize.cgRectValue.height
    }

    private func resignIfFirstResponder(_ textField: UITextField) {
        if textField.isFirstResponder {
            textField.resignFirstResponder()
        }
    }

    @IBAction func userDidTapView(_ sender: AnyObject) {
        resignIfFirstResponder(textField)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }

}

Upvotes: 0

Student
Student

Reputation: 423

If you are doing constraints just change the multiplier to 0.5. If you are doing frame, set the frame's y position (yourLabel.frame.origin.y) to self.view.frame.height / 2.

Upvotes: 0

Related Questions