Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- rxswift
- collectionview
- Observable
- 리펙터링
- 스위프트
- 리펙토링
- Refactoring
- 애니메이션
- ribs
- Xcode
- UITextView
- combine
- RxCocoa
- SWIFT
- Clean Code
- HIG
- MVVM
- 클린 코드
- 리팩토링
- uiscrollview
- swiftUI
- Protocol
- Human interface guide
- UICollectionView
- map
- uitableview
- clean architecture
- swift documentation
- ios
- tableView
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 키보드 업 동작 시 다른 뷰들도 올라가게끔 하는 방법 (UIView.transition), 키보드 내리기 본문
iOS 응용 (swift)
[iOS - swift] 키보드 업 동작 시 다른 뷰들도 올라가게끔 하는 방법 (UIView.transition), 키보드 내리기
jake-kim 2021. 12. 27. 01:52
기본 지식 - UIView.transition
- transition은 container view 관련된 곳에 애니메이션을 사용할 때 사용
- 키보드를 올릴 때, 그 위에있는 뷰를 UIView.transition 사용하여 올라가도록 하는데에 사용
- 주의) UIView.animate vs UIView.transition
- animate: 프로퍼티 개별적인 애니메이션 (ex- 뷰 확대, 축소, alpha값 변경)
- transition: 전체적인 스크린에서 동작 (뷰 이동)
구현 아이디어
- 뷰 정의
- 키보드를 감싸는 뷰, keyboardWrapperView 정의
- 키보드를 감싸는 뷰 위쪽 keyboardSafeAreaView 정의
- auto layout으로 두 뷰의 레이아웃 정의
- 키보드의 높이가 변경될 때, keybaordWrapperView의 높이를 updateConstraints
- 위 뷰들을 BaseViewController에 정의하고 일반 ViewController에서 키보드 업할때 적용할 뷰를 keybaordSafeAreaView에 addSubview하여 사용
BaseViewController에 키보드 관련 뷰 구현
- 사용할 프레임워크
pod 'SnapKit' pod 'RxKeyboard'
- BaseViewController 생성
import UIKit import SnapKit import RxSwift import RxCocoa import RxKeyboard class BaseViewController: UIViewController { }
- 키보드 관련 뷰 정의
// MARK: UI private let keyboardWrapperView: PassThroughView = { let view = PassThroughView() view.isUserInteractionEnabled = false return view }() let keyboardSafeAreaView: PassThroughView = { let view = PassThroughView() return view }()
- 프로퍼티 정의
// MARK: Properties private let disposeBag = DisposeBag() private let keyboardHeight = BehaviorRelay<CGFloat>(value: 0)
- viewDidLoad()에서 뷰 레이아웃 정의
- RxKeyboard로 keyboard의 높이 획득
- keyboard 높이를 획득하면, keyboardWrapperView의 높이를 updateConstraints를 통해 갱신
- keyboardWrapperView의 높이가 변하면 그 위에있는 keyboardSafeAreaView도 자동으로 auto layout에 의하여 갱신
override func viewDidLoad() { super.viewDidLoad() self.view.addSubview(self.keyboardWrapperView) self.view.addSubview(self.keyboardSafeAreaView) RxKeyboard.instance.visibleHeight .asObservable() .filter { 0 <= $0 } .bind { [weak self] in self?.keyboardHeight.accept($0) } .disposed(by: disposeBag) self.keyboardWrapperView.snp.makeConstraints { $0.left.right.bottom.equalToSuperview() $0.height.equalTo(0).priority(.high) } self.keyboardSafeAreaView.snp.makeConstraints { $0.top.left.right.equalToSuperview() $0.bottom.equalTo(self.keyboardWrapperView.snp.top) } self.keyboardHeight .withUnretained(self) .bind(onNext: { ss, height in ss.updateKeyboardHeight(height) UIView.transition( with: ss.keyboardWrapperView, duration: 0.25, options: .init(rawValue: 458752), animations: ss.view.layoutIfNeeded ) }) .disposed(by: disposeBag) } private func updateKeyboardHeight(_ height: CGFloat) { self.keyboardWrapperView.snp.updateConstraints { $0.height.equalTo(self.keyboardHeight.value).priority(.high) } }
사용하는 쪽
- BaseViewController 상속
import UIKit import SnapKit class ViewController: BaseViewController { }
- keyboard가 위로 올라오면, 같이 올라가게 하고싶은 뷰는 BaseViewController에 정의한 keyboardSafeAreaView.addSubview()로 추가
private let sampleTextField: UITextField = { let textField = UITextField() textField.textColor = .black textField.borderStyle = .roundedRect return textField }() private let myImageView: UIImageView = { let view = UIImageView() view.image = UIImage(systemName: "star.fill") return view }() override func viewDidLoad() { super.viewDidLoad() self.view.addSubview(self.sampleTextField) self.keyboardSafeAreaView.addSubview(myImageView) // <- 키보드가 올라가면 같이 따라 올라가게끔 keyboardSafeAreaView에 추가 self.sampleTextField.snp.makeConstraints { $0.top.equalToSuperview().inset(56) $0.left.right.equalToSuperview().inset(16) } self.myImageView.snp.makeConstraints { $0.centerX.equalToSuperview() $0.bottom.equalToSuperview().inset(150) // <- 현재 superView는 키보드를 덮고있는 뷰이므로, 키보드 높이에 종속적인 레이아웃 } }
키보드 내리기
- ViewController에서 touchesEnded(_:with:)을 오버라이딩하여 self.view.endEditing(true) 호출
// ViewController.swift
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
self.view.endEditing(true)
}
* 전체 소스 코드: https://github.com/JK0369/ExKeyboard
* 참고
- UIView.animate vs UIView.transition: 도서 - Beginning iPhone Games Development (PJ Cabrera, Peter Bakhirev)
'iOS 응용 (swift)' 카테고리의 다른 글
Comments