반응형
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
반응형
'iOS > 코드조각' 카테고리의 다른 글
[iOS, Swift] 라디오버튼 구현하기 (0) | 2023.02.25 |
---|---|
[iOS, Swift] 체크박스 구현하기 (0) | 2023.02.24 |
[iOS, Swift] Safe Area 높이 구하기 (0) | 2023.02.21 |
[iOS, Swift] DocumentPicker 사용예제 (0) | 2023.02.20 |
[iOS, Swift] UITextField 키보드 스타일 변경하기 (0) | 2023.02.20 |