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 | 29 | 30 |
Tags
- 리팩토링
- uiscrollview
- Xcode
- UICollectionView
- swiftUI
- tableView
- SWIFT
- Refactoring
- ios
- 스위프트
- 클린 코드
- combine
- Human interface guide
- map
- swift documentation
- UITextView
- 리펙토링
- Clean Code
- clean architecture
- rxswift
- 애니메이션
- Observable
- MVVM
- Protocol
- collectionview
- uitableview
- ribs
- HIG
- RxCocoa
- 리펙터링
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] UISheetPresentationController, Bottom Sheet, Sheet Drawer, 애플 지도에서 사용되는 뷰 본문
iOS 응용 (swift)
[iOS - swift] UISheetPresentationController, Bottom Sheet, Sheet Drawer, 애플 지도에서 사용되는 뷰
jake-kim 2021. 10. 21. 23:16
UISheetPresentationController
- iOS 15+ 부터 제공
- 내부적으로 UIViewController안에 프로퍼티가 존재하므로, UIViewController에서 바로 사용 가능
사용 방법
- SheetPresentation에 담길 MyViewController 정의
class MyViewController: UIViewController {
lazy var tableView: UITableView = {
let view = UITableView()
view.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
view.delegate = self
view.dataSource = self
return view
}()
var dataSource = [String]()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
title = "MyViewController"
for i in 0...100 {
dataSource.append("\(i)")
}
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 30)
])
setupSheet()
addNavigationBarButtonItem()
}
private func setupSheet() {
// TODO
}
private func addNavigationBarButtonItem() {
// TODO
}
}
extension MyViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = dataSource[indexPath.row]
return cell
}
}
- setupSheet() 정의
- 디폴트로, sheet를 아래로 당기면 dismiss되는데 이 기능을 막기위해서 `isModalInPresentation = true`로 설정
- UIViewController는 내부적으로 sheetPresentationController 프로퍼티를 가지고 있으므로 그 값을 활용
- 핵심: detents (멈춤쇠라는 의미) 설정
private func setupSheet() {
/// 밑으로 내려도 dismiss되지 않는 옵션 값
isModalInPresentation = true
if let sheet = sheetPresentationController {
/// 드래그를 멈추면 그 위치에 멈추는 지점: default는 large()
sheet.detents = [.medium(), .large()]
/// 초기화 드래그 위치
sheet.selectedDetentIdentifier = .medium
/// sheet아래에 위치하는 ViewController를 흐려지지 않게 하는 경계값 (medium 이상부터 흐려지도록 설정)
sheet.largestUndimmedDetentIdentifier = .medium
/// sheet로 present된 viewController내부를 scroll하면 sheet가 움직이지 않고 내부 컨텐츠를 스크롤되도록 설정
sheet.prefersScrollingExpandsWhenScrolledToEdge = false
/// grabber바 보이도록 설정
sheet.prefersGrabberVisible = true
/// corner 값 설정
// sheet.preferredCornerRadius = 32.0
}
}
- addNavigationBarButtonItem() 정의
- medium버튼과 large버튼을 만들고 그 버튼을 탭하면 각 위치로 이동하게끔 구현
- `sheetPresentationController?.selecrtedDetentIdentifier`값 이용
private func addNavigationBarButtonItem() {
let medium = UIBarButtonItem(title: "medium", primaryAction: .init(handler: { [weak self] _Arg in
self?.sheetPresentationController?.animateChanges {
self?.sheetPresentationController?.selectedDetentIdentifier = .medium
}
}))
navigationItem.leftBarButtonItem = medium
let large = UIBarButtonItem(title: "large", primaryAction: .init(handler: { [weak self] _Arg in
self?.sheetPresentationController?.animateChanges {
self?.sheetPresentationController?.selectedDetentIdentifier = .large
}
}))
navigationItem.rightBarButtonItem = large
}
사용하는 쪽
- MyViewController를 present하여 사용
// ViewController.swift
@objc func didTapNextButton() {
showMyViewController()
}
func showMyViewController() {
let navigationController = UINavigationController(rootViewController: MyViewController())
present(navigationController, animated: true, completion: nil)
}
* 전체 소스 코드: https://github.com/JK0369/ExBottomSheet
* 참고
- https://developer.apple.com/documentation/uikit/uisheetpresentationcontroller
'iOS 응용 (swift)' 카테고리의 다른 글
[iOS - swift] UIProgressView (로딩, 프로그래스 바) (0) | 2021.10.25 |
---|---|
[iOS - swift] UILabel 라인 간 간격 (spacing, 간격, NSMutableAttributedString, ) (0) | 2021.10.23 |
[iOS - swift] UITableView, UICollectionView, 스크롤 이동 시키는 방법 (2) | 2021.10.21 |
[iOS - swift] API 호출 후 에러가 발생했을 때 Retry 구현 방법 (재시도 기능) (0) | 2021.10.19 |
[iOS - swift] 메뉴 UIMenu, UIAction, Drop Down Menu, 점 세 개 메뉴 (2) | 2021.10.18 |
Comments