sameetandpotatoes
sameetandpotatoes

Reputation: 1220

Programmatically set UIPageViewController Transition Style to Scroll

I am using Xcode 6 and implementing UIPageViewController for my app. I followed appcoda's tutorial, and everything works except the page indicators. This is because I cannot set the transition style of UIPageViewController to scroll.

Graphically, when I click on the PageViewController, the tab shows View Controller instead of Page View Controller like appcoda (See its image below)

enter image description here

This is what mine looks like:

enter image description here

And yes, my custom class is set to: UIPageViewController as it is in the tutorial. enter image description here

Programmatically, I try to set the transition style with:

    self.pageViewController.transitionStyle = UIPageViewControllerTransitionStyle.Scroll

but it fails to build, telling me that it Could not find member transition style. One last weird thing I would like to point out is that if I just write self.pageViewController.transitionStyle, it builds successfully, but it still uses the Page Curl Transition.

Could anyone help me? I am using Swift, Xcode 6, and developing on the iOS 8 SDK.

Upvotes: 42

Views: 56346

Answers (16)

Lance Samaria
Lance Samaria

Reputation: 19572

Swift 5

class OnboardingController: UIPageViewController {

    override init(transitionStyle style: UIPageViewController.TransitionStyle, navigationOrientation: UIPageViewController.NavigationOrientation, options: [UIPageViewController.OptionsKey : Any]? = nil) {
        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    }

    required init?(coder: NSCoder) {
        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

Upvotes: 2

M Murteza
M Murteza

Reputation: 1744

In swift 5

In the Page view Controller you can write following code

TransitionStyle scroll

    required init?(coder aDecoder: NSCoder) {
        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    }

For transitionStyle curl

 required init?(coder aDecoder: NSCoder) {
        super.init(transitionStyle: .pageCurl, navigationOrientation: .horizontal, options: nil)
    }

Thank You

Upvotes: 1

Dardan
Dardan

Reputation: 531

This is how I solved this problem in Swift 2.0

1. Created a class which is subclass of class UIPageViewController

    import UIKit
    
    class OPageViewController: UIPageViewController {
        
        override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : AnyObject]?) {

           // Here i changed the transition style: UIPageViewControllerTransitionStyle.Scroll           
            super.init(transitionStyle: UIPageViewControllerTransitionStyle.Scroll, navigationOrientation: UIPageViewControllerNavigationOrientation.Horizontal, options: options)
        }
    
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
    
    }

2.Than i just used it :D

pageController = OPageViewController()
pageController.dataSource = self
pageController.setViewControllers(NSArray(object: vc) as? [UIViewController], direction: .Forward, animated: true, completion: nil)
pageController.view.frame = CGRectMake(0, container.frame.origin.y, view.frame.size.width, container.frame.size.height);

Upvotes: 11

Marcin D
Marcin D

Reputation: 916

The issue is that when you create a UIPageViewController inside a Container, the container is first created with a UIViewController, and that s the controller you see your options for.

In order to fix it you have to delete UIViewController where you set your custom UIPageViewController. Then drag UIPageViewController from the controls picker and hook up the embed segue from the container to that controller, then you can set your custom pager controller as well as set transition to scroll.

Upvotes: 43

Shirish
Shirish

Reputation: 295

This worked for me . Because if I override init for transitionStyle , it never gets called if you have set pageViewController in a container view in Storyboard.

required init?(coder aDecoder: NSCoder) {

        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    }

Upvotes: 5

evevF
evevF

Reputation: 141

Swift 5 & 4: Just put this 2 functions before viewDidLoad() in your pageview VC

override init(transitionStyle style: UIPageViewController.TransitionStyle, navigationOrientation: UIPageViewController.NavigationOrientation, options: [UIPageViewController.OptionsKey : Any]? = nil) {
    super.init(transitionStyle: .pageCurl, navigationOrientation: .horizontal, options: nil)
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

Upvotes: 10

Shahriyar
Shahriyar

Reputation: 688

None of the solutions below worked for Swift 5. here is what worked for me, in my case i needed the view controller to be presented on top of the other view controller with low opacity background:

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
    super.init(nibName: nil, bundle: nil)

    self.setupView()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    self.setupView()
}

private func setupView() {
    self.modalTransitionStyle = .crossDissolve
    self.modalPresentationStyle = .overCurrentContext
    self.view.backgroundColor = UIColor.red.withAlphaComponent(0.3)
}

Upvotes: 0

A. Welch
A. Welch

Reputation: 356

Swift 4 programmatically set the transition style of UIPageViewController

This is straight from 'UIPageViewController.h' line 61-97

Just put this before viewDidLoad() in your UIPageViewController() class

    override init(transitionStyle style: 
UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : Any]? = nil) {
            super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
        }
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }

Upvotes: 4

Cilvet
Cilvet

Reputation: 470

Swift 3.0

required init?(coder aDecoder: NSCoder) {
    super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
}

Upvotes: 31

Anton Russia
Anton Russia

Reputation: 197

swift 3 xcode 8 in

class ...: UIPageViewController {

override var transitionStyle: UIPageViewControllerTransitionStyle {
    return .scroll
}

override var navigationOrientation: UIPageViewControllerNavigationOrientation {
    return .horizontal
}

}

Upvotes: 0

Divyesh Gondaliya
Divyesh Gondaliya

Reputation: 904

in ios 8 swift3

override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : Any]? = nil) {
        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: options)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

Upvotes: 17

Sebastian
Sebastian

Reputation: 9051

Xcode 7.1 & Swift 2

All other solutions did not fully work for me at the latest Swift, especially since my class also inherits from UIPageViewControllerDataSource and UIPageViewControllerDelegate.

To set the PageViewController transition to .Scroll just add these 2 methods to your class:

override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : AnyObject]?) {
    super.init(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: options)
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

Upvotes: 10

PL175
PL175

Reputation: 81

Easiest way to do this programmatically in Swift 2.0 (without subclassing):

class PageViewController: UIPageViewController {

     override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation navigationOrientation: UIPageViewControllerNavigationOrientation, options options: [NSObject : AnyObject]!) {
          super.init(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: options) 
     }

}

Upvotes: 8

Sean Dev
Sean Dev

Reputation: 1309

This is a known bug with UIPageViewController

You can read an explanation of the cause in this SO question and more comprehensively in this one.

I used the AppCoda Tutorial as well to get a handle on PageViewControllers. Another SO user actually wrote a gist that solved the problem for me in a way that I didn't have to change a line of code in my own project. Just drop AVC in to your project and call that instead of UIPageViewController in your code.

Paul de Lange's AlzheimerViewController.

Upvotes: 1

Jorge Barboza
Jorge Barboza

Reputation: 161

I know this a little bit late, but I just had the same problem and realized that it was originated because I was using a simple UIViewController, even when my custom view controller class inherits from an UIPageViewController, aparently the graphic menu of xcode doesn't recognize it.

The solution was to delete in story board the view controller and drag a PageViewController to replace it. This will have the graphic menu with the scroll option.

Upvotes: 10

Mick MacCallum
Mick MacCallum

Reputation: 130193

You're getting an error because transitionStyle is a readonly property. If you want to set the transition style of the page controller programmatically, it can only be done during initialization with the method:

init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation navigationOrientation: UIPageViewControllerNavigationOrientation, options options: [NSObject : AnyObject]!) { ... }

More info in the documentation.

Upvotes: 42

Related Questions