We Want
네이버 지도의 Bottom Sheet 구현
UIPanGestureRecognizer를 사용하여 사용자의 터치에 따른 화면(View or ViewController)의 이동
구현 1)
사용한 라이브러리 - PanModal
구현 아이디어 - 전체 구조
- TableView / View + Lable / Composition Layout 사용
- 각각 storyBoard로 구현후 bottomsheet로 나타나게 구현
맨 위부터
- View + Label 가장 일반적인 vc
- TableViewController를 사용한 vc
- Compositional 을 이용한 vc (코드베이스 사용)
각각 해당 Button 분기처리
import UIKit
import PanModal
class ViewController: UIViewController {
@IBOutlet weak var tableModal: UIButton!
@IBOutlet weak var halfModal: UIButton!
@IBOutlet weak var comPose: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func onModalClick(_ sender: UIButton) {
switch sender {
case tableModal:
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MyTableVC") as! MyTableVC
presentPanModal(vc)
print("전체창")
case halfModal:
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MySimpleVC") as! MySimpleVC
presentPanModal(vc)
print("modal")
case comPose:
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ComposeVC") as! ComposeVC
presentPanModal(vc)
print("compose")
default: break
}
}
}
각 VC 기본 구조
import Foundation
import UIKit
import PanModal
class MyTableVC: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
extension MyTableVC: PanModalPresentable {
var panScrollable: UIScrollView? {
return tableView
}
//한번 눌려서 기본적으로 나오는 view 사이즈
var shortFormHeight: PanModalHeight {
return .contentHeight(300)
}
//펼쳤을때 top과 얼만큼 떨어졋는가
var longFormHeight: PanModalHeight {
return .maxHeightWithTopInset(100)
}
var anchorModalToLongForm: Bool {
//true면 화면 최상단까지 스크롤 안됨
return false
//false면 화면 최상단까지 스크롤 됨
}
}
결과
구현 2
구현 아이디어 - 전체 구조
FloatingPanel 사용해보기
- 참고할 Github SCENEE Github
우선 자신의 프로젝트를 만들고 cocoapod에 FloatingPanel을 install해준다.
ContentVC
mainViewController 위로 올라올 tableview를 만드는 작업을 한다.
import UIKitclass
ContentVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet var tableView: UITableView!let data = [
"NewYork",
"Seoul",
"Toronto",
"Boston",
"Paris",
"LA",
]
override func viewDidLoad() {
super.viewDidLoad()
*// 커스텀 셀을 만들어준다*tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.delegate = selftableView.dataSource = self}
*// data의 수만큼 행이 만들어진다.*func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
*// 해당 셀에 들어갈 데이터를 지정해준다.*func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = data[indexPath.row]
return cell
}
}
MainVC
import UIKitimport FloatingPanelclass MainVC: UIViewController, FloatingPanelControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
*// FloatingPanelController를 하나 생성해준다*
let fcp = FloatingPanelController()
fcp.delegate = self*// storyboardID가 FPC_content인 컨트롤러가 있는지 없는지 확인*guard let contentViewcontroller = storyboard?.instantiateViewController(identifier: "FPC_content") as? ContentVC else {
return}
*// contentViewController 설정*
fcp.set(contentViewController: contentViewcontroller)
*//`FloatingPanelController` 개체가 관리하는 뷰를 self.view에 추가하고 표시*
fcp.addPanel(toParent: self)
}
}
Storyboard
주의해야할 점
- storyboardID를 반드시 작성할 것
- tableView cell을 끌어다놓지 않았다는 점
- 주의해야할 점은 아니지만 MainVC에 MapViewKit를 사용했다는 점
결과
'IOS - Swift' 카테고리의 다른 글
[iOS/Swift] 앱스토어 배포와 리젝일기 (0) | 2023.10.29 |
---|---|
[iOS/Swift] 앱스토어 게임 탭 따라하기 (Composition Layout) (0) | 2023.10.01 |
[iOS/Swift] Run Loop ( 2 / 2 ) (1) | 2023.08.27 |
[iOS/Swift] Run Loop - (1 / 2) (0) | 2023.08.20 |
[iOS/Swift] UIkit image Resizing ( 크기 / 품질) (0) | 2023.08.06 |