Подтвердить что ты не робот

Ошибка утверждения в UIPageViewController

При слишком быстром переключении между вкладками в UIPageViewController приложение получает аварийный сигнал в строке

[UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:]

с ошибками Ошибка утверждения и завершение приложения из-за неотображенного исключения "NSInternalInconsistencyException", причина: "Нет диспетчера просмотра, управляющего видимым видом.

Журнал ошибок ниже

*** Assertion failure in -[UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:], /SourceCache/UIKit/UIKit-3318.0.1/UIPageViewController.m:1875
2014-09-29 11:34:00.770 Wowcher[193:9460] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'No view controller managing visible view <UIView: 0x1783fa80; frame = (0 0; 320 416); autoresize = W+RM+H+BM; layer = <CALayer: 0x17898540>>'
*** First throw call stack:
(0x219fbf87 0x2f15ac77 0x219fbe5d 0x226cb2c9 0x253f9fff 0x2546f8d3 0x2546f6b7 0x2546c2b9 0x254700db 0x25470f97 0x2546d037 0x24ea925f 0x2500a589 0x24ff7eef 0x24ea677d 0x252b8c81 0x24e70105 0x24e6e07f 0x24ea4b6d 0x24ea443d 0x24e7acc5 0x250ee513 0x24e79707 0x219c2807 0x219c1c1b 0x219c0299 0x2190ddb1 0x2190dbc3 0x28c99051 0x24ed9a31 0xd950b 0xca6e0)
libc++abi.dylib: terminating with uncaught exception of type NSException

Заранее спасибо

4b9b3361

Ответ 1

Поэтому мое решение было добавить BOOL который отслеживает состояние моей анимации. Поэтому перед установкой нового ViewController я тоже ViewController это:

if (!_transitionInProgress) {
    _transitionInProgress = YES;
    [self.pageController setViewControllers:@[viewController] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:^(BOOL finished) {
        _transitionInProgress = !finished;
    }];
}

Поэтому я подожду окончания анимации, прежде чем устанавливать новый контроллер вида. В моем случае у меня есть несколько кнопок, которые пользователь может нажимать для переключения страниц. Это также мешает им проходить слишком быстро, поэтому анимация всегда плавная и приятная

Ответ 2

Это ошибка во внутренней реализации UIPageViewController в режиме прокрутки. Это происходит, когда анимация перехода возникает, когда контроллер просмотра страниц уже оживляет переход. То, что я закончил, заключалось в том, чтобы заблокировать пользовательский интерфейс, позволяя нескольким быстрым прокруткам. У меня есть две кнопки, слева и справа, которые позволяют контроллеру просмотра страницы прокручиваться до предыдущего или следующего контроллера страницы. Я отключу работу кнопок, пока идет анимация. Делегат контроллера просмотра страницы сообщает вам все, что вам нужно знать, когда нужно отключить функциональность пользовательского интерфейса и когда его снова включить, как только все анимации остановились.

Ответ 3

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

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

- (void) setViewControllers:(NSArray*)viewControllers direction:(UIPageViewControllerNavigationDirection)direction animated:(BOOL)animated completion:(void (^)(BOOL))completion {

    if (!animated) {
        [super setViewControllers:viewControllers direction:direction animated:NO completion:completion];
        return;
    }

    [super setViewControllers:viewControllers direction:direction animated:YES completion:^(BOOL finished){

        if (finished) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [super setViewControllers:viewControllers direction:direction animated:NO completion:completion];
            });
        } else {
            if (completion != NULL) {
                completion(finished);
            }
        }
    }];
}

Ответ 4

Здесь очень хорошая дискуссия:

Удаление контроллера представления из UIPageViewController

Принятый ответ обсуждает это:

"Не зная точно, почему это происходит, я отступил назад и в конце концов начал использовать ответ Jai в качестве решения, создав совершенно новый UIPageViewController, нажав на UINavigationController, а затем вытащил старый. он работает - в основном. Я обнаружил, что по-прежнему получаю случайные сбои утверждений от UIPageViewController, как этот:

  • Ошибка утверждения в [UIPageViewController queueingScrollView: didEndManualScroll: toRevealView: direction: animated: didFinish: didComplete:], /SourceCache/UIKit _Sim/UIKit-2380.17/UIPageViewController.m:1820 $1 = 154507824 Нет диспетчера просмотра, управляющего видимым видом >

И приложение выйдет из строя. Зачем? Ну, в поисках, я нашел этот другой вопрос, о котором я упоминал, и, в частности, принятый ответ, который защищает мою первоначальную идею, просто вызывает setViewControllers: animated:YES, а затем, как только он завершает вызов setViewControllers: animated:NO с теми же контроллерами представления, что и reset UIPageViewController, но у него был отсутствующий элемент: вызов этого кода обратно в главную очередь! Здесь код: "

Ответ 5

Я исправил проблему, установив edgesForExtendedLayout = UIRectEdgeNone в мой подкласс UIPageViewController:

- (instancetype)initWithTransitionStyle:(UIPageViewControllerTransitionStyle)style navigationOrientation:(UIPageViewControllerNavigationOrientation)navigationOrientation options:(NSDictionary<NSString *,id> *)options
{
    self = [super initWithTransitionStyle:style navigationOrientation:navigationOrientation options:options];

    self.edgesForExtendedLayout = UIRectEdgeNone;

    return self;
}

Ответ 6

Я также столкнулся с такой же ситуацией, и в моем приложении есть кнопки "Провести" и "Следующий" и "Предыдущий" для перемещения назад и вперед. Чтобы устранить проблему, присвойте локальной переменной Bool значение true во время инициализации (скажем, private var canScroll: Bool = true), затем проверьте состояние в первой строке метода навигации, используя guard, затем установите значение Bool в false перед методом setViewcontroller. по завершении анимации установите для того же bool значение true, чтобы при выполнении действия смахивания во время перехода контроллера представления оператор защиты проверял, может ли canScroll быть истинным, если не возвращается. что то, как вы можете избежать проблемы сбоя в разбивке по страницам ниже, - мой код для следующего действия

 @IBAction func nextAction(_ sender: Any) {
            guard canScroll == true else { return } //check condition
            guard featureCount > 0 else { return }
    guard let index = self.viewControllerAtIndex(indexRow) else { return }
            let startingViewController: OnBoardModelViewController = index
            canScroll = false 
            pageViewController?.setViewControllers([startingViewController],
                                                   direction: UIPageViewControllerNavigationDirection.forward,
                                                   animated: true,
                                                   completion: {_ in
                                                    self.canScroll = true
            })
}