在iOS中导航控制器的子视图控制器PageViewController滚动问题

4
  1. 导航控制器 - 父级
  2. 页面视图控制器 - 导航控制器的子级
  3. 详情视图控制器 - 将在页面视图控制器中显示的视图控制器。

我的 DetailsViewController 包含滚动视图,并传递了一个包含不同数据的 detailsviewController 数组给 pageviewcontroller。

问题是只有 pageviewcontroller 的第一个 viewController 在导航栏下面显示,其滚动视图有效。

但是其余的视图控制器都被推到导航控制器下面,滚动视图无效。

第一个详情视图控制器正常工作

我滑动时从数据集中获取的下一个详情视图控制器。这里内容被推到导航栏下面,滚动视图无效

第一张图片:第一个详情视图控制器正常工作

第二张图片:我滑动时从数据集中获取的下一个详情视图控制器。这里内容被推到导航栏下面,滚动视图无效。

经过进一步的研究,我发现除第一个外,其余详情视图控制器的 navigationcontroller 属性为 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

    }


}

没有显示详细视图,除了第一个视图,其他所有视图都被推到导航栏下面。因此,上半部分与导航栏重叠,内部的滚动视图也因此无法工作。 - Chirag Jain
@ChiragJain:你能添加一些截图吗? - Bishal Ghimire
当然,@BishalGhimire - Chirag Jain
如果可以查看您的代码,或者如果您能在此处上传演示项目,那将更好。谢谢。 - Sohil R. Memon
你的 DetailsViewController 的顶部栏是 不透明导航栏还是半透明导航栏 ..? - Gokul G
显示剩余4条评论
4个回答

4

我曾经遇到过这个问题,那时我添加了一个普通的ViewController并将其设置为NavigationViewController的根控制器。现在,在这个ViewController中添加PageViewController。然后一切都正常工作。简而言之,尽管将NavigationController作为父控制器,但仍需将Navigation Controller的根视图控制器作为PageViewController的父控制器。

我已经在viewController.swift(Navigation Controller的根视图控制器)中创建了pageViewController实例,viewController.swift如下:

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


}

我向DetailViewController提供了一个索引,这个索引基本上会告诉我当前显示的是哪一页,然后我会相应地调整我的视图。目前我已经更改了视图转换的背景颜色。目前只有两个页面,你可以添加任意多个页面。

DetailViewController.swift代码如下:

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

}

完整代码可以在此链接中找到。

谢谢你的解决方案,我会尝试一下,但我认为它可能会导致性能问题(内存方面)。 - Chirag Jain
请问您能否提供一个内存增加的场景,我会考虑其他解决方案。 - Sanchit Kumar Singh
嘿,@Sanchit Kumar Singh,这对我不起作用,你有其他的解决方案吗? - Chirag Jain
我已经上传了一个示例代码,请在此链接(https://github.com/Rokimkar/PageViewControllerSwift)中查找。我将对相同的答案进行编辑。 - Sanchit Kumar Singh

0
在父视图控制器中使用 self.edgesForExtendedLayout = .None。它能正常工作。

嘿,我之前尝试过这个,但是在设置了self.edgesForExtendedLayout之后,滚动视图不起作用了。 - Chirag Jain

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

0

尝试使用以下方式配置您的PageViewController实例:

self.automaticallyAdjustsScrollViewInsets = false;

对于DetailsViewController,automaticallyAdjustsScrollViewInsets应该为true。
确保PageViewController和DetailViewController都具有以下“扩展边缘”设置:“在顶部栏下(已选中)”,“在底部栏下(已选中)”和“在不透明栏下(未选中)”(从Interface Builder或您的源代码).

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接