티스토리 뷰
iOS에서 키보드가 올라오면, 뷰의 컨텐츠를 가리는 경우가 있다. 그래서 키보드의 높이에 따라서 뷰의 컨텐츠 위치를 재조정해줘야하는데, 이때 주로 사용하는 방법이
UIWindow.keyboardWillShowNotification
에 observer를 달고- notification의 userinfo 키로
UIResponder.keyboardFrameEndUserInfoKey
를 사용하여 키보드의 높이를 가져와서 뷰 컨텐츠의 높이를 재조정해준다.
keyboardFrameEndUserInfoKey
는 별 게 아니고, UIResponder에 정의된 String 타입의 클래스 프로퍼티이다. 직접 코드를 타고 들어가보면 알 수 있다.
예시 코드
UIWindow.keyboardWillShowNotification
에 observer를 달고NotificationCenter.default.addObserver( self, selector: #selector(LoginViewController.keyboardWillShow(_:)), name: UIWindow.keyboardWillShowNotification, object: nil )
- notification의 userinfo 키로
UIResponder.keyboardFrameEndUserInfoKey
를 사용하여 키보드의 높이를 가져와서 뷰 컨텐츠의 높이를 재조정해준다. @objc func keyboardWillShow(_ notification: Notification) { guard let keyboardFrameBegin = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return } let keyboardFrameBeginRect = keyboardFrameBegin.cgRectValue // 뷰 컨텐츠의 높이를 재조정 }
keyboardFrameBeginUserInfoKey
와 keyboardFrameEndUserInfoKey
차이
keyboardFrameBeginUserInfoKey
, keyboardFrameEndUserInfoKey
둘 다 값은 동일하게 키보드 사이즈 값이 나오는데 전자의 경우 맨 처음을 제외하고는 height가 줄어서 나왔다. 정상적인 동작을 원한다면 후자를 사용하자(원인을 정확하게 모르겠네요 ㅠㅠ)
그리고 keyboardFrameBeginUserInfoKey
는 키보드가 등장하는 순간이기 때문에, origin 값이 (0, 뷰의 높이값) 이다. 반면 keyboardFrameEndUserInfoKey
는 키보드가 등장을 마친 후이기 때문에 origin 값이 (0, 키보드 높이값)이다. 키보드 뷰가 생성되고 밑에서 위로 밀듯이 올라온다고 생각하면 될 것 같다.
UIWindow.keyboardWillShowNotification
알림 시기
UIWindow.keyboardWillShowNotification
는 이미 키보드가 있더라도, 다른 textField를 클릭하거나 tabRecognizer가 적용된 뷰를 터치하는 등의 행위를 했을 때에도 호출이 된다. 그래서 keyboardShown
등과 같은 Bool 타입 변수를 사용해 옵저버의 타겟함수 내에서 키보드가 현재 나타나있는지 없는지를 판단해주자.
이러한 것을 고려하고, 샌드버드의 예시코드를 참고한 최종 예시와 코드는 아래와 같다(스크롤뷰를 활용함).
@objc func keyboardWillShow(_ notification: Notification) {
guard let keyboardFrameBegin = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
let keyboardFrameBeginRect = keyboardFrameBegin.cgRectValue
if !self.keyboardShown {
let distanceFromBottom = self.view.frame.height - self.LoginButton.frame.maxY
if distanceFromBottom <= keyboardFrameBeginRect.size.height + 90 {
animateUI(keyboardFrameBeginRect.size.height)
}
}
self.keyboardShown = true
}
func animateUI(_ scrollValue: CGFloat) {
self.view.layoutIfNeeded()
self.scrollViewBottom.constant = scrollValue
let animator = UIViewPropertyAnimator(duration: 0.3, curve: .easeOut) {
self.userIdLabelTop.constant = !self.keyboardShown ? 23 : 56
self.view.layoutIfNeeded()
self.versionInfoLabel.alpha = self.keyboardShown ? 1 : 0
}
animator.startAnimation()
logoInvisible = !logoInvisible
}
예시 코드는 constraint를 아울렛변수로 사용하여 컨텐츠들의 위치를 재조정해주고 있다. 특히 self.scrollViewBottom.constant
값을 재조정해주며 versionInfoLabel.alpha
값을 애니메이션해주는 것이 되게 미려했다. 나도 나중에 써먹어야지 헤헤.
참고자료
'iOS' 카테고리의 다른 글
Swift Hashable Protocol에 대한 10가지 정리 (0) | 2021.04.30 |
---|---|
UIScrollView Auto Layout 설정하기 (0) | 2021.04.17 |
UIView의 Intrinsic Content Size 설정하기 (0) | 2021.04.05 |
collectionView 셀을 터치했을 때 효과 주기 (0) | 2021.02.26 |
iOS 키보드 내리는 방법 + UITextFieldDelegate 메소드 호출 정리 (0) | 2021.02.26 |
- Total
- Today
- Yesterday
- docker image
- 도커 이미지
- dockerfile
- 제발태그그만
- 평면모니터
- iOS #코코아터치
- 144hz모니터
- 앱출시
- 암기빵
- 한성모니터
- 카카오인턴십
- 간단정리
- tensorflow
- Swift
- 소프트웨어마에스트로11기
- 도커
- 출석하냥
- docker-compose
- docker
- 개인정보처리방침
- 데일리
- 코코아터치
- ES6
- React Native
- QHD모니터
- 왕국타이머
- ios
- docker tag
- 사이드 프로젝트
- 게이밍모니터
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |