Let’s dig up the UIPageViewController!

  • UIPageViewController
    • setViewControllers()
    • DataSource
    • Delegate
    • firstIndex
    • viewControllers

*ViewController 안에 ViewController를 띄울 수 있다.

So we want to put an UIPageViewController on UIViewController


기본적으로 책장을 넘기는 듯한 효과를 가지고 있다. 또한 UIPageViewController 자체가 여러 UIViewController들을 띄우는 것을 기억하자.

pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)


Sets the view controllers to be displayed. 그래서 UIPageViewController 에 현재 띄워 줄 VC를 설정해주는 함수가 있다.

setViewControllers([controllers.first!], direction: .forward, animated: false)

배열 스타일로 ViewController를 설정하지만, 원소가 하나인 배열만 들어간다. So we only could put a single VC on viewControllers parameter [UIViewController]?


The UIPageViewControllerDataSource protocol is adopted by an object that provides view controllers to the page view controller on an as-needed basis, in response to navigation gestures.

dataSource = self

before & after

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {


+nil 값을 return하면 끝을 나타낸다.

the Point of UIPageViewController

핵심은 UIViewController를 띄우는 것, 따라서 customPageViewController에 새롭게 UIViewController를 만든다. cardViewModel에서 image들을 받아서 이미지를 받을 것이기 때문에 init을 다음과 같이 설정한다.

    class PhotoController: UIViewController {
        let imageView = UIImageView(image: #imageLiteral(resourceName: "ms1"))
        init(imageUrl: String) {
            super.init(nibName: nil, bundle: nil)
            if let url = URL(string: imageUrl) {
                imageView.sd_setImage(with: url)
        override func viewDidLoad() {
            imageView.contentMode = .scaleAspectFill
            imageView.clipsToBounds = true
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")


get a specific index of collection

Returns the first index in which an element of the collection satisfies the given predicate.

    let index = controllers.firstIndex(where: { $0 == viewController }) ?? 0

viewController is current viewController of UIPageViewController

        if let index = controllers.firstIndex(where: { $0 == currentPhotoController }) {
            barStackView.arrangedSubviews.forEach({ $0.backgroundColor = deselectedBarColor })
            barStackView.arrangedSubviews[index].backgroundColor = .white


delegate를 통해 transitionCompleted, swipe 후 실행되는 함수를 호출할 수 있다.

여기서 imageBar를 설정할 수 있다.

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
      let currentPhotoController = viewControllers?.first


The view controllers displayed by the page view controller. 띄워지는 ViewControllers, [UIViewController]? 를 가져온다. setViewControllers에서 설정한 값을 반환하는 친구.


In UIPageViewController, we need to set viewControllers to be rendered as a page.

all elements of viewControllers are UIViewController.

So, It is much more efficient to specify UIViewController class in UIPageViewController.

DataSource - swiping before & after

Delegate - complete transaction

태그: ,