4
votes
  1. Navigation Controller - Parent
  2. Page ViewController - Child of Navigation Controller
  3. DetailsViewController - ViewController to be displayed in PageViewController.

My DetailsViewController contains scrollview and array of detailsviewController with different data is passed to pageviewcontroller.

The problem is only first viewController of pageviewcontroller is shown under navigartionbar and its scrollview is working.

But rest are pushed under navigation controller and scrollview is not working.

First Details view controller working properly

Next DetailsViewController from dataset when i swipe. Here the content is pushed under navigation bar and scrollview not working

1st image : First Details view controller working properly

2nd Image : Next DetailsViewController from dataset when i swipe. Here the content is pushed under navigation bar and scrollview not working

After doing further research i found that navigationcontroller property of rest of detailsviewcontroller except first is nil.

 //
//  PagerViewController.swift
//  
//
//  Created by Admin on 13/07/16.
// 
//

import UIKit

class PagerViewController: UIPageViewController {

    var result =  Array<SearchResult>();
    var mainStoryBoard  = UIStoryboard(name: "Main", bundle: nil);
    var resultSet = [UIViewController]();
    var currentIndex = 0;
    // MARK: - Life cycle Methods
    override func viewDidLoad() {
        super.viewDidLoad();
        dataSource = self;
        delegate = self;
        generateDatset();
        let initialViewController  = resultSet[currentIndex] ;
        let viewControllers = NSArray(objects : initialViewController);
        setViewControllers(viewControllers as? [UIViewController], direction: .Forward, animated: true, completion: nil);
        self.navigationController!.edgesForExtendedLayout = .None;
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Dataset Initialisation

    func generateDatset()  {

        for searchResult in result {
            let viewController  = mainStoryBoard.instantiateViewControllerWithIdentifier(Constants.STORYBOARDUIFIELDS.DETAILSVIEWCONTROLLER) as? DetailsViewController;

            viewController?.searchResult =  searchResult;
            resultSet.append(viewController!)
        }

    }






}

// MARK: - UIPageViewControllerDataSource

extension PagerViewController : UIPageViewControllerDataSource {

    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {


        guard let viewControllerIndex  = resultSet.indexOf(viewController)  else {
            return nil;
        }

        let nextIndex  = viewControllerIndex + 1;

        guard  resultSet.count > nextIndex else {
                       return nil;
        }

        currentIndex = nextIndex;
        return resultSet[nextIndex];


    }

    func scrollToNext(viewControllers : UIViewController) {
        setViewControllers([viewControllers], direction: .Forward, animated: true, completion: nil)
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
       guard let viewControllerIndex = resultSet.indexOf(viewController) else {
            return nil;
        }
        let previousIndex =  viewControllerIndex - 1;

        guard previousIndex >= 0  else {
            return nil;
        }
        currentIndex  = previousIndex;
        return resultSet[previousIndex];

    }

}


 //
//  DetailsViewController.swift
//
//
//  Created by Admin on 13/07/16.
//  
//

import UIKit

class DetailsViewController: UIViewController {


    var searchResult  : SearchResult? = nil;

    @IBOutlet weak var ShoeImageView: UIImageView!

    @IBOutlet weak var DnsItemCodeLabel: UILabel!

    @IBOutlet weak var GeneralDetailsCollView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()

        //print(navigationController)

        DnsItemCodeLabel.text = "\(searchResult!.DNS!) - \(searchResult!.ItemCode!)";

        // converting base64encoded image into nsdata and then to ui image

        let image = UIImage(data: NSData(base64EncodedString: searchResult!.Image!, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)!)

        ShoeImageView.image = image;

        // Assigning source to CollectionView

        GeneralDetailsCollView.dataSource = self;
        print(navigationController)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }





}

// MARK: - UICollectionViewDataSource

extension DetailsViewController : UICollectionViewDataSource  {


    // returns the number of items

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return (searchResult!.summaryItems?.count)!;
    }

    //return the cell for given position

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
          let cell = collectionView.dequeueReusableCellWithReuseIdentifier(Constants.STORYBOARDUIFIELDS.GENRAL_DETAILS_CELL, forIndexPath: indexPath) as! GeneralDetailsCell
        if let data = searchResult?.summaryItems![indexPath.row] {
            cell.TitleLable.text =  data.Title!;
            cell.ValueLabel.text  = data.Value!;
        }

        return cell

    }


}
4
Did you mean, your DetailsViewControllers not shown except the first one?Jintao Ou
No details view is shown but except first one all other are pushed under navigation bar . Hence upper part is overlapping with navgaiton bar nad alos scrollview inside is not working because of this issueChirag Jain
@ChiragJain: can you add some screenshots ?Bishal Ghimire
Sure @BishalGhimireChirag Jain
If it's possible to see your code or it will better, if you can upload the demo project here. Thanks.Sohil R. Memon

4 Answers

4
votes

This has happened to me once, So what I did at that time, I added a normal ViewController and made it the root controller of the NavigationViewController. Now, I added the PageViewController in this ViewController. Then everything was working fine. In short, in spite of making NavigationController as parent controller make the root ViewController of the Navigation Controller as parent of PageViewController.

I have made pageViewController instance in viewController.swift (root View Controller of Navigation Controller), ViewController.swift looks like:

import UIKit

class ViewController: UIViewController,UIPageViewControllerDataSource,UIPageViewControllerDelegate {
    var pageViewController:UIPageViewController?
    var presentIndex = 0
    override func viewDidLoad() {
        super.viewDidLoad()
        self.pageViewController = UIPageViewController.init(transitionStyle: UIPageViewControllerTransitionStyle.Scroll, navigationOrientation: UIPageViewControllerNavigationOrientation.Horizontal, options: nil)
        self.pageViewController!.dataSource=self
        let initialViewController:DetailViewController = self.giveRequiredViewController(1)
        let viewControllerArray:NSArray = [initialViewController]
        self.pageViewController?.setViewControllers(viewControllerArray as! [DetailViewController], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
        self.addChildViewController(self.pageViewController!)
        self.view.addSubview((self.pageViewController?.view)!)
        self.pageViewController?.didMoveToParentViewController(self)
        self.view.backgroundColor=UIColor.blackColor()
        self.navigationController?.navigationBar.barTintColor=UIColor.redColor()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func viewWillLayoutSubviews() {
        let frame = CGRectMake(0, 64, self.view.frame.width, self.view.frame.height-40)
        self.pageViewController?.view.frame = frame
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        presentIndex = (viewController as! DetailViewController).index!
        if presentIndex==0{
            return nil
        }
       return self.giveRequiredViewController(presentIndex-1)
    }

    func giveRequiredViewController(index:NSInteger) -> DetailViewController {
        let detailViewController = DetailViewController(nibName: "DetailViewController", bundle: nil)
        detailViewController.index = index
        return detailViewController
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        presentIndex = (viewController as! DetailViewController).index!
        if presentIndex==1{
            return nil
        }
        return self.giveRequiredViewController(presentIndex+1)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

I provide a index to the DetailViewController, this index will basically will tell me which page is being presented and I will adjust my view accordingly. For now I have changed the background color for view change. There are only two pages presently, you can have as many as you can.

DetailViewController.swift code goes like this,

import UIKit

class DetailViewController: UIViewController {
    var index:NSInteger?
    override func viewDidLoad() {
        super.viewDidLoad()
        if index==0{
            self.view.backgroundColor=UIColor.blueColor()
        }else{
            self.view.backgroundColor = UIColor.grayColor()
        }
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

The complete code can be found in this link

0
votes

Try to configure your PageViewController instance with:

self.automaticallyAdjustsScrollViewInsets = false;

For the DetailsViewController, automaticallyAdjustsScrollViewInsets should be true.

Make sure that both PageViewController and DetailViewController have "Extend Edges" settings as follows: "Under Top Bars (Checked)", "Under Bottom Bars (Checked)" and "Under Opaque Bars (Un-checked)" (from Interface Builder or your source code).

0
votes
self.edgesForExtendedLayout = .None
self.automaticallyAdjustsScrollViewInsets = false;
0
votes

Use self.edgesForExtendedLayout = .None in Parent view controller. It works fine