Мой UIPageViewController отлично работал в iOS 5. Но когда появился iOS 6, я хотел использовать новый стиль перехода с прокруткой (UIPageViewControllerTransitionStyleScroll) вместо стиля завитки страницы. Это заставило мой UIPageViewController сломаться.
Ответ 8
О:
Похоже, Apple заметила, что разработчики используют UIPageViewController в самых разных приложениях, выходящих за рамки
изначально предназначенные Apple, основываясь на своих дизайнерских решениях, в первую очередь. Вместо того, чтобы использовать его в линейном режиме жестов
ПВХ часто используется для программного перехода к случайным
позиции в структурированной среде. Таким образом, они улучшили реализацию UIPageViewController, и теперь класс вызывает оба источника данных DataSource
обратные вызовы
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
после установки нового ContentViewController в UIPageViewController с
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
даже если анимированный поворот страниц скорее предполагает линейный прогресс в, например, иерархию страниц, например, книгу или PDF с последовательными страницами. Хотя - я сомневаюсь, что Apple с точки зрения HIG
очень любит видеть, что ПВХ используется таким образом, но - он не нарушает совместимость в обратном направлении, это было простое исправление, поэтому - они в конце концов это сделали. На самом деле это всего лишь один вызов одного из двух методов DataSource, который абсолютно не нужен в линейной среде, где страницы (ViewControllers) уже были обналичены для последующего использования.
Однако, даже если это усовершенствование может оказаться очень удобным для определенных случаев использования, первоначальное поведение класса НЕ считается ошибкой. Тот факт, что многие разработчики делают - также в других
сообщения о SO, которые обвиняют UIPageViewController в неправильном поведении, - скорее подчеркивает широко распространенное заблуждение в отношении его дизайна, назначения и функциональности.
Не пытаясь оскорбить кого-либо из моих коллег-разработчиков здесь, на этом великом объекте, я тем не менее решил не удалять мою первоначальную "разборку", которая четко объясняет OP механикой ПВХ и почему его предположение неверно, что он должен иметь дело с ошибка здесь.
Это также может быть полезно для любого другого разработчика-разработчика, который борется с некоторыми сложностями в реализации UIPageViewController!
ОРИГИНАЛЬНЫЙ ОТВЕТ:
После того, как вы прочитали все ответы снова и снова, включили
принят один - есть еще одна вещь, которую можно сказать...
Конструкция UIPageViewController
абсолютно FLAWLESS, и все
хаки, которые вы отправляете, чтобы обойти предполагаемую ошибку, - это не что иное, как
средства для ваших собственных ошибочных предположений, потому что вы справились с этим в
первое место!!!
БЕСПЛАТНО ВСЕ! Вы просто сражаетесь с каркасом. Я объясню, почему!
Существует столько разговоров о номерах страниц и индексах! Это концепции
контроллер знает НИЧЕГО! Единственное, что он знает, - это показ
некоторый контент (кстати, предоставленный вами как dataViewController), и что он может
сделайте что-то вроде анимации справа/слева, чтобы подражать повороту страницы.
CURL
или SCROLL
...!!!
В мире pageViewController существует только текущий SPACE
(пусть вызов
это просто так, чтобы избежать путаницы со страницами и индексами).
Когда вы первоначально устанавливаете pageViewController, он только об этом думает SPACE
.
Только когда вы начинаете панорамирование своего вида, он начинает спрашивать его DataSource
, что он
в конечном итоге должен отображаться в случае, когда должен произойти щелчок влево/вправо. Когда ты начинаешь
панорамирование влево, ПВХ сначала запрашивает BEFORE-SPACE
, а затем для
AFTER-SPACE
, в случае, если вы начнете вправо, он делает это наоборот.
После завершенной анимации (новый вид SPACE
отображается в виде PVC)
ПВХ считает этот SPACE
своим новым центром вселенной, и хотя он находится в нем, он
спрашивает DataSource
о том, о чем он все еще ничего не знает. В случае
законченный поворот направо, который он хочет знать о новом пространстве AFTER
и в
в случае завершенного поворота влево он запрашивает новое пространство BEFORE
.
Старое пространство BEFORE
(начиная с анимации) в случае завершенного перехода к
право полностью устарело и освобождается как можно скорее. Старый center
теперь новый BEFORE
, а первый AFTER
- новый center
. Все просто
сдвинуто на один шаг вправо.
Итак, не говорите "какая страница" или "любой индекс" - просто - есть ли BEFORE
или
a AFTER
. Если вы вернете NIL в один из обратных вызовов DataSource
, только ПВХ
предполагает, что он находится на одной крайности вашего range of SPACES
. Если вы вернете NIL на оба
обратный вызов предполагает, что он показывает one and only SPACE
, и он никогда не будет
снова снова вызывайте обратный вызов DataSource
! Логика зависит от вас! Вы определяете
страниц и индексов в вашем коде! Не ПВХ!!!
Для пользователя класса есть два способа взаимодействия с ПВХ.
-
A pan-gesture that indicates whether a turn to the BEFORE/AFTER space is desired
-
A method - namely setViewControllers:direction:animated:completion:
Этот метод делает то же самое, что и жест панорамы. Вы указываете
направлении (например, UIPageViewControllerNavigationDirectionBackward/Forward
)
для анимации - если есть одно предназначение - что, другими словами, просто означает → собирается
BEFORE
или AFTER
...
Опять же - не упоминание индексов, номеров страниц и т.д.....!!!
Это просто программный способ добиться того же жеста!
И ПВХ делает все правильно, показывая старый контент снова, когда вы двигаетесь назад
влево, после того, как он переместился вправо в первую очередь. Запомнить
- он просто показывает контент (который вы предоставляете) структурированным способом - это 'single page turn'
по дизайну!!!
Это концепция поворота страницы - или BOOK, если вам нравится этот термин лучше!
Просто потому, что вы делаете это, отправляя СТРАНИЦУ 8 после СТРАНИЦЫ 1, не означает, что ПВХ
заботится вообще о вашем искривленном мнении о том, как книга должна работать. И пользователь вашего
приложений нет. Перевертывание вправо и назад влево обязательно должно привести к достижению
исходная страница - IF выполнена с анимацией. И вы должны исправить ошибку
найти решение для катастрофы. Не обвиняйте его в UIPageViewController
. Он делает
его работа отлично!
Просто спросите себя - вы бы сделали то же самое с анимацией PAGE-CURL
? НЕТ?
Ну, и вы не должны с анимацией SCROLL
!!! Анимированный поворот страницы - это поворот страницы и только поворот страницы!
В любом режиме!
И если вы решите оторвать СТРАНИЦУ 2 к СТРАНИЦЕ 7 вашей КНИГИ, это прекрасно!
Но просто не ожидайте, что UIPageViewController
придумает несуществующую СТРАНИЦА 7, когда вернется к последней странице, если вы не скажете, что все изменилось...
Если вы действительно хотите достичь нескоординированного перехода в другое место, хорошо сделайте это без
анимация! В большинстве случаев это будет не очень элегантно, но... возможно... -
И ПВХ даже отлично играет! При переходе на новый SPACE
без анимации
он попросит вас дальше по дороге для обоих - контроллера BEFORE
и AFTER
. Таким образом, ваша прикладная логика может идти в ногу с ПВХ...
Но с анимацией, которую вы всегда передаете, перейдите в предыдущее/следующее пространство (BEFORE -
AFTER
). Так логично, что нет необходимости вообще в ПВХ, чтобы снова спросить о пространстве, которое уже было
знает о том, когда анимационная страница поворачивается!!!
Если вы хотите увидеть СТРАНИЦУ 7, когда вы поворачиваете назад влево после анимации с PAGE 1
направо - ну, я бы сказал - это определенно ваша собственная проблема!
И на всякий случай вы ищете лучшее решение, чем "взломать блок" из
принятый ответ (потому что с ним вы делаете работу заранее для чего-то, что могло бы
возможно, даже не будет использоваться дальше по дороге) используйте делегата распознавателя жестов:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
Установите свой PVC DataViewController здесь (без анимации), если вы действительно собираетесь вернуться
слева на СТРАНИЦА 7 и DataSource
будет запрашиваться BEFORE
и AFTER
, и вы можете отправить
любую страницу, которая вам нравится! С флагом или иваром, которые вы должны были спрятать, когда делаете свой неконтролируемый
переход с СТРАНИЦЫ 1-8, это не должно быть проблемой...
И когда люди продолжают жаловаться на ошибку в ПВХ - делают 2 оборота страницы, когда это
Предполагается сделать только один поворот - указать на эту статью.
Такая же проблема - запуск неанимированного setViewControllers: метод в переходном жесте
приведет к такому же хаосу. Вы думаете, что вы устанавливаете новый центр - запрашивается DataSource
для нового BEFORE - AFTER
dataController - вы reset ваш индексный счет... - Ну, это кажется ОК...
Но - после всего этого бизнеса ПВХ заканчивает свой переход/анимацию и хочет знать о
следующий (еще неизвестный ему) dataViewController (BEFORE
или AFTER
), а также запускает DataSource
. Это полностью оправдано! Он должен знать, где в его маленьком BEFORE - CENTER - AFTER
мир и готов к следующему повороту.
Но ваша программная логика добавляет еще один индекc++ к его логике и внезапно получает 2 оборота страницы!!!
И это одно от того, где вы думаете.
И ВЫ должны это учитывать! Не UIPageViewController
!!!
Это точно точка DataSourceProtocol, имеющая только два метода! Он хочет быть как можно более общим, оставив вам пространство и свободу, чтобы определить вашу собственную логику и не зацикливаться на чьих-либо других особых идеях и прецедентах! Логика полностью зависит от вас. И только потому, что вы найдете такие функции, как
- (DataViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard position:(GSPositionOfDataViewController)position;
- (NSUInteger)indexOfViewController:(DataViewController *)viewController;
во всех экземплярах с копией/вставкой в облаке не обязательно означает, что вы должны есть эту пищу заранее приготовленной пищи! Расширьте их так, как вам нравится! Посмотрите выше - в моей подписи вы найдете аргумент 'position:'
! Я продлил это, чтобы узнать позже, если завершенный поворот страницы был правильным или левым поворотом. Потому что делегат, к сожалению, просто говорит вам, завершена ли ваша очередь или нет! Это не говорит вам о направлении! Но это иногда имеет значение для подсчета индексов, в зависимости от вашего приложения...
Иди с ума - они твои...
СЧАСТЛИВЫЙ КОДИРОВАНИЕ!!!