필요 이유

  • 보통 커스텀 키보드를 만드는 경우에 UITextFieldinputView를 새롭게 정의해 만든다.
  • 이때 inputView를 대체할 새로운 view를 만들때 사용자마다의 각각 다른 키보드 높이에 대응해야 UX적으로 좋다.
  • 그렇기 때문에 커스텀 키보드가 올라오기전 미리 키보드의 높이를 알고 있어야만 한다.
  • 카카오톡의 경우 이모티콘 버튼을 누르면 사용자의 키보드와 동일한 높이의 inputView가 나타난다.
  • 사용자가 한 번 이라도 키보드를 사용했더라면 여기서 키보드 높이를 얻을 수 있지만, 한 번도 사용하지 않고 바로 이모티콘 버튼을 눌렀다 가정해보자.
  • 여기서 inputView는 어떻게 사용자 기기의 키보드 높이를 얻을 수 있을까?
  • 이 경우에 방법은 아래와 같다.

첫번째

  • textField1은 일반적인 키보드가 올라오는 UITextField다.
  • textField2는 커스텀 키보드가 올라온다.
  • didTapButton(_:)은 textField2를 first responder로 만든다.
import UIKit



class ViewController: UIViewController {
    // MARK: - Properties
    // MARK: Custom
    
    var keyboardHeight: CGFloat?
    
    // MARK: IBOutlet
    
    @IBOutlet weak var textField1: UITextField!
    @IBOutlet weak var textField2: UITextField!
    
    
    
    // MARK: - Methods
    // MARK: View Life Cycle
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    }
    
    // MARK: Custom
    
    @objc func keyboardWillShow(notification: NSNotification) {
        if let keyboardHeight = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height {
            self.keyboardHeight = keyboardHeight
        }
    }
    
    // MARK: IBAction
    
    @IBAction func didTapButton(_ sender: UIButton) {
        if let view = self.textField2.viewWithTag(99) {
            view.removeFromSuperview()
        }
        
        let textField = UITextField()
        self.view.addSubview(textField)
        textField.becomeFirstResponder() // 이 시점에 self.keyboardHeight에 값이 할당.
        textField.resignFirstResponder()
        textField.removeFromSuperview()
        
        guard let keyboardHeight = self.keyboardHeight else { return }
        
        let view = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: keyboardHeight))
        view.backgroundColor = UIColor.blue
        view.tag = 99
        self.textField2.inputView = view
        self.textField2.becomeFirstResponder()
    }
    
}

두번째 방법

class ViewController: UIViewController {
    // MARK: - Properties
    // MARK: Custom
    
    var keyboardHeight: CGFloat?
    
    
    
    // MARK: - Methods
    // MARK: View Life Cycle
    
    override func viewDidLoad() {
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        let textField = UITextField()
        UIApplication.shared.windows.first?.addSubview(textField)
        textField.becomeFirstResponder() // 이 시점에 self.keyboardHeight에 값이 할당
        textField.resignFirstResponder()
        textField.removeFromSuperview()
    }
    
}
  • 이렇게 하면 사용자의 키보드 높이가 변경되어도 이에 대응할 수 있다.