Несбалансированное вызовы begin и End возникновение переходы для


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

я получил это сообщение, когда я добавил контроллер вида изначально:

Unbalanced calls to begin/end appearance transitions for 
<UITabBarController: 0x197870>

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

я получил 5-tab TabBarController, связанный с 5 контроллерами представления. На начальной вкладке показа я вызываю новый контроллер представления для наложения в качестве введения приложения.

Я использую этот код для вызова введение контроллер вида:

IntroVC *vc = [[IntroVC alloc] init];
[self presentModalViewController:vc animated:YES];
[vc release]; 

после этого IntroVC представление-контроллер отображается, показывает ошибку.

p. s.Я использую Xcode 4.2 & iOS 5.0 SDK, разрабатывая приложение iOS 4.3.

20 104

20 ответов:

не видя больше окружающего кода, я не могу дать определенного ответа, но у меня есть две теории.

  1. вы не используете UIViewController ' s назначенный инициализатор initWithNibName:bundle:. Попробуйте использовать его вместо того, чтобы просто init.

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

я исправил эту ошибку, изменив анимацию с да на нет.

от:

[tabBarController presentModalViewController:viewController animated:YES];

To:

[tabBarController presentModalViewController:viewController animated:NO];

Как написал danh

вы можете сгенерировать это предупреждение, представив модальный vc до завершения инициализации приложения. т. е. запустите приложение шаблона приложения с вкладками и представьте модальный vc поверх себя.tabBarController как последняя строка в приложении: didFinishLaunching. Появится предупреждение. Решение: пусть стек сначала раскрутится, представит модальный vc в другом методе, вызванном с помощью performSelector withDelay: 0.0

попробуйте переместить метод в viewWillAppear и охраняет его, поэтому он выполняется только один раз (рекомендуется настроить свойство)

У меня была та же проблема, когда мне нужно представить мой контроллер представления входа из другого контроллера представления, если пользователь не авторизован, я сделал это в методе ViewDidLoad моего другого контроллера представления ( если не авторизован -> presentModalViewController ). Когда я начинаю делать это в методе ViewDidAppear, я решил эту проблему. Я думаю, что ViewDidLoad только инициализирует свойства, и после этого начинается фактический алгоритм отображения вида! Thats, почему вы должны использовать viewDidAppear метод, чтобы сделать модал переходы!

у меня была та же проблема. Я вызвал метод внутри viewDidLoad внутри моего первого UIViewController

- (void)viewDidLoad{
    [self performSelector:@selector(loadingView)
               withObject:nil afterDelay:0.5];
}

- (void)loadingView{

    [self performSegueWithIdentifier:@"loadedData" sender:self];
}

во втором UIViewController Я сделал то же самое и с задержкой 0,5 секунды. После изменения задержки на более высокое значение, он работал нормально. Это похоже на то, что сегмент не может быть выполнен слишком быстро после другого сегмента.

у меня было много проблем с той же проблемой. Я решил эту проблему с помощью

  1. инициирование ViewController с помощью метода storyboad instantiateViewControllerWithIdentifier. я.е Intro *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"introVC"];
  2. [self.tabBarController presentModalViewController : vc animated:YES];

у меня есть viewcontroller в моей раскадровке, по какой-то причине используя только [[introvc alloc] init]; не работает для меня.

Я решил ее писать!--2-->

[self.navigationController presentViewController:viewController 
                                        animated:TRUE 
                                      completion:NULL];

еще одно решение для многих случаев, чтобы убедиться, что переход между UIViewController s случается после не подходит (как во время инициализации) процедура заканчивается, выполнив:

__weak MyViewController *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    [weakSelf presentViewController:vc animated:YES];
});

Это общее для Также pushViewController:animated: и т. д.

у меня была такая же ошибка. У меня есть панель вкладок с 3 элементами, и я бессознательно пытался вызвать корневой контроллер представления элемента 1 в пункте 2 моей панели вкладок с помощью performSegueWithIdentifier.

что происходит, так это то, что он вызывает контроллер вида и возвращается к корневому контроллеру вида элемента 2 через несколько секунд и регистрирует эту ошибку.

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

Так вместо performSegueWithIdentifier

I используется [self.parentViewController.tabBarController setSelectedIndex:0];

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

у меня была такая же проблема, и я думал, что опубликую, если кто-то еще столкнется с чем-то подобным.

в моем случае я прикрепил распознаватель жестов длительного нажатия к моему UITableViewController.

UILongPressGestureRecognizer *longPressGesture = [[[UILongPressGestureRecognizer alloc]
                                                   initWithTarget:self
                                                   action:@selector(onLongPress:)]
                                                  autorelease];
[longPressGesture setMinimumPressDuration:1];
[self.tableView addGestureRecognizer:longPressGesture];

в моем селекторе onLongPress я запустил свой следующий контроллер вида.

- (IBAction)onLongPress:(id)sender {

    SomeViewController* page = [[SomeViewController alloc] initWithNibName:@"SomeViewController" bundle:nil];

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

    [page release];

}

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

решение состояло в том, чтобы добавить логическое значение, чтобы указать, когда SomeViewController был помещен в стек. Когда был вызван метод viewWillAppear моего UITableViewController, я вернул логическое значение NO.

У меня была эта проблема с кодом третьей стороны. Кто-то забыл установить супер внутри viewWillAppear и viewWillDisappear в пользовательском классе TabBarController.

- (void) viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];
    // code...
}

or

- (void) viewWillDisappear:(BOOL)animated {

    [super viewWillDisappear:animated];
    // code...
}

In Swift 2+ для меня работает:

У меня есть UITabBarViewController в раскадровке, и я выбрал свойство index следующим образом:

enter image description here

но я удаляю его и добавляю в свой метод viewDidLoad моего начального класса, например:

override func viewDidLoad() {
   super.viewDidLoad()
   self.tabBarController?.selectedIndex = 2
}

Я надеюсь, что смогу помочь кому-то.

если вы используете transitioningDelegate (не так в примере этого вопроса), также установите modalPresentationStyle до .Custom.

Свифт

let vc = storyboard.instantiateViewControllerWithIdentifier("...")
vc.transitioningDelegate = self
vc.modalPresentationStyle = .Custom

у меня была такая проблема из-за опечатки:

override func viewDidAppear(animated: Bool) {
    super.viewWillAppear(animated)

вместо

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

он вызывал "WillAppear" в супер вместо "DidAppear"

на самом деле вам нужно подождать, пока не закончится анимация толчка. Таким образом, вы можете делегировать 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];
    }
}

как предположил @danh, моя проблема заключалась в том, что я представлял модальный vc перед UITabBarController готово. Тем не менее, я чувствовал себя неловко опираясь на определенный фиксированный срок, прежде чем представить контроллер представления (из моего тестирования, я должен использовать 0.05-0.1 с задержка в performSelector:withDelay:). Мое решение-добавить блок, который вызывается на UITabBarController ' s viewDidAppear: способ:

PRTabBarController.h:

@interface PRTabBarController : UITabBarController

@property (nonatomic, copy) void (^viewDidAppearBlock)(BOOL animated);

@end

PRTabBarController.м:

#import "PRTabBarController.h"

@implementation PRTabBarController

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (self.viewDidAppearBlock) {
        self.viewDidAppearBlock(animated);
    }
}

@end

сейчас application:didFinishLaunchingWithOptions:

PRTabBarController *tabBarController = [[PRTabBarController alloc] init];

// UIWindow initialization, etc.

__weak typeof(tabBarController) weakTabBarController = tabBarController;
tabBarController.viewDidAppearBlock = ^(BOOL animated) {
    MyViewController *viewController = [MyViewController new];
    viewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
    [weakTabBarController.tabBarController presentViewController:navigationController animated:NO completion:nil];
    weakTabBarController.viewDidAppearBlock = nil;
};

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

вам нужно убедиться, что- (void)beginAppearanceTransition: (BOOL)isappearing animated: (BOOL)animated и - (void)endAppearanceTransition создаются вместе в классе.

у меня была эта проблема, когда я перешел от корневого TVC к TVC A, а затем к TVC B. После нажатия кнопки "Загрузить" в TVC B я хотел сразу вернуться к корневому TVC (нет необходимости возвращаться к TVC a, так зачем это делать). У меня было:

//Pop child from the nav controller
[self.navigationController popViewControllerAnimated:YES];
//Pop self to return to root
[self.navigationController popViewControllerAnimated:YES];

...что дало ошибку "несбалансированные вызовы для начала / конца и т. д.". Ниже Исправлена ошибка, но без анимации:

//Pop child from the nav controller
[self.navigationController popViewControllerAnimated:NO];
//Then pop self to return to root
[self.navigationController popViewControllerAnimated:NO];

Это было мое окончательное решение, без ошибок и еще анимированные:

//Pop child from the nav controller
[self.navigationController popViewControllerAnimated:NO];
//Then pop self to return to root, only works if first pop above is *not* animated
[self.navigationController popViewControllerAnimated:YES];

я столкнулся с этой ошибкой, когда я подключил UIButton к раскадровке segue action (в IB), но позже решил, что кнопка программно вызывает performSegueWithIdentifier забыв удалить первый из IB.

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

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