Swipe direction PageViewController - ios

My problem here it's the swipe movement when I use the pageViewController implementation. I want it to go from right to left but it's going from left to right who's not naturally for the UI experience !
It was working perfectly when I was using Xcode 7 and Swift 2.2 ...
So since I copied/pasted my code and modifiying with the Xcode 8 suggestion, it has this strange behavior.
import UIKit
class FirstEventViewController: UIViewController {
// FIXME: - The swipe gesture has to be from right to left when the view appears (PageControl not showing)
var pageViewController: UIPageViewController!
var titleEvents = [String]()
var pageImages: NSArray!
override func viewDidLoad() {
super.viewDidLoad()
pageImages = NSArray(objects: "supersmashbros","spiritodjsession","thomasdelortrio")
titleEvents = ["supersmashbros","spiritodjsession","thomasdelortrio"]
initiatePgVC()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//TODO: CODE HERE
}
// MARK: - Private functions
/**
Function initializing the logic of the pageviewController
*/
func initiatePgVC() {
pageViewController = UIStoryboard(name:"Main", bundle:nil).instantiateViewController(withIdentifier: "PageViewController") as! UIPageViewController
pageViewController.dataSource = self
let startVC = viewControllerAtIndex(index: 0)
let viewControllers = NSArray(object: startVC) as! [UIViewController]
pageViewController.setViewControllers(viewControllers, direction: .forward, animated: true, completion: nil)
//pageViewController.view.frame = CGRect(x:0, y:65, width:self.view.frame.width, height:self.view.frame.size.height - 140)
pageViewController.view.frame = self.view.bounds
addChildViewController(pageViewController)
view.addSubview(pageViewController.view)
pageViewController.didMove(toParentViewController: self)
}
/**
Function associating the viewControllers
*/
func viewControllerAtIndex(index: Int)->SecondEventViewController{
if ((titleEvents.count == 0) || (index >= titleEvents.count)){
return SecondEventViewController()
}
let vc:SecondEventViewController = storyboard?.instantiateViewController(withIdentifier: "SecondEventViewController") as! SecondEventViewController
vc.imageFile = pageImages[index] as! String
vc.labelTitle = titleEvents[index]
vc.pageIndex = index
return vc
}
}
extension FirstEventViewController:UINavigationBarDelegate{
func position(for bar: UIBarPositioning) -> UIBarPosition {
return .topAttached
}
}
extension FirstEventViewController:UIPageViewControllerDataSource{
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let vc = viewController as! SecondEventViewController
var index = vc.pageIndex as Int
if (index == 0 || index == NSNotFound){
return nil
}
index = index-1
return viewControllerAtIndex(index: index)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let vc = viewController as! SecondEventViewController
var index = vc.pageIndex as Int
if (index == NSNotFound){
return nil
}
index = index+1
if (index == titleEvents.count){
return nil
}
return viewControllerAtIndex(index: index)
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return titleEvents.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
}
I once suspected the pageViewController.setViewControllers(viewControllers, direction: .forward, animated: true, completion: nil) because it implements the direction but even if I change with reverse, nothing happens.

Have you got the changing of the indexes the wrong way around?
for after controller i'd expect the index to increase but you are decreasing it, and vice versa.
Try swapping these, so after should be + 1 and before -1
index = index+1

Related

BAD_ACCESS on UIPageViewController

I've got a working UIPageViewController that holds multiple UIViewControllers embedded in an UINavigationController and each UIViewController has a preview of an array of images wich, when opened, instantiate a new UIPageViewController to display those images
when i swipe through the images and then swipe back to the first one my app crashes with "EXC_BAD_ACCESS(code=EXC_I386_GPFLT)" same thing when i use the back button of the UINavigationController
why is that and how can i fix this ?
My PageViewController (the marked line is the last one i got in the debugger before it crashes):
class DetailPageMasterViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource
{
var presentationPageIndex: Int = 0
var itemsArray = [Aktion]()
var pageViewController: UIPageViewController!
#IBOutlet weak var btnEditOutlet: UIBarButtonItem!
#IBAction func btnEditAction(sender: AnyObject)
{
}
override func viewDidLoad()
{
super.viewDidLoad()
self.pageViewController = UIPageViewController.init(transitionStyle: .Scroll,
navigationOrientation: .Horizontal,
options: nil)
self.pageViewController.delegate = self
self.pageViewController.dataSource = self
self.presentationPageIndex = 0
let firstVC = self.viewControllerAtIndex(presentationPageIndex)
let viewControllers = [firstVC]
self.pageViewController.setViewControllers(viewControllers,
direction: .Forward,
animated: false,
completion: nil)
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
self.pageViewController.didMoveToParentViewController(self)
self.setupPageControl()
}
func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool)
{
if completed
{
let minionVC = self.pageViewController.viewControllers?.last as! DetailMinionViewController
presentationPageIndex = minionVC.pageIndex
}
}
func viewControllerAtIndex(index: Int) -> DetailMinionViewController
{
let contentVC = self.storyboard?.instantiateViewControllerWithIdentifier("MinionPageViewController") as! DetailMinionViewController
contentVC.aktion = itemsArray[index]
contentVC.pageIndex = index
return contentVC
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController?
{
if let viewController = viewController as? DetailMinionViewController
{
var index = viewController.pageIndex
if index == 0 || index == NSNotFound
{
return nil //MARKED LINE
}
index -= 1
return self.viewControllerAtIndex(index)
}
return nil
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController?
{
if let viewController = viewController as? DetailMinionViewController
{
var index = viewController.pageIndex
if index == NSNotFound
{
return nil
}
index += 1
if index == NSNotFound || index >= itemsArray.count
{
return nil
}
return self.viewControllerAtIndex(index)
}
return nil
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int
{
return itemsArray.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int
{
return presentationPageIndex
}
func setupPageControl()
{
UIPageControl.appearance().backgroundColor = UIColor.clearColor()
UIPageControl.appearance().pageIndicatorTintColor = UIColor.whiteColor()
UIPageControl.appearance().currentPageIndicatorTintColor = UIColor.redColor()
}
}
So the structure looks like
UINavigationController -> DetailPageMasterViewController -> DetailMinionViewController -> PicturesPageMasterViewController -> PicturesMinionViewController
So i finally figured out what caused my app to crash.
Long story short:
a gestureRecognizer in the PicturesMinionViewController tried to access an already deinitialized ImageView, my pageViewController worked fine
Please check the number of viewController added into the PageController. If possible you can share your code.

UIPageViewController doesn't stop scroll

I am Using UIPageController having 2 images in it. While running the app, The UIPageController shows the first page perfectly, but then scrolls infinitely from the second page. It maintains the same image and continues to show the similar image even after it has reached the limit. It only changes the image for the first swipe, and then neither changes the image nor revert back to the initial image on the subsequent scroll.
Given is the source. Please help.
import UIKit
class SignUpViewController: UIViewController, UIPageViewControllerDataSource {
var pageViewController : UIPageViewController!
var InfoImages : NSArray!
override func viewDidLoad() {
super.viewDidLoad()
self.InfoImages = NSArray(objects: "blue","red")
self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("IntroPageController") as! UIPageViewController
self.pageViewController.dataSource = self
let startVC = self.viewControllerAtIndex(0) as ContentViewController
let viewControllers = NSArray(object: startVC)
self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .Forward, animated: true, completion: nil)
self.pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
self.pageViewController.didMoveToParentViewController(self)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func viewControllerAtIndex(index: Int) -> ContentViewController
{
if ((self.InfoImages.count == 0) || (index >= self.InfoImages.count)){
return ContentViewController()
}
let info = storyBoard.instantiateViewControllerWithIdentifier("ContentViewController") as! ContentViewController
info.imageFile = self.InfoImages[index] as! String
return info
}
//MARK : -DataSource
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController?
{
let vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if( index == 0 || index == NSNotFound ){
return nil
}
index--
return self.viewControllerAtIndex(index)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController?
{
let vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if( index == NSNotFound ){
return nil
}
index++
if(index == self.InfoImages.count){
return nil
}
return self.viewControllerAtIndex(index)
}
#available(iOS 6.0, *)
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int
{
return self.InfoImages.count
}
#available(iOS 6.0, *)
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int
{
return 0
}
#IBAction func SkipInfo(sender: AnyObject) {
let skipinfo = storyBoard.instantiateViewControllerWithIdentifier("afterLoginview") as! LoginViewController
self.presentViewController(skipinfo , animated: true, completion: nil)
}
Cheers and Thanks in advance!
P.S : I am using Xcode 7.0 beta (swift 2.0)

Can't figure out why I am getting "Class ViewController has no initializers" Error in Swift iOS App Code

I was trying to make a tutorial screen in my iOS app where the user swipes past a few pictures to learn a bit about the said application. Everything looks fine, except when I build my project, I get the following error on the very first line of code:
Class ViewController has no initializers
What did I do wrong?
My ViewController.swift code is below
import UIKit
//line below is where I get the error
class ViewController: UIViewController, UIPageViewControllerDataSource {
//end
var pageViewController: UIPageViewController
var pageTitles: NSArray!
var pageImages: NSArray!
override func viewDidLoad() {
super.viewDidLoad()
self.pageTitles = NSArray(objects: "", "", "")
self.pageImages = NSArray(objects: "page1", "page2", "page3")
self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as!
UIPageViewController
self.pageViewController.dataSource = self
var startVC = self.viewControllerAtIndex(0) as ContentViewController
var viewControllers = NSArray(object: startVC)
self.pageViewController.setViewControllers(viewControllers as [AnyObject], direction: .Forward, animated: true, completion: nil)
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
self.pageViewController.didMoveToParentViewController(self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func restartAction(sender: AnyObject) {
}
func viewControllerAtIndex(index: Int) -> ContentViewController
{
if ((self.pageTitles.count == 0) || (index >= self.pageTitles.count))
{
return ContentViewController()
}
var vc: ContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ContentViewController") as! ContentViewController
vc.imageFile = self.pageImages[index] as! String
vc.titleText = self.pageTitles[index] as! String
vc.pageIndex = index
return vc
}
// Mark: - Page View Controller Data Source
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
var vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == 0 || index == NSNotFound)
{
return nil
}
index--
return self.viewControllerAtIndex(index)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
var vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == NSNotFound)
{
return nil
}
index++
if (index == self.pageTitles.count)
{
return nil
}
return self.viewControllerAtIndex(index)
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return self.pageTitles.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
}
It's because of this line:
var pageViewController: UIPageViewController
You're saying that pageViewController cannot be null, but you don't have an initializer that sets it to a value. Looking at your code, I suspect you want to change it to this:
var pageViewController: UIPageViewController!
I went into more detail on this problem here.
In a Swift class each non-optional declared variable must be initialized in one of the given init methods.
In your case, it's this variable
var pageViewController: UIPageViewController
declare it as implicit unwrapped optional as the other two variables, because the variable is guaranteed to be set before it's used.
var pageViewController: UIPageViewController!

Xcode won't open up ContentViewController but stays on the launch screen

I am trying to compile my Xcode application. It builds successfully however it doesn't get past the launch screen.
Also It keeps referring me to this particular line of code: instantiateViewControllerWithIdentifier (full code below) and in the logs I get this message:
Unknown class ContentViewController in Interface Builder file.
Could not cast value of type 'UIViewController' (0x10741f418) to 'HelloHi.ContentViewController' (0x1049aa2e0).
(lldb)
Can anyone please help me fix this?
import UIKit
class ViewController: UIViewController, UIPageViewControllerDataSource {
var pageViewController: UIPageViewController!
var pageTitles: NSArray!
var pageImages: NSArray!
override func viewDidLoad() {
super.viewDidLoad()
self.pageTitles = NSArray(objects: "Welcome", "Hello")
self.pageImages = NSArray(objects: "page1", "page2")
self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! UIPageViewController
self.pageViewController.dataSource = self
var startVC = self.viewControllerAtIndex(0) as ContentViewController
var viewControllers = [startVC]
self.pageViewController.setViewControllers(viewControllers, direction: .Forward, animated: true, completion: nil)
self.pageViewController.view.frame = CGRectMake(0, 30, self.view.frame.width, self.view.frame.size.height - 60 )
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
self.pageViewController.didMoveToParentViewController(self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func restartAction(sender: AnyObject) {
var startVC = self.viewControllerAtIndex(0) as ContentViewController
var viewControllers = [startVC]
self.pageViewController.setViewControllers(viewControllers, direction: .Forward, animated: true, completion: nil)
}
func viewControllerAtIndex(index: Int) -> ContentViewController
{
if ((self.pageTitles.count == 0) || (index >= self.pageTitles.count))
{
return ContentViewController()
}
var vc: ContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ContentViewController") as! ContentViewController
vc.imageFile = self.pageImages[index] as! String
vc.titleText = self.pageTitles[index] as! String
vc.pageIndex = index
return vc
}
//MARK: - Page View Controller Data Source
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
var vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == 0 || index == NSNotFound)
{
return nil
}
index--
return self.viewControllerAtIndex(index)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
var vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == NSNotFound)
{
return nil
}
index++
if (index == self.pageTitles.count)
{
return nil
}
return self.viewControllerAtIndex(index)
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return self.pageTitles.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
}
The error message indicates that the view controller in the Interface Builder file has the wrong class set. Select the offending controller, open the identity inspector and change the class name to the correct UIViewController subclass. Presumably this is ContentViewController for you.
Of course, you need to define the the ContentViewController class somewhere in the project. It is not in the code you posted, and following the error message, it is not anywhere else in your project.

Swift - UITapGestureRecognizer UIPageViewController

Okay, I've created a pageview slider app. Everything works great, but now I'd like to be able to hide/unhide my navbar with a single tap using UITapGestureRecognizer.
I have been able to hide the navbar on viewDidLoad, but I am not sure where to call my singleTapped function, or how to implement UITapGestureRecognizer.
How can I hide/unhide the UIPageViewController navbar with UITapGestureRecognizer?
New to swift/ios
my code
class ViewController: UIViewController, UIPageViewControllerDataSource {
var pageViewController: UIPageViewController!
private var allPages = [Page]()
var pages = NSMutableOrderedSet()
override func viewDidLoad() {
super.viewDidLoad()
###Hide NavBar
self.navigationController?.navigationBarHidden = true
self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! UIPageViewController
self.pageViewController.dataSource = self
var startVC = self.viewControllerAtIndex(0) as ContentViewController
var viewControllers = NSArray(object: startVC)
self.pageViewController.setViewControllers(viewControllers as [AnyObject], direction: .Forward, animated: true, completion: nil)
self.pageViewController.view.frame = CGRectMake(0, 30, self.view.frame.width, self.view.frame.size.height)
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
self.pageViewController.didMoveToParentViewController(self)
}
###Function to Hide/Unhide Navbar
func singleTapped(recognizer: UITapGestureRecognizer) {
if (self.navigationController?.navigationBarHidden == false) {
###hide the Navigation Bar
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
###if Navigation Bar is already hidden
else if (self.navigationController?.navigationBarHidden == true)
{
###Show the Navigation Bar
self.navigationController?.setNavigationBarHidden(false, animated: true)
}
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
var vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == 0 || index == NSNotFound) {
return nil
}
index--
return self.viewControllerAtIndex(index)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
var vc = viewController as! ContentViewController
var index = vc.pageIndex as Int
if (index == NSNotFound) {
return nil
}
index++
if (index == self.pages.count) {
return nil
}
return self.viewControllerAtIndex(index)
}
func viewControllerAtIndex(index: Int) -> ContentViewController
{
if ((self.pages.count == 0) || (index >= self.pages.count)) {
return ContentViewController()
}
var vc: ContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ContentViewController") as! ContentViewController
###Store image in imageFile
var image = (pages.objectAtIndex(index) as! Page).image
vc.imageFile = image
vc.pageIndex = index
return vc
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int
{
return self.pages.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int
{
return 0
}
}
Use UITapGestureRecognizer:
In viewDidLoad function add
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action:"singleTapped:"))

Resources