개발/Swift
[Swift] Tab bar 와 Page view를 동시에 사용할때
덤벨로퍼
2024. 5. 18. 13:40
문제
Tab bar 와 UIPageViewController
스와이핑이 가능하면서 동시에 탭바 선택으로 ViewController를 움직이고 싶을때
TabbarController 와 UIPageViewController 동시에 사용 할 경우 생각보다 예시가 많이 없고 정상 동작 하지 않았다.
TabbarController 는 또한 UI 커스텀이 쉽지 않았다.
해결
UIPageViewController 를 사용하여 페이지 관리 를 하고 ( 스와이프 가능 )
Tab Bar UI는 직접 커스텀하게 구현
구현
- TabBar 에서는 Rx 사용하여 클릭 이벤트 전달함
UIPageViewController 설정
private lazy var pageViewController = {
let pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
pageViewController.dataSource = self
pageViewController.delegate = self
return pageViewController
}()
private lazy var pages: [UIViewController] = [maleViewController, femaleViewController]
private let maleViewController = UserListViewController()
private let femaleViewController = UserListViewController()
UIPageViewController DataSource 및 Delegate 구현
extension ViewController: UIPageViewControllerDataSource, UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = pages.firstIndex(of: viewController), viewControllerIndex > 0 else {
return nil
}
return pages[viewControllerIndex - 1]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = pages.firstIndex(of: viewController),
viewControllerIndex < pages.count - 1 else {
return nil
}
return pages[viewControllerIndex + 1]
}
// 페이지 스와이핑 -> Tab bar 에 전달
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if let visibleViewController = pageViewController.viewControllers?.first,
let index = pages.firstIndex(of: visibleViewController) {
tabButtonView.select(index: index)
}
}
}
Delegate 메소드를 통해 스와이핑 액션 발생시 페이지 return 구현 쉽게 가능 하며
현재 페이지 값을 탭바에 전달할수 있다.
Tab Bar 커스텀 및 이벤트 바인딩
private let tabButtonView = TabButtonView(typeList: [.male, .female])
tabButtonView.selectedType.bind { [weak self] type in
guard let self = self else { return }
switch type {
case .male:
pageViewController.setViewControllers([pages[0]], direction: .reverse, animated: true, completion: nil)
case .female:
pageViewController.setViewControllers([pages[1]], direction: .forward, animated: true, completion: nil)
}
}.disposed(by: disposeBag)
탭바 클릭시 이벤트를 전달받아서 Page ViewController 에 전달 해줌