iOS) UISheetPresentationController 에서 키보드를 사용해보자
text field 를 통해 키보드를 사용하게 되면 어떻게 되는지 알아보겠습니다. 우선, 결과는 WWDC21 Customize and resize sheets in UIKit 에서 등장합니다.
키보드와 관련된 스크립트를 살펴보겠습니다.
medium 높이의 sheet 는 automatic keyboard avoidance 를 지원해서 keyboard 를 계산해서 커지거나 축소된다고 합니다.
우리는 결과를 알지만, custom detent 의 높이에도 자연스럽게 적용되는지 확인해보겠습니다.
👉 확인해보자
두 가지를 살펴보겠습니다.
첫 번째는 UISheetPresentationController 의 detents 프로퍼티에 두 가지 detent 를 설정하겠습니다.
- 코드
let sheetVC = SheetVC()
let detentIdentifier = UISheetPresentationController.Detent.Identifier("tagSheet")
let customDetent = UISheetPresentationController.Detent.custom(identifier: detentIdentifier) { _ in
return 270
}
if let sheet = sheetVC.sheetPresentationController {
sheet.detents = [customDetent, .large()] // detent 설정
// ...
}
- 결과
키보드가 활성되는 순간 large detent 로 높이가 설정되었습니다.
large detent 를 제거해보겠습니다.
두 번째는 detents 에 custom detent 만 설정하겠습니다.
- 코드
// ...
if let sheet = tagSheet.sheetPresentationController {
sheet.detents = [customDetent] // detent 설정
// ...
}
- 결과
키보드가 활성화되었을 때 키보드 만큼 위로 올라가는 것을 확인할 수 있었습니다.
❓ 궁금증
detents 가 두 개 보다 많을 때는 어떻게 작동할까요?
custom detent(높이 270), medium, large 를 사용해보겠습니다.
// ...
if let sheet = tagSheet.sheetPresentationController {
sheet.detents = [customDetent, .medium(), .large()] // detent 설정
// ...
}
스크롤에 따라서 세 개의 detent 모두 확인할 수 있었고, 키보드가 활성화되면 가장 큰 detnet 에 맞춰서 automatic keyboard avoidance 가 적용되는 것을 확인하였습니다.
❗️ 결과적으로, 다음과 같이 알 수 있었습니다.
- custom detent 도 automatic keyboard avoidance 가 적용됩니다.
- detent 가 두 개 이상이라면, 가장 큰 detent 에 맞춰서 automatic keyboard avoidance 가 적용됩니다.
👉 요구사항
다음의 요구사항을 구현해보겠습니다.
- sheet 를 띄우는 동시에 키보드도 띄우고, sheet 가 사라질 때 키보드도 사라지게 해봅시다.
UISheetPresentationController 를 사용할 때 뷰 컨트롤러의 라이프 사이클에 대해서 알아야 자연스럽게 적용할 수 있을 것 같습니다.
View Life Cycle
우선, UISheetPresentationController 역할을 하는 뷰 컨트롤러에 다음과 같이 현재 라이프 사이클을 알 수 있도록 UI 를 작성하여 보겠습니다.
그리고 detent 를 변경하고, dimming view 를 터치하여 바텀시트를 내리거나 grabber 를 사용하여 바텀시트를 내릴 때 어떤 라이프 사이클인지 확인해보겠습니다.
- grabber 잡고 내릴때 viewWillDisappear 호출되고, medium detent 로 돌려놓으면 viewWillAppear -> viewDidAppear 호출됩니다.
결과물로도 확인해보겠습니다.
- viewWillAppear(_:) 에서 키보드를 활성화하는 것이 가장 자연스러웠습니다.
- grabber 를 통해 일정 높이 이상 sheet 를 내리게 되면 keyboard 가 사라졌습니다.(view life cycle 과는 별개로 automatic keyboard avoidance 가 적용되기 때문인 것 같습니다.)
- dimming view 를 터치하여 sheet 를 한번에 내릴때 역시 별도의 작업 없이 자연스러웠습니다.
override func viewWillAppear(_ animated: Bool) {
super.viewDidAppear(animated)
textFiled.becomeFirstResponder()
}
🚨트러블 슈팅
- viewWillAppear(:) 에서 키보드를 띄우다보니 grabber 을 잡고 동작하다가 다시 detent 로 돌려놓으면 viewWillAppear(:) 가 호출되어서 키보드가 원치 않는 상황에 다시금 등장하게 되었습니다.
- flag 역할을 할 수 있는 변수를 사용하여 해결하였습니다.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// flag 역할
if !keyboardOn {
adjectiveTextFiled.becomeFirstResponder()
keyboardOn = true
}
}