✅ 자 이번시간에는 키보드에 따른 레이아웃을 조정해보는 시간을 가져보도록 할게요.
이번 포스팅부터는,,,! 녹화 기능을 발견해서 녹화기능도 넣어보도록 하겠습니다!
아직은 안되겠네,,, ^_^
아무튼 키보드에 따른 레이아웃 조정이 어떤건지 그림으로 보자
지금 보는 이미지처럼 텍스트 필드가 키보드에 맞게 조정되어야 사용자가 입력하는게 편하겠지? 만약에 이게 조정되지 않는다면 키보드에 텍스트 필드가 가려지는 현상이 발생할거야.
그럼 이걸 어떻게 조정하느냐?
-> bottom으로 걸린 레이아웃을 조정함으로써 변경할 수 있어. 그럼 다음은 코드를 통해 사용하는 법을 알아보도록 할까?
(목차)
1. 키보드 상태를 확인할 옵저버 설정
2. 셀렉터에 구현되 메소드를 알아보자
3. 키보드가 내려가게 만드는 제스처 달기
✅ 키보드 상태를 확인할 옵저버 설정
override func viewDidLoad() {
super.viewDidLoad()
// TODO: 키보드 디텍션
NotificationCenter.default.addObserver(self, selector: #selector(adjustInputView), name: UIResponder.keyboardWillShowNotification, object: nil)
// 키보드가 나오는게 감지 되면은 에드저스트 인풋뷰가 실행돼
NotificationCenter.default.addObserver(self, selector: #selector(adjustInputView), name: UIResponder.keyboardWillHideNotification, object: nil)
// 키보드가 들어가는게 감지 되면!! self는 이 뷰컨트롤러에서 감지하겠다.
}
키보드를 감지하기 위해서는 NotificationCenter에 옵저버를 부착하여 어떤 상태인지 확인하면 돼.
그에 따른 액션은 셀렉터를 사용하여 처리할 로직에 대한 메소드를 건네줄 수 있어.
✅ 셀렉터에 구현되 메소드를 알아보자
@objc private func adjustInputView(noti: Notification) {
guard let userInfo = noti.userInfo else { return }
// TODO: 키보드 높이에 따른 인풋뷰 위치 변경
guard let keyboardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return }
if noti.name == UIResponder.keyboardWillShowNotification {
let adjustmentHeight = keyboardFrame.height - view.safeAreaInsets.bottom
inputViewBottom.constant = adjustmentHeight
} else {
inputViewBottom.constant = 0
}
print("---> Keyboard End Frame: \(keyboardFrame)")
}
셀렉터에는 다음과 같이 구현되어 있어.
노티피케이션에 대한 정보는 아래에 참고 부분에 따로 적어두었으니, 보기로하고, 코드를 보면 userInfo는 옵저버를 통해 받아온 정보가 있는지를 확인하는 코드야.
다음으로는 keyboardFrame을 알아보자. 이 부분은 기기별 키보드 사이즈가 모두 다르겠지? 그에 대응하기 위해서 작성되는 함수인데, 애플 공식 개발문서에 따르면 keyboardFrameEndUserInfoKey는 키보드가 나타나는 애니메이션이 끝날때 프레임을 검색하는거야.
다음은 if-else문인데 notificationCenter에서 어떤 이벤트를 받아왔는지 봐야겠지?
if에는 키보드가 나타날때의 액션인데, 키보드의 높이에서 뷰의 아래쪽 safeArea를 빼주는 코드를 확인할 수 있어.
그 이유는 iPhone이 노치가 있는 하드웨어가 출시되면서, 노치에 의해 뷰가 짤려 보일 수 있기 때문에 약간의 inset(마진, 여백)을 두는데, 이걸 빼줘야 키보드에 정확하게 착 달라붙어!!
위의 그림을 보면 이해가 가지?
다음은 inputViewBottom인데, 이 변수는 레이아웃을 변수로 잡은거야.
레이아웃을 다음과 같이 잡는데, 여기서 second item에 적혀있는 View는 텍스트필드와 버튼 2개를 담고 있는 뷰야.
❗️슈퍼뷰가 아닌것에 주의
그럼 다시 코드로 돌아가서 inputViewBottom.constant를 우리가 잡은 값으로 바꿔주면? 아래쪽이 붕 뜨게 되겠지? 키보드 위에 위치하는 효과를 볼 수 있어!!
그리고 키보드가 내려간다면, 자연스럽게 이 값을 0으로 세팅해주면 다시 원래 자리를 찾아갈거야!!
✅ 키보드가 내려가게 만드는 제스처 달기
키보드를 올렸으니까, 이제 내려야겠지? 내리는 방법은 우리는 보통 키보드 이외에 여백을 클릭하면 키보드가 내려가길 바라잖아? 그렇게 구현해보도록 할게.
탭 제스쳐를 우선 달아야하는데, 검색해서 달면 돼.
UIView(슈퍼뷰) 쪽에다가 다는데, 그래야지만 뷰 터치했을때, 빠져나올 수 있다.
❗️이번에는 텍스트 포함하는 뷰 아니니까 주의
제스쳐를 장착하게 되면 도커에 세번째에 제스쳐가 장착된 모습도 확인할 수 있어.
여기서 조금 주목할만한 점은 제스쳐도 IBAction으로 설정할 수 있다는 점이야 그럼 코드를 한번 볼까?
// TODO: BG 탭했을때, 키보드 내려오게 하기
@IBAction func tapBG(_ sender: Any) {
inputTextField.resignFirstResponder()
}
제스쳐를 IBAction을 통해 연결한 코드인데, 이 코드의 의미는 애플 개발자 공식 문서에 따르면 resignFirstResponder()의 경우 "첫번째 응답자로써의 상태를 포기하라는 요청을 받았다" 라는 의미야
즉, 제스쳐가 등록된 뷰 터치시 키보드가 올라오는 텍스트 필드의 상태를 포기하라는 의미로, 포커싱을 텍스트 필드에서 뺴게 돼
그럼 이것으로 마치도록 하자
- 참고
https://developer.apple.com/documentation/uikit/uikeyboardframeenduserinfokey
https://developer.apple.com/documentation/uikit/uiresponder/1621097-resignfirstresponder
'Archive > 패캠(올인원)' 카테고리의 다른 글
📡 ch14 Networking (0) | 2021.06.28 |
---|---|
ch13 Todo 리스트 코드리뷰 (0) | 2021.06.26 |
🤪 ch13 버튼 상태에 따라 바꿔주기 (0) | 2021.06.26 |
😂 ch13 swift Equatable?! (0) | 2021.06.25 |
🦧 ch13 Static Cell (TableView) (0) | 2021.06.25 |