如何让 uipageviewcontroller 转圈

Posted

技术标签:

【中文标题】如何让 uipageviewcontroller 转圈【英文标题】:how to make uipageviewcontroller go in circles 【发布时间】:2014-05-13 10:57:46 【问题描述】:

我有一个显示不同页面的 UIPageViewController。当前的行为是当我到达最后一页时它停止滚动。我现在想要实现的是,当在最后一页并向右滚动时,它会转到第一页。在第一页时,向左滚动时转到最后一页。所以基本上让 PageViewController 以圆圈的形式显示页面。我的第一种方法在有多个页面或从一个页面开始时效果很好:

- (UIViewController*) pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(TMCollectionViewController *)viewController


    if((viewController.pageIndex) >= 1)
    
        return _viewControllers[viewController.pageIndex - 1];
    
    else
    
        if ([_viewControllers count] == 1) 
            return nil;
        
        return [_viewControllers objectAtIndex:[_viewControllers count]-1];
    

但是当我删除页面以只剩下一个时,它仍然会记住之前或之后的页面,并相应地显示它。即使数组中只剩下一页。非常感谢任何帮助。

【问题讨论】:

【参考方案1】:

你可以实现它

当您位于第一个索引并向左滑动时,使其索引 = 总页数

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController

    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;

    if ((index == 0) || (index == NSNotFound)) 
        index = self.pageTitles.count;
    

    index--;
    return [_viewControllers objectAtIndex:index];

当您在最后一个索引上时,将其设置为零索引

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController

    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;

    if (index == NSNotFound) 
        return nil;
    

    index++;
    if (index == [self.pageTitles count]) 
        index = 0;
    
    return [_viewControllers objectAtIndex:index];

【讨论】:

您好,感谢您的快速回复。我尝试了您的代码,但它显示出与我自己的方法类似的行为。当有很多页面时它工作正常。在我的应用程序中,每个页面都代表一个可以添加或删除的新闻源。因此,如果用户有例如五个来源,代码运行良好。现在,当用户删除五个中的四个,因此 PageViewController 中只剩下一个时,仍然可以左右滚动,但会看到带有令人讨厌的浮华效果的白页。 您在presentationCountForPageViewController 中的计数可能不会更新,因此您将获得 5 页,尽管它只有 1 页,而您将获得 4 页白色 我展示的页面都位于 _viewControllers 数组中。用户删除五个页面中的四个后,_viewControllers 数组仅包含一个 ViewController。 'presentationCountForPageViewController' 回复 [_viewControllers count]。但不知何故无济于事。 我发现我发布的代码确实有效。我的代码中其他地方的一个错误导致 PageViewController 显示多个页面,即使只剩下一个页面。在我修复它之后,PageViewController 完全按照我的意愿去做。特别是当只剩下一页时,停止滚动。 Roshni 的代码效果同样好,但是当只剩下一页时,至少在我的设置中,它在滚动时显示出华丽的效果。【参考方案2】:

谢谢,@Roshni

Swift 2 - Roshni 的解决方案

func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? 
    var index: Int = (viewController as! PageContentViewController).index

    if index == 0 || index == NSNotFound 
        index = self.pageTitles.count
    

    index--
    return viewControllerAtIndex(index)


func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? 
    var index: Int = (viewController as! PageContentViewController).index

    if index == NSNotFound 
        return nil
    

    index++
    if index == self.pageTitles.count 
        index = 0
    
    return viewControllerAtIndex(index)

【讨论】:

【参考方案3】:

这是示例,我是为循环分页做的

我使用的是 Using UIPageViewController to create a content slider (Objective-C/Swift) 文章,但感谢 @Tom Calmon 和 @Roshani 现在我能够在 Swift 2.2

上实现我想要的结果
class PageHomeViewController: UIViewController , UIPageViewControllerDataSource

    // MARK: - Variables
    private var pageViewController: UIPageViewController?

    // Initialize it right away here
    private let contentImages = ["nature_pic_1.png",
                                 "nature_pic_2.png",
                                 "nature_pic_3.png",
                                 "nature_pic_4.png"];

    //MARK: - View controller life cycle methods
    override func viewDidLoad() 
        super.viewDidLoad()
        createPageViewController()
        setupPageControl()
    

   //MARK: - Create and start page view controller
    private func createPageViewController() 
        let pageController = self.storyboard!.instantiateViewControllerWithIdentifier("PageViewController") as! UIPageViewController
        pageController.dataSource = self

        if contentImages.count > 0 
            let firstController = getItemController(0)!
            let startingViewControllers: NSArray = [firstController]
            pageController.setViewControllers(startingViewControllers as? [UIViewController], 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()
    

    // MARK: - UIPageViewControllerDataSource
    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? 
        var index: Int = (viewController as! PageContentViewController).itemIndex

        if index == 0 || index == NSNotFound 
            index = contentImages.count
        

        index -= 1
        return getItemController(index)
    

    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController?
        var index: Int = (viewController as! PageContentViewController).itemIndex
        if index == NSNotFound return nil
        index += 1
        if index == contentImages.count index = 0
        return getItemController(index)
    

    private func getItemController(itemIndex: Int) -> PageContentViewController? 
        if itemIndex < contentImages.count 
            let pageItemController = self.storyboard!.instantiateViewControllerWithIdentifier("PageContentViewController") as! PageContentViewController
            pageItemController.itemIndex = itemIndex
            pageItemController.imageName = contentImages[itemIndex]
            return pageItemController
        
        return nil
    

    // MARK: - Page Indicator
    func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int 
        return contentImages.count
    
    func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int 
        return 0
    


希望有一天这能帮助到某人!!

【讨论】:

以上是关于如何让 uipageviewcontroller 转圈的主要内容,如果未能解决你的问题,请参考以下文章

旋转到横向时如何让 UIPageViewController 工作?

如何让 UIPageViewController 使用过渡样式滚动?

如何让 UIPageViewController 知道我的异步下载何时完成?

如何设置 UIPageViewController(分页类型)手势委托

如何使 UIPageViewController 像 tableview 重用单元一样重用控制器?

如何在UIPageViewController顶部添加按钮?