카테고리 없음
[Swift - UIKit] 키보드 사용시 뷰 올리기, NotificationCenter
분홍이귀여워
2024. 11. 8. 14:54
반응형
키보드가 올라갈때 뷰를 가리게 되는 경우가 있다. 나의 경우 테이블뷰가 가려졌고 키보드가 올라갈때 테이블뷰도 y축으로 이동시키고 싶었다. 이 경우 NotificationCenter 를 이용해 키보드가 올라갔는지 내려갔는지를 보고받고 그에따라 키보드의 높이만큼 뷰를 올리거나 내려주면 불편함 없이 키보드를 사용할 수 있다.
1. 테이블뷰의 하단 제약조건을 변수에 저장하기
lazy var tableViewBottomAnchorConstraint = tableView.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor, constant: 0)
func setupConstraints() {
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: self.safeAreaLayoutGuide.topAnchor, constant: 0),
tableView.leadingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.leadingAnchor, constant: 0),
tableView.trailingAnchor.constraint(equalTo: self.safeAreaLayoutGuide.trailingAnchor, constant: 0),
tableViewBottomAnchorConstraint
])
}
2. NotificationCenter 이벤트 등록
func setupKeyboardNotifications(showSelector: Selector, hideSelector: Selector) {
//키보드가 올라갈때 관찰후 알림
NotificationCenter.default.addObserver(self, selector: showSelector, name: UIResponder.keyboardWillShowNotification, object: nil)
//키보드가 내려갈때 관찰후 알림
NotificationCenter.default.addObserver(self, selector: hideSelector, name: UIResponder.keyboardWillHideNotification, object: nil)
}
addObserver -> 특정 이벤트가 발생할때 알림을 받겠다.
selector -> 알람이 발생했을때 실행할 메서드의 이름
name -> 어떤 종류의 알림을 수신할지
object -> 알림을 발송한 특정 객체를 지정할 수 있으며, nil이면 모든 객체로부터의 알림을 수신
여기서 name, 알림이름은 여러 종류가 있으며 키보드 관련 대표적인 것은 아래와 같다.
나는 키보드가 화면에 나타날때와 사라지기 직전을 선택했다.
- UIResponder.keyboardWillShowNotification: 키보드가 화면에 나타날 때 발송
- UIResponder.keyboardDidShowNotification: 키보드가 완전히 화면에 나타난 후에 발송
- UIResponder.keyboardWillHideNotification: 키보드가 화면에서 사라지기 직전에 발송
- UIResponder.keyboardDidHideNotification: 키보드가 완전히 사라진 후에 발송
- UIResponder.keyboardWillChangeFrameNotification: 키보드의 프레임이 변경되기 직전에 발송 (예: 회전할 때).
- UIResponder.keyboardDidChangeFrameNotification: 키보드의 프레임이 변경된 후에 발송
3. 함수 정의
//노티피케이션 셋팅
func setupNotification() {
setupKeyboardNotifications(showSelector: #selector(moveUpAction), hideSelector: #selector(moveDownAction))
}
@objc func moveUpAction(notification: NSNotification) {
adjustForKeyboard(notification: notification, bottomConstraint: todayTodoview.tableViewBottomAnchorConstraint)
}
@objc func moveDownAction() {
resetAfterKeyboardDismiss(bottomConstraint: todayTodoview.tableViewBottomAnchorConstraint)
}
3-1. 키보드가 올라갔을때
키보드가 올라갈때는 adjustForKeyboard 함수를 통해 키보드의 높이를 구하여 테이블뷰의 하단 제약조건 constant: 0 에서 키보드 높이만큼 - 해준다. 반대로 키보드가 내려갈때는 제약조건 - 에서 0으로 돌려준다.
//키보드 올라갈때 실행하는 함수 -> 키보드 높이를 구해서 테이블뷰 하단 제약조건 변경
func adjustForKeyboard(notification: NSNotification, bottomConstraint: NSLayoutConstraint) {
//키보드 높이 구하기
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue) {
let keyboardHeight = keyboardSize.cgRectValue.height
if bottomConstraint.constant == 0 { //테이블뷰 하단 제약조건 키보드 높이만큼 -
bottomConstraint.constant -= keyboardHeight
}
}
}
3-2. 키보드가 내려갔을때
//키보드 내려갈때 실행하는 함수 -> 테이블뷰 위치 제자리로 돌리기
func resetAfterKeyboardDismiss(tableView: UITableView, bottomConstraint: NSLayoutConstraint) {
if bottomConstraint.constant != 0 {
bottomConstraint.constant = 0
}
}
4. 이벤트 해제
화면이 종료되어 더이상 알림이 필요하지 않을경우 메모리 누수 방지를 위해 옵저버를 해제한다
func removeKeyboardNotifications() {
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
deinit {
removeKeyboardNotifications()
}
코드 전체보기
나는 여러개의 뷰컨트롤러에서 사용하기 위해 확장을 이용했다.
import UIKit
extension UIViewController {
//이벤트 등록
func setupKeyboardNotifications(showSelector: Selector, hideSelector: Selector) {
//키보드가 올라갈때 관찰후 알림
NotificationCenter.default.addObserver(self, selector: showSelector, name: UIResponder.keyboardWillShowNotification, object: nil)
//키보드가 내려갈때 관찰후 알림
NotificationCenter.default.addObserver(self, selector: hideSelector, name: UIResponder.keyboardWillHideNotification, object: nil)
}
//키보드 올라갈때 실행하는 함수 - 키보드 높이를 구해서 테이블뷰 하단 제약조건 변경
func adjustForKeyboard(notification: NSNotification, bottomConstraint: NSLayoutConstraint) {
//키보드 높이 구하기
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue) {
let keyboardHeight = keyboardSize.cgRectValue.height
if bottomConstraint.constant == 0 { //테이블뷰 하단 제약조건 키보드 높이만큼 -
bottomConstraint.constant -= keyboardHeight
}
}
}
//키보드 내려갈때 실행하는 함수 - 테이블뷰 위치 제자리로 돌리기
func resetAfterKeyboardDismiss(bottomConstraint: NSLayoutConstraint) {
if bottomConstraint.constant != 0 {
bottomConstraint.constant = 0
}
}
//이벤트 해제
func removeKeyboardNotifications() {
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
}
UIViewController
import UIKit
class YourViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupNotification()
}
//노티피케이션 셋팅
func setupNotification() {
setupKeyboardNotifications(showSelector: #selector(moveUpAction), hideSelector: #selector(moveDownAction))
}
@objc func moveUpAction(notification: NSNotification) {
adjustForKeyboard(notification: notification, bottomConstraint: todayTodoview.tableViewBottomAnchorConstraint)
}
@objc func moveDownAction() {
resetAfterKeyboardDismiss(bottomConstraint: todayTodoview.tableViewBottomAnchorConstraint)
deinit {
removeKeyboardNotifications()
}
}
반응형