UIPageViewController uiNavigationController childViewController 在 ios 中的滚动问题

Posted

技术标签:

【中文标题】UIPageViewController uiNavigationController childViewController 在 ios 中的滚动问题【英文标题】:PageViewController in NavigationController child ViewController of scrolling issue in ios 【发布时间】:2016-07-20 13:33:55 【问题描述】:
    导航控制器 - 父级 Page ViewController - 导航控制器的子级 DetailsViewController - 要在 PageViewController 中显示的 ViewController。

我的 DetailsViewController 包含滚动视图,并将具有不同数据的 detailsviewController 数组传递给 pageviewcontroller。

问题是只有 pageviewcontroller 的第一个 viewController 显示在导航栏下,并且它的滚动视图正在工作。

但是其余部分被推送到导航控制器下并且滚动视图不起作用。

第一张图片:第一个细节视图控制器正常工作

第二张图片:当我滑动时,来自数据集的下一个 DetailsViewController。这里内容被推送到导航栏下,滚动视图不起作用

经过进一步研究,我发现除了 first 之外的 detailsviewcontroller 其余部分的 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

    



【问题讨论】:

你的意思是,除了第一个之外,你的 DetailsViewControllers 没有显示? 没有显示细节视图,但除了第一个视图之外,所有其他视图都被推到导航栏下。因此,由于这个问题,上部与导航栏重叠,内部滚动视图不起作用 @ChiragJain:你能添加一些截图吗? 当然@BishalGhimire 如果可以看到你的代码或者它会更好,如果你可以在这里上传演示项目。谢谢。 【参考方案1】:

这种情况发生在我身上一次,所以我当时的做法是添加了一个普通的ViewController,并将其作为NavigationViewController的根控制器。现在,我在这个 ViewController 中添加了 PageViewController。然后一切正常。简而言之,尽管将 NavigationController 设为父控制器,但仍将 Navigation Controller 的根 ViewController 设为 PageViewController 的父级。

我在viewController.swift(导航控制器的根视图控制器)中创建了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.
    


完整的代码可以在这个link找到

【讨论】:

感谢您的解决方案,我会尝试但我认为它会导致性能问题(内存方面) 你能告诉我一个内存增加的场景,我会想一些其他的解决方案。 嘿@Sanchit Kumar Singh 它对我不起作用你有任何替代解决方案 我已经推送了一个示例代码,请在link找到它。我将编辑我的答案。【参考方案2】:

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

self.automaticallyAdjustsScrollViewInsets = false;

对于 DetailsViewController,automaticAdjustsScrollViewInsets 应该为 true。

确保 PageViewController 和 DetailViewController 都具有“延伸边缘”设置,如下所示:“在顶栏下方(选中)”、“在底部栏下方(选中)”和“在不透明栏下方(未选中)"(来自 Interface Builder 或您的源代码)。

【讨论】:

【参考方案3】:
self.edgesForExtendedLayout = .None
self.automaticallyAdjustsScrollViewInsets = false;

【讨论】:

【参考方案4】:

在父视图控制器中使用self.edgesForExtendedLayout = .None。效果很好

【讨论】:

嘿,我之前尝试过,但设置 self.edgesForExtendedLayout 后滚动视图不起作用

以上是关于UIPageViewController uiNavigationController childViewController 在 ios 中的滚动问题的主要内容,如果未能解决你的问题,请参考以下文章

如何从属于 UIPageViewController 的 UIViewController 之一更改 UIPageViewController?

UIPageViewController - 不符合协议

UIPageViewController 方向只向前

UIPageViewController 和 UIScrollView

NavigationController 中的 UIPageViewController

如何删除 UIPageViewController 中的 previousViewControllers