UIPageViewContoller in container view with page control icon - ios

I am writing a Swift app with three views. I have achieved this by putting a UIPageViewController inside a container and having that switch when you swipe, from another Stack Overflow article: UIPageViewController and storyboard. I would also like to have dots on the bottom indicating the page you are on. But, the UIPageControl I am using can only be placed on the view controller with the container, and the code with the current page is in the page controller's code. Here is my code:
class ContainerView : UIViewController {
#IBOutlet var myPageController: UIPageControl!
}
class MyPageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var pages = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
let page1: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "Page1ID")
let page2: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "Page2ID")
let page3: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "Page3ID")
pages.append(page1)
pages.append(page2)
pages.append(page3)
setViewControllers([page1], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
if (currentIndex == 0) {
return pages[currentIndex]
}
let previousIndex = abs((currentIndex - 1) % pages.count)
//myPageControl.currentPage = previousIndex
return pages[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
if (currentIndex == 2) {
return pages[currentIndex]
}
let nextIndex = abs((currentIndex + 1) % pages.count)
//myPageControl.currentPage = nextIndex
return pages[nextIndex]
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return pages.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
}
How could I access the parent view controller (ContainerView) from the child in the container (MyPageViewController)? I'm new to Swift/Objective-C but have programmed in other languages (C++, Python). If you need the storyboard, please ask.

Related

Adjust containerView Height based on PageviewController

I'm kinda having a trouble adjusting the ContainerView height based on the height of the pageViewController.
So on this example I have two pages : "Yellow Page","Purple Page"
Yellow page = 120px Height
Purple page = 250px Height
All I wanna work out is to adjust the height automatically as I scroll on the pageViewController embedded on the containerView.
Hope you can help, thank you!
Here's the Image.
Storyboard Image
This is my PageViewController Code.
import UIKit
class PageViewController: UIPageViewController,UIPageViewControllerDataSource, UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
let previousIndex = abs((currentIndex - 1) % pages.count)
return pages[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]
}
var pages = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
let page1: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "page1");
let page2: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "page2");
pages.append(page1)
pages.append(page2)
setViewControllers([page1], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return pages.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
override func viewDidLayoutSubviews() {
}
}
You can hook the height of the container and controls it from the pager like this
#IBOutlet weak var conH: NSLayoutConstraint!
//
func callMe(value:CGFloat) {
conH.constant = value
self.view.layoutIfNeeded()
}
//
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
let vc = UIApplication.shared.keyWindow?.rootViewController as! ViewController
let currentIndex = pages.index(of: previousViewControllers.first!)!
let nextIndex = abs((currentIndex + 1) % pages.count)
vc.callMe(value:nextIndex == 0 ? 100 : 200)
}
//

transition page with uipageviewcontroller

I have a view container containing a UIPageViewController. to him they are associated with 2 viewController of UIImageView. It works almost everything. I can not change the animations to scroll through images. the animation is always that of the page curl while I would like a simple scroll. how to do?
class MyPageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var pages = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
let page1: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "page1")
let page2: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "page2")
pages.append(page1)
pages.append(page2)
setViewControllers([page1], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
let previousIndex = abs((currentIndex - 1) % pages.count)
return pages[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]
}
private func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return pages.count
}
private func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
}
How are you initiating the UIPageViewController?
From code, you can specify a transitionStyle in the constructor, as seen here
From storyboard, you can specify the same transitionStyle in the storyboard itself, as shown in this SO answer

UITableView in UIPageViewController in NavigationController with Page Control

I have the following set up:
UINavigationController -> UIPageViewController-> UITableViewController/UIViewController/UIViewController
my UIPageViewController looks like this:
import UIKit
class DailyRoutinePageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var pages = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false;
self.delegate = self
self.dataSource = self
self.navigationItem.title = getActiveUserName()
let page1: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("dailyRoutinePage1")
let page2: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("dailyRoutinePage2")
let page3: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("dailyRoutinePage3")
pages.append(page1)
pages.append(page2)
pages.append(page3)
setViewControllers([page1], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}
#IBAction func buttonKontakte(sender: AnyObject) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("careTaker")
self.presentViewController(vc, animated: true, completion: nil)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.indexOf(viewController)!
let previousIndex = abs((currentIndex - 1) % pages.count)
return pages[previousIndex]
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.indexOf(viewController)!
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return pages.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
}
this works fine. I can scroll through all pages. Now I want to add a Page Control. I can add a Page Control to the UIPageView's. But how can I add one to the UITableViewController? And when I scroll through the pages the Page Control scroll with the pages. How can I make it stand still?
An other problem: The PageViewController doesn't respect the navigation title bar. So there is content behind the Naviagtion bar at the top. How can I fix this?

How to implement a vertical UIPageViewController inside a horizontal UIPageViewController

I want to adjust my UIPageViewController to work like in the image, currently 1b is able to go 2a etc. What do i need to do to lock the direction like in the image? Did i forget anything or am i using the wrong logic. Any tip would help a lot!
Note the vertical UIPageViewController is inside the horizontal UIPageViewController
Horizontal UIPageViewController code
class MyPageViewController: UIPageViewController , UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var pages = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
let page1: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("page1")
let page2: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("page2")
let page3: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("page3")
pages.append(page1)
pages.append(page2)
pages.append(page3)
setViewControllers([page2], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.indexOf(viewController)!
let previousIndex = abs((currentIndex - 1) % pages.count)
if (previousIndex > 0)
{
return nil
}
return pages[previousIndex]
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.indexOf(viewController)!
let nextIndex = abs((currentIndex + 1) % pages.count)
if (nextIndex < 1)
{
return nil
}
return pages[nextIndex]
}
Vertical UIPageViewController code
class upAndDownViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var pages = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
let midPage: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("midPage")
let topPage: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("topPage")
pages.append(midPage)
pages.append(topPage)
setViewControllers([midPage], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.indexOf(viewController)!
let nextIndex = abs((currentIndex + 1) % pages.count)
if (nextIndex < 1)
{
return nil
}
return pages[nextIndex]
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.indexOf(viewController)!
let previousIndex = abs((currentIndex - 1) % pages.count)
if (previousIndex > 0)
{
return nil
}
return pages[previousIndex]
}
I put the horizontal UIPageViewController inside the vertical UIPageViewController. That fixed it but for some reasons other ViewControllers opened inside the TOP vertical UIPageViewController are able to Page down, i will look more into that and probably fix it.

Disable swipe function in UIViewController

I have a UIPageViewController with two ViewControllers in it, one of them got a NavigationController connected so i can push to another ViewController using the Push-Segue embedded in a button. The ViewController that is being pushed have the UIPageViewController datasource enabled so i can swipe from the pushed ViewController back to the first ViewController.
I want to be able to disable the swip function in the pushed ViewController so i must press on the back button to return, not swipe.
I think that my UIPageViewController is not setting the correct view in the function before and after.
Code for UIPageViewController
class upAndDownViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var pages = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
let page2: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("page2")
let topPage: UIViewController! = storyboard?.instantiateViewControllerWithIdentifier("topPage")
pages.append(page2)
pages.append(topPage)
setViewControllers([page2], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.indexOf(viewController)!
let nextIndex = abs((currentIndex + 1) % pages.count)
if (nextIndex < 1)
{
return nil
}
return pages[nextIndex]
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.indexOf(viewController)!
let previousIndex = abs((currentIndex - 1) % pages.count)
if (previousIndex > 0)
{
return nil
}
return pages[previousIndex]
}

Resources