UIContainerView element under the view where he is contained - ios

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)

Related

UIPageViewController overlapping other view [Swift - UIStoryBoard]

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)

(Swift) how can I change view in pageviewcontroller with touching button

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)
}
}

Start ViewPagerController with second UIViewController

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.

Change UIPageViewController page programmatically

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)
}
}

UIPageViewController bad access error

I know the error means I have a NULL pointer, but I am unsure as to WHY that is, and I assume it must be something I did wrong in my code. My index starts at 1 because I want it to start in the middle view controller which is the home page. I am trying to make a page view controller to swipe between view controllers similar to snapchat. I have the following code:
import UIKit
class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
var viewControllersArray = [UIViewController]()
var pageIndex: Int?
let selectedIndex = 1
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.clearColor()
let vc1 = storyboard?.instantiateViewControllerWithIdentifier("ProfileView") as! ProfileViewController
let vc2 = storyboard?.instantiateViewControllerWithIdentifier("HomeView") as! HomeViewController
let vc3 = storyboard?.instantiateViewControllerWithIdentifier("MatchesView") as! MatchViewController
viewControllersArray.append(vc1)
viewControllersArray.append(vc2)
viewControllersArray.append(vc3)
self.dataSource = self
let pageContentViewController = self.viewControllerAtIndex(selectedIndex)
self.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil) //Error here
}
the error occurs at this line:
self.setViewControllers([pageContentViewController!], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil) //Error here
The error is as follows: "Thread 1: EXC_BAD_ACCESS(code=2, address=0x7fff58d57ff8)
Here is my viewControllerAtIndex function:
func viewControllerAtIndex(index : Int) -> UIViewController? {
if((self.viewControllersArray.count == 0) || (index >= self.viewControllersArray.count)) {
return nil
}
let pageContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! PageViewController
pageContentViewController.pageIndex = index
return pageContentViewController
}
Here is my storyboard with the view controllers to swipe between:
Any and all help is greatly appreciated!
It looks like
func viewControllerAtIndex(index : Int) -> UIViewController? {
if((self.viewControllersArray.count == 0) || (index >= self.viewControllersArray.count)) {
return nil
}
let pageContentViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! PageViewController
pageContentViewController.pageIndex = index
return pageContentViewController
}
Needs to be:
func viewControllerAtIndex(index : Int) -> UIViewController? {
if((self.viewControllersArray.count == 0) || (index >= self.viewControllersArray.count)) {
return nil
}
return viewControllersArray[index]
}
Additionally
let selectedIndex = 1
should be
let selectedIndex = 0
since 1 will refer to the second page.

Resources