创建具有无限滚动天数的UIPageViewController

时间:2017-01-08 18:12:34

标签: ios uipageviewcontroller

我的应用程序中有一个由UIPageViewController控制的日记。页面的视图控制器工作正常,但UIPageViewController有一些不稳定的行为。首先,委托方法(页面视图控制器是它自己的委托):

private func journalPage(for date: Date) -> JournalViewController? {
    // Create a new view controller and pass suitable data.
    guard let journalPage = storyboard?.instantiateViewController(withIdentifier: JournalViewController.storyboardID) as? JournalViewController else {
        return nil
    }

    journalPage.date = date
    return journalPage
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
    guard let yesterday = calendar.date(byAdding: .day, value: -1, to: self.date) else {
        return nil
    }

    self.date = calendar.startOfDay(for: yesterday)        
    return journalPage(for: self.date)
}

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

    guard let tomorrow = calendar.date(byAdding: .day, value: 1, to: self.date) else {
        return nil
    }

    self.date = calendar.startOfDay(for: tomorrow)
    return journalPage(for: self.date)
}

我更新date的{​​{1}},然后返回已配置的日记页面。问题是通常存在重复的页面(同一日期的页面),或者跳过页面/日期。我发现了this个问题,但是我不知道如何实现类似的东西。

之前我曾与UIPageViewController合作并且一直使用索引来解决这个问题,但在这种情况下,索引没有意义,因为您可以滚动到开头/结尾时间(字面意思)。

如何确保在正确的时间制作新页面以避免重复/错过日期?

3 个答案:

答案 0 :(得分:2)

我在不使用索引的情况下解决了问题(页面上的date属性就足够了)。这无限制地向任一方向滚动,而不会创建重复或跳过页面。

extension JournalPageViewController: UIPageViewControllerDataSource {
    /// Creates and returns a JournalViewController if it can be found in the storyboard,
    /// and sets it's date to `date`
    private func journalPage(for date: Date) -> JournalViewController? {
        // Create a new view controller and pass suitable data.
        guard let journalPage = storyboard?.instantiateViewController(withIdentifier: JournalViewController.storyboardID) as? JournalViewController else {
            return nil
        }

        journalPage.date = date
        return journalPage
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        debugPrint("Before: ", separator: "", terminator: "")
        let today = (viewController as! JournalViewController).date
        guard var yesterday = calendar.date(byAdding: .day, value: -1, to: today) else {
            return nil
        }
        yesterday = calendar.startOfDay(for: yesterday)

        return journalPage(for: yesterday)
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        debugPrint("After: ", separator: "", terminator: "")
        let today = (viewController as! JournalViewController).date
        guard var tomorrow = calendar.date(byAdding: .day, value: 1, to: today) else {
            return nil
        }
        tomorrow = calendar.startOfDay(for: tomorrow)

        return journalPage(for: tomorrow)
    }
}

extension JournalPageViewController: UIPageViewControllerDelegate {
    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        self.date = (self.viewControllers?.first as! JournalViewController).date
    }
}

答案 1 :(得分:0)

我认为您必须以另一种方式为数据建模,因此创建一个包含数据的数组的模型,并且(例如)使用索引来访问dato以填充控制器。通过这种方式,您可以唯一地访问数据。

我在一个基于PageController的应用程序中这样做,从apple sample开始。

我有一个课程:(请参阅苹果模板进行比较..)

class ModelController:NSObject,UIPageViewControllerDataSource {

var myPages : [Page]?

.. }

其中Page是描述单页的类。 我用这种方式修改了苹果代码:

func viewControllerAtIndex(_ index: Int) -> BaseHWTestController? {
    // Return the data view controller for the given index.

    let count = selected.count
    if (count == 0) || (index >= count) {
        return nil
    }

    // Create a new view controller and pass suitable data.

    let myController = storyboard.instantiateViewController(withIdentifier: identifier) as! CustomPageController
    // set ref. to data inside the controller:
    BaseHWTestController.dataObject = myPages[index]
    return BaseHWTestController
} 

答案 2 :(得分:0)

你不能使用Juilan Day Number(JDN)作为索引号吗?