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
- Protocol
- clean architecture
- Refactoring
- ios
- Xcode
- ribs
- rxswift
- UITextView
- HIG
- 클린 코드
- MVVM
- 애니메이션
- swiftUI
- tableView
- collectionview
- map
- Observable
- Human interface guide
- combine
- swift documentation
- RxCocoa
- 리펙터링
- uitableview
- uiscrollview
- SWIFT
- UICollectionView
- 리펙토링
- Clean Code
- 리팩토링
- 스위프트
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] UIPageViewController의 첫 페이지, 마지막 페이지 Scroll disable 방법 본문
iOS 응용 (swift)
[iOS - swift] UIPageViewController의 첫 페이지, 마지막 페이지 Scroll disable 방법
jake-kim 2023. 1. 25. 23:59UIPageViewController 첫 페이지와 마지막 페이지 스크롤 disable 방법
- UIPageViewController의 일반적인 경우
- 첫번째 페이지에서 swipe left to right를 해도 스크롤 (bounce)
- 마지막 페이지에서 swipe right to left를 해도 스크롤 (bounce)
- 첫번째 페이지와 마지막 페이지에서 bounce 효과를 없애는 방법?
구현 방법
- UIPageViewController에는 내부적으로 UIScrollView가 있는데, 이 스크롤뷰를 스크롤 할때마다 bounces 프로퍼티를 가지고 on/off 시도하여 구현
- 기본 PageViewController UI 준비
- PageViewController 내부에는 LabelViewController가 있는 구성
import UIKit
class ViewController: UIViewController {
private let pageVC: UIPageViewController = {
let pageVC = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
pageVC.view.translatesAutoresizingMaskIntoConstraints = false
return pageVC
}()
private var items = (0...2).map(String.init)
fileprivate var contentViewControllers = [UIViewController]()
var currentPageIndex: Int {
contentViewControllers
.enumerated()
.first(where: { _, vc in vc == pageVC.viewControllers?.first })
.map(\.0) ?? 0
}
override func viewDidLoad() {
super.viewDidLoad()
setUpViewControllers()
setUpViews()
setUpLayout()
}
private func setUpViewControllers() {
items
.forEach { title in
let vc = LabelViewController() // 단순히 UILabel을 가지고 있는 VC
vc.titleText = title
contentViewControllers.append(vc)
}
}
private func setUpViews() {
pageVC.dataSource = self
addChild(pageVC)
pageVC.didMove(toParent: self)
pageVC.setViewControllers([contentViewControllers[0]], direction: .forward, animated: false)
}
private func setUpLayout() {
view.addSubview(pageVC.view)
NSLayoutConstraint.activate([
pageVC.view.leftAnchor.constraint(equalTo: view.leftAnchor),
pageVC.view.rightAnchor.constraint(equalTo: view.rightAnchor),
pageVC.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
pageVC.view.topAnchor.constraint(equalTo: view.topAnchor),
])
}
}
extension ViewController: UIPageViewControllerDataSource {
// left -> right 스와이프 하기 직전 호출 (다음 화면은 무엇인지 리턴)
func pageViewController(
_ pageViewController: UIPageViewController,
viewControllerBefore viewController: UIViewController
) -> UIViewController? {
guard let index = contentViewControllers.firstIndex(of: viewController) else { return nil }
let previousIndex = index - 1
guard previousIndex >= 0 else { return nil }
return contentViewControllers[previousIndex]
}
// right -> left 스와이프 하기 직전 호출 (이전 화면은 무엇인지 리턴)
func pageViewController(
_ pageViewController: UIPageViewController,
viewControllerAfter viewController: UIViewController
) -> UIViewController? {
guard let index = contentViewControllers.firstIndex(of: viewController) else { return nil }
let nextIndex = index + 1
guard nextIndex < contentViewControllers.count else { return nil }
return contentViewControllers[nextIndex]
}
}
- PageViewController에서 scrollView를 찾아서, delegate = self 로 할당
// 1.
let scrollView = pageVC.view.subviews
.compactMap { $0 as? UIScrollView }
.first
scrollView?.delegate = self
- 델리게이트 구현
- 스크롤 될 때마다 현재의 page index 값을 구한 후, 지금 페이지가 첫번째거나 마지막인 경우 bounces를 비활성화하면 완료
extension ViewController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// 2.
print(scrollView.bounces, scrollView.contentOffset)
let currentPageIndex = contentViewControllers
.enumerated()
.first(where: { _, vc in vc == pageVC.viewControllers?.first })
.map(\.0) ?? 0
let isFirstable = currentPageIndex == 0
let isLastable = currentPageIndex == contentViewControllers.count - 1
let shouldDisableBounces = isFirstable || isLastable
scrollView.bounces = !shouldDisableBounces
}
}
* 전체 코드: https://github.com/JK0369/ExPageVC
'iOS 응용 (swift)' 카테고리의 다른 글
Comments