iOS/코드조각

[iOS, Swift] Keyboard로 인해 가려진 뷰 올리기

검은참깨두유vm 2023. 2. 22. 00:01
반응형

iOS 16.1, Xcode 14.2, Swift 5, UIKit 환경에서 진행했습니다.

 

 

먼저 ViewDidLoad 함수에 키보드가 올라가거나 내려가는 Notification을 구독합니다.

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

UIResponder를 통해 사용자가 키보드를 올리거나 내리는 것을 감지할 수 있습니다.

 

그 후 키보드 높이를 구하고, 올라갈 때에 맞춰 뷰의 높이를 올려주거나 내려갈 때에 뷰의 높이를 내려줍니다.

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

        UIView.animate(withDuration: 1) {
        	// 키보드가 올라올 때, 뷰의 높이를 변경함
            self.alienBtn.frame.origin.y -= keyboardHeight - self.notchBottom
            self.changedNumberBtn.frame.origin.y -= keyboardHeight - self.notchBottom
            self.nextBtn.frame.origin.y -= keyboardHeight - self.notchBottom
        }
    }
}

@objc func keyboardWillHide(_ sender: NSNotification) {
    if let keyboardFrame: NSValue = sender.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
        let keyboardRectangle = keyboardFrame.cgRectValue
        let keyboardHeight = keyboardRectangle.height

        UIView.animate(withDuration: 1) {
        	// 키보드가 내려올 때, 뷰의 높이를 변경함
            self.alienBtn.frame.origin.y += keyboardHeight - self.notchBottom
            self.changedNumberBtn.frame.origin.y += keyboardHeight - self.notchBottom
            self.nextBtn.frame.origin.y += keyboardHeight - self.notchBottom
        }
    }
}

safe Area 때문에 올라오는 높이가 다르다면, notchBottom 변수를 사용한 것과 같이 notch의 높이를 구해줍니다.

 

SafeArea 높이 구하기https://bksesame.tistory.com/199

 

 

그리고 편의에 따라 View를 클릭할 때에 TextField의 키보드가 내려가는 역할을 해주게끔 설정합니다.

 override func viewDidLoad() {
    ...
    
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapView(_:))))

    phoneTf.becomeFirstResponder()
}

@objc func didTapView(_ sender: UIGestureRecognizer) {
    view.endEditing(true)
}

 

 

 

전체 소스 코드

 

let notchBottom = UIApplication.shared.windows.first?.safeAreaInsets.bottom ?? 0

override func viewDidLoad() {
    super.viewDidLoad()
    
    setKeyboardObserver()
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapView(_:))))

    phoneTf.becomeFirstResponder()
}

@objc func didTapView(_ sender: UIGestureRecognizer) {
    view.endEditing(true)
}

func setKeyboardObserver() {
    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(_ sender: NSNotification) {
    if let keyboardFrame: NSValue = sender.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
        let keyboardRectangle = keyboardFrame.cgRectValue
        let keyboardHeight = keyboardRectangle.height

        UIView.animate(withDuration: 1) {
            self.alienBtn.frame.origin.y -= keyboardHeight - self.notchBottom
            self.changedNumberBtn.frame.origin.y -= keyboardHeight - self.notchBottom
            self.nextBtn.frame.origin.y -= keyboardHeight - self.notchBottom
        }
    }
}

@objc func keyboardWillHide(_ sender: NSNotification) {
    if let keyboardFrame: NSValue = sender.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
        let keyboardRectangle = keyboardFrame.cgRectValue
        let keyboardHeight = keyboardRectangle.height

        UIView.animate(withDuration: 1) {
            self.alienBtn.frame.origin.y += keyboardHeight - self.notchBottom
            self.changedNumberBtn.frame.origin.y += keyboardHeight - self.notchBottom
            self.nextBtn.frame.origin.y += keyboardHeight - self.notchBottom
        }
    }
}

 

 

 

 

참조

https://developer.apple.com/documentation/uikit/uiresponder/1621578-keyboardframeenduserinfokey

반응형