Swift - UITapGestureRecognizer UIPageViewController - ios

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:"))

Related

How to properly advance a PageViewController in Swift

I am trying to develop a tutorial in Swift. I have a page view controller working with the indicators (http://www.appcoda.com/uipageviewcontroller-storyboard-tutorial/) but I want to add a button to go to the next page by clicking it instead of swiping the screen (TODO NextPage).
I've tried:
let startVC = self.viewControllerAtIndex(self.index + 1) as TutorialContentViewController
let viewControllers = NSArray(object: startVC)
self.pageViewController.setViewControllers(viewControllers as! [UIViewController],
direction: UIPageViewControllerNavigationDirection.Forward,
animated: true,
completion: nil)
The problem is that circle page indicator is not being updated and after clicking next, all the pages are the second page.
Source code
import UIKit
class TutorialViewController: UIViewController, UIPageViewControllerDataSource {
var pageViewController: UIPageViewController!
var pageTexts: NSArray!
var pageImages: NSArray!
var index: Int = 0
#IBOutlet var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
self.pageTexts = NSArray(objects: "Explore", "Today Widget")
self.pageImages = NSArray(objects: "background1.jpg", "background2.jpg")
self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! UIPageViewController
self.pageViewController.dataSource = self
let startVC = self.viewControllerAtIndex(index) as TutorialContentViewController
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.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.
}
func viewControllerAtIndex(index: Int) -> TutorialContentViewController {
if (index >= self.pageTexts.count) {
return TutorialContentViewController()
}
let vc: TutorialContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("TutorialContentViewController") as! TutorialContentViewController
vc.image = self.pageImages[index] as! String
vc.text = self.pageTexts[index] as! String
vc.pageIndex = index
self.index = index
self.button.setTitle(self.index == self.pageTexts.count - 1 ? "Finish" : "Next", forState: .Normal)
return vc
}
// MARK: - Page View Controller Data Source
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let vc = viewController as! TutorialContentViewController
let index = vc.pageIndex as Int
return self.viewControllerAtIndex(index)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let vc = viewController as! TutorialContentViewController
var index = vc.pageIndex as Int
if (index == NSNotFound) {
return nil
}
index++
if (index == self.pageTexts.count) {
self.button.setTitle("Finish", forState: .Normal)
return nil
} else {
self.button.setTitle("Next", forState: .Normal)
}
return self.viewControllerAtIndex(index)
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return self.pageTexts.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
#IBAction func onButtonClick(sender: AnyObject) {
if (self.index == self.pageTexts.count - 1) {
let vc : UIViewController = self.storyboard!.instantiateViewControllerWithIdentifier("splashViewController")
vc.modalTransitionStyle = UIModalTransitionStyle.CrossDissolve
self.presentViewController(vc, animated: true, completion:nil)
} else {
//TODO NextPage
}
}
}
Here let viewControllers = NSArray(object: startVC) you make an array of UIViewController with only one UIViewController (your second UIViewController).
Instead use the viewControllerAtIndex function from your code.
So now your UIButton action should look like this:
func nextPage(sender: AnyObject) {
self.pageViewController.setViewControllers([self.viewControllerAtIndex(self.index + 1)!], direction: .Forward, animated: true, completion: nil)
}

Go to next page on button Click PageViewController

I've created a PageViewController, which i'm trying to make into a quiz where when you press a button it will slide to the next view. I can't seem to get this to work. so far i've added a tableView which contain a button, which i would like to make this gesture with. Beside this i would like to disable the scroll gesture, so the user can't manually scroll. Is this possible or would it make more sense to use a scrollView for this?
viewDidLoad
self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("QuizPageViewController") as! UIPageViewController
self.pageViewController.dataSource = self
let startVC = self.viewControllerAtIndex(0) as QuestionViewController
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.size.height)
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
self.pageViewController.didMoveToParentViewController(self)
PageViewController delegate
func viewControllerAtIndex(index: Int) -> QuestionViewController
{
if ((self.pageTitles.count == 0) || (index >= self.pageTitles.count)) {
return QuestionViewController()
}
let vc: QuestionViewController = self.storyboard?.instantiateViewControllerWithIdentifier("QuestionViewController") as! QuestionViewController
vc.questionText = self.pageTitles[index] as! String
vc.pageIndex = index
vc.pageCount = self.pageTitles.count
return vc
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController?
{
let vc = viewController as! QuestionViewController
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! QuestionViewController
var index = vc.pageIndex as Int
print(index)
if (index == NSNotFound)
{
return nil
}
index++
if (index == self.pageTitles.count)
{
return nil
}
return self.viewControllerAtIndex(index)
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int
{
return 0
}

Hi Swift type does not conform to protocol NilliteralConvertible

//For Navigation Bar Tint and BG Color
var NavBarBGColor = CommonUtilities.RGBColor("#2574A9")
var NavBarTintColor = UIColor.whiteColor()
var pageViewController: UIPageViewController!
var pageTitles: NSArray!
var pageImages: NSArray!
#IBOutlet weak var Open: UIBarButtonItem!
override func viewDidLoad() {
//Navigation Bar Tint and BG Color
self.navigationController?.navigationBar.tintColor = NavBarTintColor
self.navigationController?.navigationBar.barTintColor = NavBarBGColor
super.viewDidLoad()
//Menu Button Click
Open.target = self.revealViewController()
Open.action = Selector("revealToggle:")
//Pan Gesture Recognizer for page navigation
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
//Page View Controller for Men
self.pageTitles = NSArray(objects: "Try","And")
self.pageImages = NSArray(objects: "page1","page2")
self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! UIPageViewController
self.pageViewController.dataSource = self.pageViewController.dataSource
/*var startVC = self.viewControllerIndex(0) as ContentMenuViewController
var viewControllers = NSArray(object: startVC)
self.pageViewController.ViewControllers(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()
}
#IBAction func MenuRestartBtn(sender: AnyObject) {
}
func viewControllerAtIndex(index: Int) -> ContentMenuViewController
{
if ((self.pageTitles.count == 0)) || (index >= self.pageTitles.count)
{
return ContentMenuViewController()
}
var vc: ContentMenuViewController = self.storyboard?.instantiateViewControllerWithIdentifier("") as! ContentMenuViewController
vc.imageFile = self.pageImages[index] as! String
vc.titleText = self.pageTitles[index] as! String
vc.pageIndex = index
return vc
}
//Page View Controller Data Source
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
var vc = viewController as! ContentMenuViewController
var index = vc.pageIndex as Int
if (index == 0 || index == NSNotFound)
{
return nil
}
index--
return self.viewControllerAtIndex(index)
}
func pageViewController(pageController: UIPageViewController, ViewControllerAfterViewController viewController: UIViewController) -> UIViewController{
var vc = viewController as! ContentMenuViewController
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
}
}
You cannot return nil when function should return UIViewController wich your trying to do in:
func pageViewController(pageController: UIPageViewController, ViewControllerAfterViewController viewController: UIViewController) -> UIViewController
Replace above with:
func pageViewController(pageController: UIPageViewController, ViewControllerAfterViewController viewController: UIViewController) -> UIViewController?

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)

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.

Resources