teunteun2
[Swift] 키보드에 맞춰 ScrollView Content Inset 변경하기 본문
오늘은 제가 Sopt 합동세미나에서
주어진 뷰를 구현하면서
배우게 된 것을 공유하려고 합니다
제가 맡은 뷰는
당근마켓의 글쓰기 뷰였는데요,
이런 화면의 경우 콘텐츠를
키보드에 가려질 위치까지 작성한다면
키보드가 위로 올라왔을 땐
ScrollView의 어딘가에 키보드 크기가 반영되어야
사용자들이 키보드에 가려진 부분도
스크롤해서 볼 수 있겠죠 ?
- 순서 -
1. 키보드가 올라왔을 때, 내려갔을 때를 캐치
2. ScrollView의 contentInset 변경
1. NotificationCenter 를 통해 키보드 감지
우선 키보드가 올라왔을 때와
내려갔을 때를 감지하기 위해
특정 이벤트를 감지해서 알려주는 NotificationCenter를
viewWillAppear에 등록해주었어요
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
그리고나서
다른 곳에서 같은 노티를 사용했을 때
중복 반응되지 않도록
viewDidDisappear에서
NotificationCenter를 제거해주었습니다
보통 짝이 맞는 생명주기에서
addObserver 와 removeObserver를
구현한다고 합니다.
- ex -
viewWillAppear() <-> viewWillDisappear
viewDidLoad() <-> deinit()
전자는 뷰컨이 띄워질 때마다 호출,
후자는 한번만 호출되므로
상황에 따라 다르게 구현
그리고나서 두 경우에 실행될
selector 메서드를 구현해줘야겠죠 ?
2. ScrollView의 ContentInset 변경
2-1. keyboardWillShow(_ notification:NSNotification)
@objc func keyboardWillShow(_ notification:NSNotification) {
guard let userInfo = notification.userInfo,
let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else {
return
}
let contentInset = UIEdgeInsets(
top: 0.0,
left: 0.0,
bottom: keyboardFrame.size.height + 40,
right: 0.0)
scrollView.contentInset = contentInset
}
저는 키보드가 올라오고 내려갈 때
ScrollView의 인스턴스 중
contentInset을 변경해주었는데요,
ScrollView ContentInsent
ContentInset은 스크롤되는 영역인 ContentView가
ScrollView에서 안쪽으로 얼마나 마진이 떨어져있느냐를 의미해요
따라서 키보드가 올라왔을 때
키보드 크기만큼의 ContentInset을 Bottom에 주면 됩니다
먼저 키보드의 height을 구해주기 위해
notification 의 userInfo에서 키보드 크기를 가져왔어요
notification을 받는 곳에서
자신의 정보를 활용할 수 있도록
딕셔너리 형태로 전달되는 것이 userInfo 입니다.
키보드의 많은 userInfo 중
UIKeyboardFrameEndUserInfoKey 를 가져왔는데요,
이 userInfo는 키보드 애니메이션이 끝났을 때의
키보드 CGRect를 제공해줍니다.
저는 디자인 요청사항에
키보드 위치보다 마진을 40 정도 주었으면 좋겠다고 적혀있어
+40을 해주었어요
2-2. keyboardWillHide(_ notification:NSNotification)
@objc func keyboardWillHide(_ notification:NSNotification) {
let contentInset = UIEdgeInsets.zero
scrollView.contentInset = contentInset
}
반대로 키보드가 내려갔을 땐
다시 contentInset을 0으로 돌려놓습니다
'iOS' 카테고리의 다른 글
[Swift] 고차함수 정리(1) - Map, FlatMap, CompactMap, Filter, ForEach (0) | 2023.04.23 |
---|---|
[Xcode] SwiftGen 적용하기 (0) | 2022.09.07 |
[Swift] ReactorKit (0) | 2022.05.10 |
[Swift] Collection View Cell 내부의 Button Action (tag & delegate & closure 차이점) 코드X (0) | 2022.05.10 |
[Swift] Extension NSMutableAttributedString (0) | 2022.05.08 |