Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
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
Archives
Today
Total
관리 메뉴

teunteun2

[Swift] 키보드에 맞춰 ScrollView Content Inset 변경하기 본문

iOS

[Swift] 키보드에 맞춰 ScrollView Content Inset 변경하기

teunteun2 2022. 5. 21. 11:10

오늘은 제가 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으로 돌려놓습니다