对的开始/结束外观转换的调用不平衡
我读到另一位用户遇到类似的错误,但是这个错误是在不同的情况下发生的。
当我最初添加视图控制器时,我收到了这条消息:
Unbalanced calls to begin/end appearance transitions for
<UITabBarController: 0x197870>
应用程序的结构如下:
我有一个链接到 5 个视图控制器的 5 个选项卡 TabBarController。在最初的显示选项卡中,我调用了一个新的视图控制器来覆盖作为应用程序的介绍。
我使用此代码调用介绍视图控制器:
IntroVC *vc = [[IntroVC alloc] init];
[self presentModalViewController:vc animated:YES];
[vc release];
此 IntroVC
视图控制器显示后,显示上述错误。
ps 我正在使用 xCode 4.2 & iOS 5.0 SDK,开发iOS 4.3应用程序。
I read SO about another user encountering similar error, but this error is in different case.
I received this message when I added a View Controller initially:
Unbalanced calls to begin/end appearance transitions for
<UITabBarController: 0x197870>
The structure of the app is as follow:
I got a 5-tab TabBarController linked to 5 View Controllers. In the initial showing tab, I call out a new View Controller to overlay as an introduction of the app.
I use this code to call the introduction view controller:
IntroVC *vc = [[IntroVC alloc] init];
[self presentModalViewController:vc animated:YES];
[vc release];
After this IntroVC
view controller shows up, the above error shows.
p.s. I am using xCode 4.2 & iOS 5.0 SDK, developing iOS 4.3 app.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(24)
对我来说,发生此错误是因为在设置根视图控制器时,我没有在类的上层声明
UIWindow
Ex,如果我尝试在该块中声明
window
代码而不是引用 self 那么我会收到错误For me this error occurred because i didn't have
UIWindow
declared in the upper level of my class when setting a root view controllerEx if I tried declaring
window
in that block of code instead of referencing self then I would receive the error当尝试呈现通过闭包延迟初始化的
UINavigationController
时,将显示此错误。This error will be displayed when trying to present an
UINavigationController
that is lazily initialized via a closure.当我从根 TVC 导航到 TVC A,然后导航到 TVC B 时,我遇到了这个问题。点击 TVC 中的“加载”按钮后,BI 想要直接跳回根 TVC(无需重新访问 TVC A,所以为什么要这样做) 。我有:
...这给出了错误“对开始/结束等的不平衡调用”。以下修复了错误,但没有动画:
这是我的最终解决方案,没有错误并且仍然有动画:
I had this problem when I had navigated from root TVC to TVC A then to TVC B. After tapping the "load" button in TVC B I wanted to jump straight back to the root TVC (no need to revisit TVC A so why do it). I had:
...which gave the error "Unbalanced calls to begin/end etc". The following fixed the error, but no animation:
This was my final solution, no error and still animated:
当我将 UIButton 连接到故事板 segue 操作(在 IB 中)时遇到此错误,但后来决定让按钮以编程方式调用
performSegueWithIdentifier
忘记从 IB 中删除第一个。本质上,它执行了两次 segue 调用,给出了这个错误,并且实际上将我的视图推送了两次。修复方法是删除其中一个 segue 调用。
希望这可以帮助像我一样疲惫的人!
I encountered this error when I hooked a UIButton to a storyboard segue action (in IB) but later decided to have the button programatically call
performSegueWithIdentifier
forgetting to remove the first one from IB.In essence it performed the segue call twice, gave this error and actually pushed my view twice. The fix was to remove one of the segue calls.
Hope this helps someone as tired as me!
斯威夫特5
Swift 5
如果没有看到更多周围的代码,我无法给出明确的答案,但我有两种理论。
您没有使用
UIViewController
的 指定初始化器initWithNibName:bundle:
。尝试使用它而不仅仅是init
。此外,
self
可能是选项卡栏控制器的视图控制器之一。始终从最顶层的视图控制器呈现视图控制器,这意味着在这种情况下要求选项卡栏控制器代表视图控制器呈现覆盖视图控制器。您仍然可以将任何回调委托保留给真正的视图控制器,但您必须让选项卡栏控制器存在并关闭。Without seeing more of the surrounding code I can't give a definite answer, but I have two theories.
You're not using
UIViewController
's designated initializerinitWithNibName:bundle:
. Try using it instead of justinit
.Also,
self
may be one of the tab bar controller's view controllers. Always present view controllers from the topmost view controller, which means in this case ask the tab bar controller to present the overlay view controller on behalf of the view controller. You can still keep any callback delegates to the real view controller, but you must have the tab bar controller present and dismiss.我通过将动画从“是”更改为“否”来修复此错误。
从:
到:
I fixed this error by changing animated from YES to NO.
From:
To:
正如 danh 所发布的
您可以通过在应用程序初始化之前显示模态 vc 来生成此警告。即启动一个选项卡式应用程序模板应用程序并在 self.tabBarController 之上呈现一个模态 vc 作为 application:didFinishLaunching 中的最后一行。出现警告。解决方案:首先让堆栈展开,在另一个方法中呈现模态 vc,使用 PerformSelector withDelay:0.0 调用
尝试将该方法移动到 viewWillAppear 中并保护它,以便它只执行一次(建议设置财产)
As posted by danh
You can generate this warning by presenting the modal vc before the app is done initializing. i.e. Start a tabbed application template app and present a modal vc on top of self.tabBarController as the last line in application:didFinishLaunching. Warning appears. Solution: let the stack unwind first, present the modal vc in another method, invoked with a performSelector withDelay:0.0
Try to move the method into the viewWillAppear and guard it so it does get executed just once (would recommend setting up a property)
许多情况下的另一个解决方案是确保 UIViewController 之间的转换发生在不适合的(例如在初始化期间)过程完成之后,通过执行
以下 操作:还有
pushViewController:animated:
等。Another solution for many cases is to make sure that the transition between
UIViewController
s happens after the not-suitable (like during initialization) procedure finishes, by doing:This is general for also
pushViewController:animated:
, etc.我也有同样的问题。我在第一个
UIViewController
内的viewDidLoad
中调用了一个方法。在第二个
UIViewController
内,我也做了同样的事情,延迟了 0.5 秒。将延迟更改为更高的值后,效果很好。就像在另一个segue之后segue不能执行得太快一样。I had the same problem. I called a method inside
viewDidLoad
inside my firstUIViewController
Inside the second
UIViewController
I did the same also with 0.5 seconds delay. After changing the delay to a higher value, it worked fine. It's like the segue can't be performed too fast after another segue.当我需要从另一个视图控制器呈现我的登录视图控制器时,我遇到了同样的问题如果用户未经授权,我在另一个视图控制器的 ViewDidLoad 方法中完成了它(如果未经授权 - >presentModalViewController)。当我开始在 ViewDidAppear 方法中制作它时,我解决了这个问题。我认为 ViewDidLoad 仅初始化属性,然后实际显示视图算法开始!这就是为什么你必须使用 viewDidAppear 方法来进行模式转换!
I had the same problem when I need to Present My Login View Controller from another View Controller If the the User is't authorized, I did it in ViewDidLoad Method of my Another View Controller ( if not authorized -> presentModalViewController ). When I start to make it in ViewDidAppear method, I solved this problem. I Think that ViewDidLoad only initialize properties and after that the actual showing view algorithm begins! Thats why you must use viewDidAppear method to make modal transitions!
如果您使用的是
transitioningDelegate
(不是本问题示例中的情况),请将modalPresentationStyle
设置为.Custom< /代码>
。
斯威夫特
If you're using
transitioningDelegate
(not the case in this question's example), also setmodalPresentationStyle
to.Custom
.Swift
我因为拼写错误而遇到这个问题:
而不是
在超级中调用“WillAppear”而不是“DidAppear”
I had this problem because of a typo:
instead of
It was calling "WillAppear" in the super instead of "DidAppear"
我遇到了很多同样的问题。我
Intro *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"introVC"];
[self.tabBarControllerpresentModalViewController : vcanimated:YES];
我的故事板中有视图控制器,出于某种原因,仅使用
[[introvc alloc] init];
对我不起作用。I had lot of problem with the same issue. I solved this one by
Intro *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"introVC"];
[self.tabBarController presentModalViewController : vc animated:YES];
I have the viewcontroller in my storyboard, for some reason using only
[[introvc alloc] init];
did not work for me.我通过写解决了
I solved it by writing
我在使用第三方代码时遇到了这个问题。有人忘记在自定义 TabBarController 类中设置 viewWillAppear 和 viewWillDisappear 的 super 内部。
I had this problem with a third party code. Someone forgot to set the super inside of viewWillAppear and viewWillDisappear in a custom TabBarController class.
我有同样的错误。我有一个包含 3 个项目的选项卡栏,并且我无意识地尝试使用
performSegueWithIdentifier
调用选项卡栏项目 2 中项目 1 的根视图控制器。发生的情况是,它调用视图控制器,并在几秒钟后返回到项目 2 的根视图控制器并记录该错误。
显然,您无法将一个项目的根视图控制器调用到另一个项目。
而不是
performSegueWithIdentifier
因此,我使用了
[self.parentViewController.tabBarController setSelectedIndex:0];
希望这对某人有帮助。
I had the same error. I have a tab bar with 3 items and I was unconsciously trying to call the root view controller of item 1 in the item 2 of my tab bar using
performSegueWithIdentifier
.What happens is that it calls the view controller and goes back to the root view controller of item 2 after a few seconds and logs that error.
Apparently, you cannot call the root view controller of an item to another item.
So instead of
performSegueWithIdentifier
I used
[self.parentViewController.tabBarController setSelectedIndex:0];
Hope this helps someone.
我遇到了同样的问题,并认为我会发布以防其他人遇到类似的问题。
就我而言,我在 UITableViewController 上附加了一个长按手势识别器。
在我的 onLongPress 选择器中,我启动了下一个视图控制器。
就我而言,我收到了错误消息,因为长按识别器多次触发,因此,我的“SomeViewController”被多次推入堆栈。
解决方案是添加一个布尔值来指示 SomeViewController 何时被推入堆栈。当我的 UITableViewController 的 viewWillAppear 方法被调用时,我将布尔值设置回 NO。
I had the same problem and thought I would post in case someone else runs into something similar.
In my case, I had attached a long press gesture recognizer to my UITableViewController.
In my onLongPress selector, I launched my next view controller.
In my case, I received the error message because the long press recognizer fired more than one time and as a result, my "SomeViewController" was pushed onto the stack multiple times.
The solution was to add a boolean to indicate when the SomeViewController had been pushed onto the stack. When my UITableViewController's viewWillAppear method was called, I set the boolean back to NO.
我发现,如果您使用故事板,您将需要将呈现新视图控制器的代码放在 viewDidAppear 中。它还将消除“不鼓励在分离视图控制器上呈现视图控制器”警告。
I found that, if you are using a storyboard, you will want to put the code that is presenting the new view controller in viewDidAppear. It will also get rid of the "Presenting view controllers on detached view controllers is discouraged" warning.
在 Swift 2+ 对我来说有效:
我在故事板中有 UITabBarViewController 并且我有这样的 selectedIndex 属性:
但我删除了它,并添加到我的 viewDidLoad 方法中我的第一堂课是这样的:
我希望我能帮助别人。
In Swift 2+ for me works:
I have UITabBarViewController in storyboard and I had selectedIndex property like this:
But I delete it, and add in my viewDidLoad method of my initial class, like this:
I hope I can help someone.
实际上你需要等到推送动画结束。因此,您可以委托 UINavigationController 并防止推送直到动画结束。
Actually you need to wait till the push animation ends. So you can delegate UINavigationController and prevent pushing till the animation ends.
正如 @danh 所建议的,我的问题是我在 UITabBarController 准备好之前就呈现了模态 vc。然而,在呈现视图控制器之前,我对依赖固定延迟感到不舒服(根据我的测试,我需要在
performSelector:withDelay:
中使用 0.05-0.1 秒的延迟)。我的解决方案是添加一个在UITabBarController
的viewDidAppear:
方法上调用的块:PRTabBarController.h:
PRTabBarController.m:
Now in
application:didFinishLaunchingWithOptions:< /代码>
As @danh suggested, my issue was that I was presenting the modal vc before the
UITabBarController
was ready. However, I felt uncomfortable relying on a fixed delay before presenting the view controller (from my testing, I needed to use a 0.05-0.1s delay inperformSelector:withDelay:
). My solution is to add a block that gets called onUITabBarController
'sviewDidAppear:
method:PRTabBarController.h:
PRTabBarController.m:
Now in
application:didFinishLaunchingWithOptions:
您需要确保 -(void)beginAppearanceTransition:(BOOL)isAppearinganimated:(BOOL)animated 和 -(void)endAppearanceTransition 在类中一起创建。
you need make sure -(void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated and -(void)endAppearanceTransition is create together in the class.
我有同样的问题。开发时我想绕过屏幕。我通过调用选择器方法在 viewDidLoad 中从一个视图控制器导航到另一个视图控制器。
问题是我们应该让 ViewController 在转换到另一个 ViewController 之前完成转换。
I had the same issue. When developing I wanted to bypass screens. I was navigating from one view controller to another in viewDidLoad by calling a selector method.
The issue is that we should let the ViewController finish transitioning before transitioning to another ViewController.