I am using UIPageViewController having Next button that have same functionality like swipe to next view.
#IBAction func next(sender: UIButton!) {
let pageContentViewController = pageViewController.viewControllers![0] as! WelcomeViewController
let index = pageContentViewController.pageIndex + 1
if index < titleArray.count {
let vctoMove = self.viewControllerAtIndex(index) as WelcomeViewController
let viewControllers = NSArray(objects: vctoMove)
pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .Forward, animated: true, completion: nil)
}
}
Related
I am trying add UIPageView with static position counter. But UIPageView page hiding Counter Label
Following code - I am creating PageViewController in my ControllerView.
func createPageViewController(){
let pageVC = self.storyboard?.instantiateViewController(identifier:
Constant.storyIdPageViewIdentifier) as! UIPageViewController
pageVC.dataSource = self
if carsArray.count>0 {
let imageController = getImageViewController(withIndex: 0)!
let imageControllers = [imageController]
pageVC.setViewControllers(imageControllers, direction: .forward, animated: true, completion: nil)
}
pageViewController = pageVC
self.addChild(pageViewController!)
self.view.addSubview(pageViewController!.view)
pageViewController?.didMove(toParent: self)
}
Try using self.view.bringSubviewToFront(counterlabel)
I'm using PageViewController and tab bar. And I have a question which is 'how to move another view by touching button.' My app has 5 ViewControllers and they are on PageViewController. And the PageViewController is on ViewController. That ViewController is MainController. So I separated Main view, with about 4 : 1(PageViewController : tab bar). So tab bar is on MainController, MainController can changes ViewController when tab item is touched.
But what I want to make is a button on one of five ViewControllers which can change ViewController.
The button has not right to change ViewController. So I searched how to solve this problem but It couldn't find good solution.
I think the solution is very short, about 1 ~ 2 sentences.
I attached my code, so I hope anybody who know how to solve this problem please helps me.
I'm new in Swift, so explain detail please
This is a part of MainController
import UIKit
class ViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var pageViewController: UIPageViewController!
var subVC: [UIViewController] = []
var viewIndex: Int = 0
var tabIndicator1 = UIView()
var tabIndicator2 = UIView()
var tabIndicator3 = UIView()
var tabIndicator4 = UIView()
var tabIndicator5 = UIView()
var views = [UIView]()
override func viewDidLoad() {
super.viewDidLoad()
createVC() // make five ViewControllers
self.pageViewController = self.storyboard?.instantiateViewController(withIdentifier: "PageViewController") as! UIPageViewController
self.pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
self.pageViewController.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
let startVC = subVC[0]
viewIndex = 0
let viewControllers = NSArray(object: startVC)
self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: true, completion: nil)
self.pageViewController.didMove(toParentViewController: self)
createTabBar() // make Tab Bar
createIndicator() // make Tab Indicator
self.pageViewController.dataSource = self
self.pageViewController.delegate = self
}
...
func createVC() { // I have five ViewController files
let HomeVC = VCInstance(name: "Home")
let AccessVC = VCInstance(name: "AccessLog")
let RegisterVC = VCInstance(name: "Register")
let SettingVC = VCInstance(name: "Setting")
let HelpVC = VCInstance(name: "Help")
subVC = [HomeVC, AccessVC, RegisterVC, SettingVC, HelpVC]
}
func VCInstance(name: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: name)
}
....
You can use this code it might be help you.
extension UIViewController {
func goNextPage(animated: Bool = true) {
guard let currentViewController = self.viewControllers?.first else { return }
guard let nextViewController = dataSource?.pageViewController(self, viewControllerAfter: currentViewController) else { return }
setViewControllers([nextViewController], direction: .forward, animated: animated, completion: nil)
}
func goPreviousPage(animated: Bool = true) {
guard let currentViewController = self.viewControllers?.first else { return }
guard let previousViewController = dataSource?.pageViewController(self, viewControllerBefore: currentViewController) else { return }
setViewControllers([previousViewController], direction: .reverse, animated: animated, completion: nil)
}
}
i have a viewpagercontroller and have it running correctly with 3 pre set UIViewControllers, however when i load the app it first displays the first UIViewController, i would instead, like to display the second UIViewController first, however i am having trouble achieving this.
Here is my ViewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
}
}
Here is my orderedViewControllers
private(set) lazy var orderedViewControllers: [UIViewController] = {
return [self.newProfileViewController(vc: "UserContentViewController"),
self.newProfileViewController(vc: "ProfileViewController"),
self.newProfileViewController(vc: "NotificationViewController")]
}()
you can this function with your desired index,
func scrollToViewController(index newIndex: Int) {
if let firstViewController = viewControllers?.first,
let currentIndex = orderedViewControllers.indexOf(firstViewController) {
let direction: UIPageViewControllerNavigationDirection = newIndex >= currentIndex ? .Forward : .Reverse
let nextViewController = orderedViewControllers[newIndex]
scrollToViewController(nextViewController, direction: direction)
}
}
All you need to do is change the first bit of code that sets the viewcontrollers:
So change this:
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
}
To this:
if orderedViewControllers.count > 0 {
let secondViewController = orderedViewControllers[1]
setViewControllers([secondViewController],
direction: .forward,
animated: false,
completion: nil)
}
This will set the page view controller to the second view controller straight away and then your delegate methods on the page view controller should handle the swiping before and after to load the correct view controller.
I've a little problem with a UIContainerView. Each element from my containerView are under my ViewController generated by my UIPageController
This image will be more explicit :
So here, my blue button will be under the UIImageView (viewController at the bot) and i need it over it. I don't understand why, if someone have an I idea.
Result :
How i create my PageVieWController :
fileprivate func createPageViewController() {
let pageController = self.storyboard!.instantiateViewController(withIdentifier: "PageController") as! UIPageViewController
pageController.dataSource = self
if contentImages.count > 0 {
let firstController = getItemController(0)!
let startingViewControllers = [firstController]
pageController.setViewControllers(startingViewControllers, direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
}
pageViewController = pageController
addChildViewController(pageViewController!)
self.view.addSubview(pageViewController!.view)
pageViewController!.didMove(toParentViewController: self)
}
And how i instantiate my pageItem :
fileprivate func getItemController(_ itemIndex: Int) -> ABTutorialPageItemViewController? {
if itemIndex < contentImages.count {
let pageItemController = self.storyboard!.instantiateViewController(withIdentifier: "ItemController") as! ABTutorialPageItemViewController
pageItemController.itemIndex = itemIndex
pageItemController.imageName = contentImages[itemIndex]
return pageItemController
}
return nil
}
If you want to manipulate, show directly in action you can use this project :
https://github.com/YanisSOTO/Simple-UIPageViewController-Example
Solved by replacing :
self.view.addSubview(pageViewController!.view)
to :
self.containerView.addSubview(pageViewController!.view)
I finnaly synchronized my segmentedController to the UIPageViewController in this way: when I swipe between pages, the segmented controller changes it's segment index. I want to know how to do the reverse too, when segmentedController's segment is tapped, to change the pageViewController page by segmentedController index. Here is my code:
class photoPageViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate, UINavigationControllerDelegate {
#IBOutlet var segmentedControl: UISegmentedControl!
private var pageViewController: UIPageViewController?
var controllers = [thePageViewController]()
var thePage = thePageViewController()
override func viewDidLoad() {
super.viewDidLoad()
createPageViewController()
setupPageControl()
}
private func createPageViewController() {
var pageController = self.storyboard!.instantiateViewControllerWithIdentifier("PageController") as! UIPageViewController
pageController.dataSource = self
pageController.delegate = self
var firstController = getItemController(thePage.itemIndex)!
var startingViewControllers: NSArray = [firstController]
pageController.setViewControllers(startingViewControllers as [AnyObject], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
pageViewController = pageController
addChildViewController(pageViewController!)
self.view.addSubview(pageViewController!.view)
pageViewController!.didMoveToParentViewController(self)
}
private func setupPageControl() {
let appearance = UIPageControl.appearance()
appearance.pageIndicatorTintColor = UIColor.grayColor()
appearance.currentPageIndicatorTintColor = UIColor.whiteColor()
appearance.backgroundColor = UIColor.darkGrayColor()
}
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let itemController = viewController as! thePageViewController
if itemController.itemIndex > 0 {
return getItemController(itemController.itemIndex-1)
}
return nil
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let itemController = viewController as! thePageViewController
if itemController.itemIndex+1 < 3 {
return getItemController(itemController.itemIndex+1)
}
return nil
}
func getItemController(itemIndex: Int) -> UIViewController? {
var vc: thePageViewController? = nil
switch itemIndex {
case 0:
vc = self.storyboard!.instantiateViewControllerWithIdentifier("ViewController0") as! firstPhotoViewController
vc?.itemIndex = itemIndex
case 1:
vc = self.storyboard!.instantiateViewControllerWithIdentifier("ViewController1") as! secondPhotoViewController
vc?.itemIndex = itemIndex
case 2:
vc = self.storyboard!.instantiateViewControllerWithIdentifier("ViewController2") as! thirdPhotoViewController
vc?.itemIndex = itemIndex
default:
return nil
}
return vc
}
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return 3
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
func pageViewController(photoPageViewController: UIPageViewController,
didFinishAnimating finished: Bool,
previousViewControllers pageViewController: [AnyObject],
transitionCompleted completed: Bool)
{
if (!completed)
{
return;
}
segmentedControl.selectedSegmentIndex = thePageIndex
//thePageIndex is a global variable that changes when views from pageViewController appear
}
#IBAction func segmentedFunction(sender: AnyObject) {
switch segmentedControl.selectedSegmentIndex
{
case 0:
getItemController(0)
case 1:
getItemController(1)
case 2:
getItemController(2)
default:
println("...")
}
}}
I think you need to change your code a little bit! In my case I create several vc and put them to one array.
func createArrayOfControllers(){
newsLenta = self.storyboard?.instantiateViewControllerWithIdentifier("NewsLentaTableViewController") as NewsLentaTableViewController
mainPage = self.storyboard?.instantiateViewControllerWithIdentifier("MainPageTableViewController") as MainPageTableViewController
onlinetranslation = self.storyboard?.instantiateViewControllerWithIdentifier("SingleTopicTableViewController") as SingleTopicTableViewController
tableViewControllers = [newsLenta, mainPage, onlinetranslation]
}
where tableViewController is global var var tableViewControllers = [UITableViewController]() ! I signed type TableViewController because all my vs's are type of table View controller. So the next function you need to change is
func viewControllerAtIndex(index : Int) -> UIViewController? {
if index > 2 || index < 0 {
return nil
}
return tableViewControllers[index]
}
In the end you just need to create action of segmentControl and reset your vc by index. Using this function:
func resetToMainPage(index: Int!) {
/* Getting the page View controller */
mainPageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("MainPageViewController") as UIPageViewController
self.mainPageViewController.dataSource = self
self.mainPageViewController.delegate = self
let pageContentViewController = self.viewControllerAtIndex(index)
segmentedControl.selectedSegmentIndex = index
self.mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
self.mainPageViewController.view.frame = CGRectMake(0, 95, self.view.frame.width, self.view.frame.height)
self.addChildViewController(mainPageViewController)
self.view.addSubview(mainPageViewController.view)
self.mainPageViewController.didMoveToParentViewController(self)
}
My question for your how do you update thePageIndex... I dont get that...
I found the way how to change UIPageViewController's content viewcontroller. I dont know is it right way or wrong but it works. Here is a code:
put this to viewdidload:
segmentControl.addTarget(self, action: "selectPageIndexBySegmentControl", forControlEvents: UIControlEvents.ValueChanged)
put it separte from viewdieload:
func selectPageIndexBySegmentControl(){
switch segmentControl.selectedIndex {
case 0:
println("zero index were selected")
pageContentViewController = self.viewControllerAtIndex(0)
mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
case 1:
println("first element were selected")
pageContentViewController = self.viewControllerAtIndex(1)
mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
case 2:
println("second element were selected")
pageContentViewController = self.viewControllerAtIndex(2)
mainPageViewController.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
default:
break
}
}