it-swarm.com.ru

Несбалансированные вызовы для начала/окончания переходов внешнего вида для <UITabBarController: 0x197870>

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

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

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

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

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

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

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

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

постскриптум Я использую xCode 4.2 и iOS 5.0 SDK, разрабатываю приложение для iOS 4.3.

105
Raptor

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

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

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

92
Jesper

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

От:

[tabBarController presentModalViewController:viewController animated:YES];

Для того, чтобы:

[tabBarController presentModalViewController:viewController animated:NO];
38
PokerIncome.com

Как опубликовано Данх

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

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

15
Peter Lapisu

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

3
Tolusha

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

- (void)viewDidLoad{
    [super viewDidLoad];

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

- (void)loadingView{

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

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

3
Alex Cio

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

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

вместо 

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

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

2
Adriano Spadoni

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

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

Это также правило для pushViewController:animated: и т.д.

2
mllm

Я решил это, написав

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

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

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

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

2
Mogambolal

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

- (void) viewWillAppear:(BOOL)animated {

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

or

- (void) viewWillDisappear:(BOOL)animated {

    [super viewWillDisappear:animated];
    // code...
}
1
J. Lopes

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

В моем случае я подключил распознаватель жестов длинным нажатием к своему 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.

1
Dale Moore

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

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

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

Так что вместо performSegueWithIdentifier 

Я использовал [self.parentViewController.tabBarController setSelectedIndex:0];

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

1
Gellie Ann

В Swift 2+ у меня работает:

У меня есть UITabBarViewController в раскадровке, и я выбрал свойство selectedIndex, как это:

 enter image description here

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

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

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

1
Dasoga

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

Swift

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

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

0
zszen

На самом деле вам нужно дождаться окончания анимации 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];
    }
}
0
ymutlu

Я была такая же проблема. При разработке я хотел обойти экраны. Я переходил от одного контроллера представления к другому в viewDidLoad, вызывая метод селектора.

Проблема в том, что мы должны позволить ViewController завершить переход, прежде чем переходить к другому ViewController.

Это решило мою проблему: задержка необходима, чтобы позволить ViewControllers завершить переход перед переходом к другому.

self.perform(#selector(YOUR SELECTOR METHOD), with: self, afterDelay: 0.5)

0
codeedoc

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

0
Dan Levy

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

PRTabBarController.h:

@interface PRTabBarController : UITabBarController

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

@end

PRTabBarController.m:

#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;
};
0
johnboiles