Làm thế nào để có được chiều cao của Bàn phím?


Câu trả lời:


217

Trong Swift:

Bạn có thể nhận được chiều cao bàn phím bằng cách đăng ký nhận UIKeyboardWillShowNotificationthông báo. (Giả sử bạn muốn biết chiều cao sẽ là bao nhiêu trước khi nó được hiển thị).

Một cái gì đó như thế này:

Swift 2

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)

Swift 3

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

Swift 4

NotificationCenter.default.addObserver(
    self,
    selector: #selector(keyboardWillShow),
    name: UIResponder.keyboardWillShowNotification,
    object: nil
)

Sau đó, bạn có thể truy cập chiều cao trong keyboardWillShowchức năng như sau:

Swift 2

func keyboardWillShow(notification: NSNotification) {
    let userInfo: NSDictionary = notification.userInfo!
    let keyboardFrame: NSValue = userInfo.valueForKey(UIKeyboardFrameEndUserInfoKey) as! NSValue
    let keyboardRectangle = keyboardFrame.CGRectValue()
    let keyboardHeight = keyboardRectangle.height
}

Swift 3

@objc func keyboardWillShow(_ notification: Notification) {
    if let keyboardFrame: NSValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
        let keyboardRectangle = keyboardFrame.cgRectValue
        let keyboardHeight = keyboardRectangle.height
    }
}

Swift 4

@objc func keyboardWillShow(_ notification: Notification) {
    if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
        let keyboardRectangle = keyboardFrame.cgRectValue
        let keyboardHeight = keyboardRectangle.height
    }
}

Tôi không hiểu tại sao anh chàng ở đây nghĩ-in-g.net/ghawk/blog/2012/09/… lại kiểm tra isPortrait. Bàn phím keyboardRectangle.height sẽ vẫn chính xác ở tất cả các hướng?
Anton Tropashko

5
vâng, trong 3 nhanh chóng nó đã lộn xộn. đưa giá trị khác nhau mỗi lần
Mahesh Agrawal

NotificationCenter.default.addObserver (tự như công cụ chọn: #selector (keyboardWillShow), và tên: .UIKeyboardWillShow, đối tượng: nil) là đúng cú pháp
shinyuX

Điều gì sẽ xảy ra nếu bạn đã có bàn phím hiển thị và bạn xoay thiết bị, làm cách nào để tìm chiều cao bàn phím mới?
Khoury

1
Sử dụng cái này cho Swift 4 : UIResponder.keyboardWillShowNotificationin the name bit
George_E

63

Swift 3.0 và Swift 4.1

1- Đăng ký thông báo trong viewWillAppearphương thức:

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

2- Phương thức được gọi:

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        let keyboardHeight = keyboardSize.height
        print(keyboardHeight)
    }
}

3
Điều này hoạt động, bạn cũng có thể có loại keyboardWillShowtham số Notificationđể làm cho Swift 3.0 tuân thủ hơn.
bfich

1
khi chúng ta gọi hàm keyBoardWillShow (), chính xác thì chúng ta đặt đối số là gì? Tôi đã thêm dòng đầu tiên trong viewDidLoad và hàm trong lớp ... nhưng tôi không chắc cách gọi nó như thế nào haha
VDog

1
@VDog bạn không gọi nó, iOS sẽ gọi nó khi bàn phím được hiển thị
Jeremiah Nunn

4
Đăng ký nhận thông báo viewDidLoadkhông phải là một ý kiến ​​hay: bạn đặt lệnh removeObservergọi phù hợp ở đâu để khi VC này không còn được hiển thị nữa, nó sẽ ngừng nhận thông báo? Nó là tốt hơn để đưa việc đăng ký thông báo trong viewWillAppear, và sau đó đặt các removeObservercuộc gọi trongviewWillDisappear
xaphod

5
Bạn cần thay đổi "UIKeyboardFrameBeginUserInfoKey" thành "UIKeyboardFrameEndUserInfoKey" vì trong ví dụ của bạn, bạn thường có thể nhận được chiều cao bằng không. Thông tin chi tiết: stackoverflow.com/questions/45689664/…
andreylanadelrey

26

Swift 4 và các ràng buộc

Đối với chế độ xem bảng của bạn, hãy thêm một ràng buộc dưới cùng so với vùng an toàn dưới cùng. Trong trường hợp của tôi, ràng buộc được gọi là tableViewBottomLayoutConstraint.

@IBOutlet weak var tableViewBottomLayoutConstraint: NSLayoutConstraint!

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillAppear(notification:)), name: .UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear(notification:)), name: .UIKeyboardWillHide, object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow , object: nil)
    NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide , object: nil)
}

@objc 
func keyboardWillAppear(notification: NSNotification?) {

    guard let keyboardFrame = notification?.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else {
        return
    }

    let keyboardHeight: CGFloat
    if #available(iOS 11.0, *) {
        keyboardHeight = keyboardFrame.cgRectValue.height - self.view.safeAreaInsets.bottom
    } else {
        keyboardHeight = keyboardFrame.cgRectValue.height
    }

    tableViewBottomLayoutConstraint.constant = keyboardHeight
}

@objc 
func keyboardWillDisappear(notification: NSNotification?) {
    tableViewBottomLayoutConstraint.constant = 0.0
}

2
Câu trả lời đầu tiên cho bất kỳ câu hỏi nào trong số này có tính đến các khu vực an toàn. Cảm ơn!
Zach Nicoll

20

Cập nhật Swift 4.2

private func setUpObserver() {
    NotificationCenter.default.addObserver(self, selector: .keyboardWillShow, name: UIResponder.keyboardWillShowNotification, object: nil)
}

phương pháp bộ chọn:

@objc fileprivate func keyboardWillShow(notification:NSNotification) {
    if let keyboardRectValue = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        let keyboardHeight = keyboardRectValue.height
    }
}

sự mở rộng:

private extension Selector {
    static let keyboardWillShow = #selector(YourViewController.keyboardWillShow(notification:)) 
}

Cập nhật Swift 3.0

private func setUpObserver() {
    NotificationCenter.default.addObserver(self, selector: .keyboardWillShow, name: .UIKeyboardWillShow, object: nil)
}

phương pháp bộ chọn:

@objc fileprivate func keyboardWillShow(notification:NSNotification) {
    if let keyboardRectValue = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        let keyboardHeight = keyboardRectValue.height
    }
}

sự mở rộng:

private extension Selector {
    static let keyboardWillShow = #selector(YourViewController.keyboardWillShow(notification:)) 
}

tiền boa

UIKeyboardDidShowNotification hoặc UIKeyboardWillShowNotification có thể được gọi hai lần và nhận được kết quả khác nhau, bài viết này giải thích lý do tại sao được gọi hai lần.

Trong Swift 2.2

Swift 2.2 deprecates sử dụng dây cho selectors và thay vào đó giới thiệu cú pháp mới: #selector.

Cái gì đó như:

private func setUpObserver() {

    NSNotificationCenter.defaultCenter().addObserver(self, selector: .keyboardWillShow, name: UIKeyboardWillShowNotification, object: nil)
}

phương pháp bộ chọn:

@objc private func keyboardWillShow(notification:NSNotification) {

    let userInfo:NSDictionary = notification.userInfo!
    let keyboardFrame:NSValue = userInfo.valueForKey(UIKeyboardFrameEndUserInfoKey) as! NSValue
    let keyboardRectangle = keyboardFrame.CGRectValue()
    let keyboardHeight = keyboardRectangle.height
    editorBottomCT.constant = keyboardHeight
}

sự mở rộng:

    private extension Selector {

    static let keyboardWillShow = #selector(YourViewController.keyboardWillShow(_:)) 
}

3
Đừng quên để loại bỏ các quan sát viên trong deinit, ví dụ như:. NSNotificationCenter.defaultCenter () removeObserver (tự)
tapmonkey

11

Phiên bản ngắn hơn ở đây:

func keyboardWillShow(notification: NSNotification) {

        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            let keyboardHeight = keyboardSize.height
        }
}

1
bạn chuyển đối số nào cho keyboardWillShow dưới thông báo?
VDog

Khó nói, tôi đang trả lời khối mã của người đăng ... nhưng nó tương ứng với dòng này (hãy để userInfo: NSDictionary = notification.userInfo!)
Alessign

6

Swift 4 .

Phương pháp đơn giản nhất

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

func keyboardWillShow(notification: NSNotification) {  

      if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
             let keyboardHeight : Int = Int(keyboardSize.height)
             print("keyboardHeight",keyboardHeight) 
      }

}

4

Swift 5

override func viewDidLoad() {
    //  Registering for keyboard notification.
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
}


/*  UIKeyboardWillShowNotification. */
    @objc internal func keyboardWillShow(_ notification : Notification?) -> Void {
        
        var _kbSize:CGSize!
        
        if let info = notification?.userInfo {

            let frameEndUserInfoKey = UIResponder.keyboardFrameEndUserInfoKey
            
            //  Getting UIKeyboardSize.
            if let kbFrame = info[frameEndUserInfoKey] as? CGRect {
                
                let screenSize = UIScreen.main.bounds
                
                //Calculating actual keyboard displayed size, keyboard frame may be different when hardware keyboard is attached (Bug ID: #469) (Bug ID: #381)
                let intersectRect = kbFrame.intersection(screenSize)
                
                if intersectRect.isNull {
                    _kbSize = CGSize(width: screenSize.size.width, height: 0)
                } else {
                    _kbSize = intersectRect.size
                }
                print("Your Keyboard Size \(_kbSize)")
            }
        }
    }

2

// Bước 1: - Đăng ký NotificationCenter

ViewDidLoad() {

   self.yourtextfield.becomefirstresponder()

   // Register your Notification, To know When Key Board Appears.
    NotificationCenter.default.addObserver(self, selector: #selector(SelectVendorViewController.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

   // Register your Notification, To know When Key Board Hides.
    NotificationCenter.default.addObserver(self, selector: #selector(SelectVendorViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

// Bước 2: - Các Phương thức này sẽ được gọi là Tự động khi Bàn phím xuất hiện Hoặc Ẩn

    func keyboardWillShow(notification:NSNotification) {
        let userInfo:NSDictionary = notification.userInfo! as NSDictionary
        let keyboardFrame:NSValue = userInfo.value(forKey: UIKeyboardFrameEndUserInfoKey) as! NSValue
        let keyboardRectangle = keyboardFrame.cgRectValue
        let keyboardHeight = keyboardRectangle.height
        tblViewListData.frame.size.height = fltTblHeight-keyboardHeight
    }

    func keyboardWillHide(notification:NSNotification) {
        tblViewListData.frame.size.height = fltTblHeight
    }

1

Phương thức của ZAFAR007 được cập nhật cho Swift 5 trong Xcode 10

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)

}




@objc func keyboardWillShow(notification: NSNotification) {

    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        let keyboardHeight : Int = Int(keyboardSize.height)
        print("keyboardHeight",keyboardHeight)
    }

}

Điều này cung cấp các độ cao khác nhau sau lần đầu tiên nó được gọi trong quá trình thực thi chương trình.
Brandon Stillitano

0

Tôi phải làm điều này. đây là một chút hackery. không được đề xuất.
nhưng tôi thấy điều này rất hữu ích,

tôi đã tạo tiện ích mở rộng và cấu trúc

Phần mở rộng ViewController + Cấu trúc

import UIKit
struct viewGlobal{
    static var bottomConstraint : NSLayoutConstraint = NSLayoutConstraint()
}

extension UIViewController{ //keyboardHandler
 func hideKeyboardWhenTappedAround() {
    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
    tap.cancelsTouchesInView = false
    view.addGestureRecognizer(tap)
 }
 func listenerKeyboard(bottomConstraint: NSLayoutConstraint) {
    viewGlobal.bottomConstraint = bottomConstraint
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    // Register your Notification, To know When Key Board Hides.
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
 }
 //Dismiss Keyboard
 @objc func dismissKeyboard() {
    view.endEditing(true)
 }
 @objc func keyboardWillShow(notification:NSNotification) {
    let userInfo:NSDictionary = notification.userInfo! as NSDictionary
    let keyboardFrame:NSValue = userInfo.value(forKey: UIResponder.keyboardFrameEndUserInfoKey) as! NSValue
    let keyboardRectangle = keyboardFrame.cgRectValue
    let keyboardHeight = keyboardRectangle.height
    UIView.animate(withDuration: 0.5){
        viewGlobal.bottomConstraint.constant = keyboardHeight
    }
 }

 @objc func keyboardWillHide(notification:NSNotification) {
    UIView.animate(withDuration: 0.5){
        viewGlobal.bottomConstraint.constant = 0
    }
 }
}

Cách sử dụng:
nhận được hầu hết các ràng buộc dưới cùng

@IBOutlet weak var bottomConstraint: NSLayoutConstraint! // default 0

gọi hàm bên trong viewDidLoad ()

override func viewDidLoad() {
    super.viewDidLoad()

    hideKeyboardWhenTappedAround()
    listenerKeyboard(bottomConstraint: bottomConstraint)

    // Do any additional setup after loading the view.
}

Hy vọng điều này giúp đỡ.
-bàn phím của bạn bây giờ sẽ tự động đóng khi người dùng chạm vào bên ngoài trường văn bản
- nó sẽ đẩy tất cả chế độ xem lên trên bàn phím khi bàn phím xuất hiện.
-bạn cũng có thể sử dụng snoKeyboard () bất cứ khi nào bạn cần


0

Tôi sử dụng mã dưới đây,

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

func registerObservers(){

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

}

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

@objc func keyboardWillAppear(notification: Notification){
    if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
        let keyboardRectangle = keyboardFrame.cgRectValue
        let keyboardHeight = keyboardRectangle.height
        self.view.transform = CGAffineTransform(translationX: 0, y: -keyboardHeight)
    }
}

@objc func keyboardWillHide(notification: Notification){
        self.view.transform = .identity
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.