2017-01-08 1 views
0

У моего приложения есть журнал, в котором находится 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 в UIPageViewController, а затем возвращает сконфигурированный страницу журнала. Проблема в том, что часто дублируются страницы (страницы за ту же дату) или пропущена страница/дата. Я нашел this вопрос, но не вижу, как я могу реализовать что-то подобное.

Я работал с UIPageViewController раньше и всегда использовал индекс, чтобы обойти это, но в этом случае индекс не имеет смысла, поскольку вы можете прокручивать начало/конец времени (буквально).

Как я могу гарантировать, что новая страница будет сделана в правильное время, чтобы избежать дублирования/пропущенных дат?

ответ

1

Я решил проблему без использования указателя (достаточно указать свойство 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 
    } 
} 
0

Я думаю, что вы должны моделировать свои данные по-другому, поэтому создайте модель, содержащую массив с вашими данными, и (например) используйте индекс для доступа к dato для заполнения контроллера. таким образом вы получаете уникальный доступ к данным.

Я сделал это в приложении для загрузки страницы, начиная с образца яблока.

У меня есть класс (см шаблон яблоко сравнить ..)

класса 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 
} 
0

не могли бы вы использовать Juilan номер дня (JDN) как номер индекса?

+0

Мне нравится эта идея, но это ломается при использовании других систем календаря, не так ли? – jjatie

+0

iOS позволяет легко конвертировать между календарями, поэтому вы можете использовать дату Juilan для своего индекса, а затем сопоставить эту дату в календаре пользователя для отображения. –