"Неуравновешенные вызовы для начала и конца перехода на внешний вид для DetailViewController" при нажатии нескольких контроллеров подробных представлений

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

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

У меня есть проблема, которая проявляется, когда два уведомления истекают одновременно, что приводит к неправильному отображению представлений и, кроме того, к журналам консоли: "Неуравновешенные вызовы для перехода на начало/конец перехода для NNN", где NNN - это контроллер подробных представлений.

Контроллер табличного представления создается следующим образом:

 self.tableViewController = [[TableViewController alloc] initWithNibName:@"TableView" bundle:nil];
 UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.tableViewController];
 self.window.rootViewController = navController;

Когда локальное уведомление истекает, а didReceiveLocalNotification: вызывается, приложение транслирует уведомление с использованием NSNotifcationCenter postNotificationName: и к которому прослушивает контроллер табличного представления. Когда контроллер табличного представления получает это уведомление, он создает контроллер подробного представления и толкает его в стек как:

[self.navigationController pushViewController:detailViewController animated:YES]; 

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

Итак, я изменил код push:

[[self.navigationController topViewController].navigationController pushViewController:detailController animated:YES];

Но это не имело значения.

Итак, я подумал, что может возникнуть проблема, потому что первый контроллер подробного представления не получил возможности полностью отображать до 2-го контроллер просмотра был нажат - поэтому я изменил проводку уведомлений о приложении с помощью:

[[NSNotificationCenter defaultCenter] postNotificationName: 

к

[[NSNotificationQueue defaultQueue] enqueueNotification: postingStyle:NSPostWhenIdle]

Так что толкания не будут возникать в пределах одного и того же действия цикла приложения. Но это не имело никакого значения и не пыталось ввести задержку в нажатие кнопки просмотра деталей:

double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [[self.navigationController topViewController].navigationController     pushViewController:detailController animated:YES]; 
});

Я не знаю, в чем проблема или что попробовать дальше, любые идеи?

Ответ 1

"Несбалансированные вызовы для перехода к началу/концу отображения"

возникает, когда вы пытаетесь отобразить новый диспетчер представлений до того, как будет отображаться текущий контроллер. Вы можете воспроизвести его, перейдя в viewWillAppear.

В основном вы пытаетесь одновременно нажать два контроллера представления в стек. Предложите, чтобы вы поддерживали очередь в контроллере tableview, который поддерживает список подробных представлений, требующих отображения. Нажимайте поочередно на стек и проверяйте при выходе из текущего подробного представления, есть ли какие-либо подробные представления в очереди, требующие отображения.

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

Ответ 2

'Несбалансированные вызовы для перехода на начало/конец для "

Говорит, что анимация запускается до того, как последняя связанная анимация не будет выполнена. Итак, вы выталкиваете какой-либо контроллер, прежде чем нажимать новый? Или может появиться до корня? если да, попробуйте сделать это без анимации. т.е.

[self.navigationController popToRootViewControllerAnimated:NO];

И посмотрим, разрешило ли это проблему, В моем случае это сделало трюк.

Ответ 3

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

Итак, вы должны быть уверены, что не будете предлагать новый VC, пока первый не завершит анимацию.

Используйте didShowViewController и willShowViewController для блокировки представления нового VC до того, как старая завершит свою анимацию. Это для backButtonAction, который создает popViewController с анимацией: ДА.

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [self.myNavView.backButton addTarget:self action:@selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside];
}

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [self.myNavView.backButton removeTarget:self action:@selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside];
}

Ответ 4

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

Ответ 5

На самом деле вам нужно дождаться окончания анимации push. Таким образом, вы можете делегировать UINavigationController и предотвращать нажатие до окончания анимации.

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
    waitNavigation = NO;
}


-(void)showGScreen:(id)gvc{

    if (!waitNavigation) {
        waitNavigation = YES;
        [_nav popToRootViewControllerAnimated:NO];
        [_nav pushViewController:gvc animated:YES];
    }
}

Ответ 6

В моем случае я реализовывал пользовательский контроллер представления контейнера и получал предупреждение при замене дочерних контроллеров представления, несмотря на то, что я вызывал как beginAppearanceTransition(_:animated:) и endAppearanceTransition() как для входа, так и для выход из вида контроллеров.

Я решил это, переупорядочив вызовы методов для входящего контроллера представления; от:

addChildViewController(newContent)
targetContainer.insertSubview(newContent.view, at: 0)

newContent.beginAppearanceTransition(true, animated: animated)
// Called AFTER adding subview 

чтобы:

// Called BEFORE adding subview 
newContent.beginAppearanceTransition(true, animated: animated)

addChildViewController(newContent)
targetContainer.insertSubview(newContent.view, at: 0)

Надеюсь, это поможет кому-то!

Ответ 7

Посмотрите на эти перегрузки:

Если они пусты, то заметьте их и перестройте.

- (void) beginAppearanceTransition:(BOOL) isAppearing animated:(BOOL)animated {}
- (void) becomeActive:(NSNotification *) notification {}

Ответ 8

В моем случае проблема заключается в том, что я представляю viewController (оповещение) на уже представленном viewController (полноэкранный лист). UIKit идет вверх по родительской цепочке viewController, но не по цепочке представления, поэтому существует несоответствие при достижении представленного и корневого контроллера представления окна. Ручной вызов beginAppearanceTransition в этих случаях beginAppearanceTransition сообщения, хотя, похоже, это скорее исправление симптома, чем реальное исправление ошибки.

Ответ 9

Вы можете добавить точку останова к

-[UIViewController _endAppearanceTransition:]

откуда печатает UIKit

"Unbalanced calls to begin/end appearance transitions for %@."

Это может помочь вам с вашими расследованиями

Ответ 10

Используете ли вы функцию прокси-сервера внешнего вида?

Я нашел очень проблематичную эту функцию, в прошлый раз у меня есть

"Несбалансированные вызовы для перехода на начало/конец для"

Я решил удалить методы [[UITextField appearance] ..].

Надеюсь, что это поможет