在 viewWillDisappear 期间隐藏 UINavigationController 的 UIToolbar:
我有一个带有 UITableView
菜单的 iPhone 应用程序。当选择表中的一行时,相应的视图控制器就会被推送到应用程序的 UINavigationController 堆栈上。
我的问题是 MenuViewController
不需要工具栏,但推入堆栈的 UIViewControllers
需要。每个被推送的 UIViewController
都会调用 viewDidAppear:
中的 setToolbarHidden:animated:
。为了隐藏工具栏,我在 viewWillDisappear:
中调用 setToolbarHidden:animated:
。
显示工具栏有效,这样当推送的视图出现时,工具栏会向上滑动并且视图可以正确调整大小。但是,当按下后退按钮时,工具栏会向下滑动,但视图不会调整大小。这意味着当其他视图过渡时,视图底部有一条黑色条带。我尝试在隐藏工具栏之前将工具栏的高度添加到视图的高度,但这会导致视图在过渡,以便仍然有一个黑条。
我意识到我可以管理自己的 UIToolbar,但为了方便起见,我想使用 UIToolbar 中内置的 UINavigationControllers
。
这个论坛帖子提到了同样的问题,但没有提到解决方法。
I've got an iPhone application with a UITableView
menu. When a row in the table is selected, the appropriate view controller is pushed onto the application's UINavigationController
stack.
My issue is that the MenuViewController
does not need a toolbar, but the UIViewControllers
which are pushed onto the stack do. Each UIViewController
that gets pushed calls setToolbarHidden:animated:
in viewDidAppear:
. To hide the toolbar, I call setToolbarHidden:animated:
in viewWillDisappear:
.
Showing the toolbar works, such that when the pushed view appears the toolbar slides up and the view resizes correctly. However, when the back button is pressed the toolbar slides down but the view does not resize. This means that there's a black strip along the bottom of the view as the other view transitions in. I've tried adding the toolbar's height to the height of the view prior to hiding the toolbar, but this causes the view to be animated during the transition so that there's still a black bar.
I realise I can manage my own UIToolbar, but I'd like to use UINavigationControllers
built in UIToolbar for convenience.
This forum post mentions the same issue, but no workaround is mentioned.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
我也经历过这个问题。就我而言,我发现成功隐藏工具栏而不显示窗口背景的唯一方法是在视图控制器的
- 中调用
方法。[self.navigationController setToolbarHidden:YESAnimated:animated]
viewDidAppear:I too have experienced this problem. In my case, the only way I found to successfully hide the toolbar without showing the background of the window is to call
[self.navigationController setToolbarHidden:YES animated:animated]
in your view controller’s-viewDidAppear:
method.我对这个问题的答案不满意,所以我发布了自己的答案: 同时引用源视图控制器和目标视图控制器
我得到的答案解决了我的问题。它也可能对你有用(虽然这个问题很老了,但我想这可能会帮助像我这样阅读这篇文章六次寻找提示的人)。
这就是我所做的。我不知道标记协议是否是惯用的 Objective-C,但我将它们比作我在 C# 中使用的属性,所以我有这个标记协议:
我将 UINavigationControllerDelegate 添加到我的 AppDelegate 中。我还不确定这是否是一件好事。我考虑过将该实现保留在另一个对象中,但现在,这就是我放置它的地方。这是实现:
这样,我可以在 UIViewController 实现上设置标记协议,如下所示:
如果我没有该接口,它将把它放回去。
最后,在我的 appDelegate 的 application:didFinishLaunchingWithOptions: 方法中,我像这样连接委托:
现在我没有得到黑匣子,也没有柴郡猫。我的解决方案当然是关于导航栏的,但我确信它对于工具栏来说也是一样的。这与 Danra 的答案非常相似,只是我得到的黑匣子没有“动画:动画”。
I wasn't satisfied with the answers on this question so I posted my own: Reference to source view controller and destination view controller at the same time
The answer I got fixed my problem. It may work for yours too (though this question is pretty old, I figured this might help someone like me who read this post a half dozen times looking for a hint).
Here's what I did. I don't know if marker protocols are idiomatic objective-c or not, but I liken them to attributes like I'd use in c# so I have this marker protocol:
I added UINavigationControllerDelegate to my AppDelegate. I'm not sure yet whether or not that's a good thing. I thought about keeping that implementation in another object, but for now, this is where I put it. Here's the implementation:
This way, I can just set my marker protocol on my UIViewController implementation like so:
If I don't have that interface, it puts it back.
Finally, in my appDelegate's application:didFinishLaunchingWithOptions: method, I wire up the delegate like this:
Now I get no black boxes and no Cheshire Cat. My solution was with regard to the navigation bar of course, but I'm sure it works the same for the toolbar. This is very similar to Danra's answer except that I get the black box without the "animated:animated."
对于推送时不需要工具栏的 UIViewController,您可以考虑使用
为该 UIViewController 实现 hidesBottomBarWhenPushed 方法:
或者在推送 UIViewController 之前,设置 hidesBottomBarWhenPushed 的值:
For the UIViewController that does not need a toolbar when pushed you can consider using either
Implementing the hidesBottomBarWhenPushed method for that UIViewController:
Or prior to pushing in the UIViewController, set the value of hidesBottomBarWhenPushed:
尝试实现 UINavigationControllerDelegate 并将其设置为导航控制器的委托属性。
这对我来说实现了您在帖子中描述的内容,没有可见的伪影。
以下代码假设通过在firstController 中执行的操作将secondController 推入导航视图。
sharedDelegate 只是一个辅助方法:
Try implementing a UINavigationControllerDelegate and setting it to your navigation controller's delegate property.
This achieved for me what you are describing in your post, with no visible artifacts.
The following code assumes that secondController is pushed into the navigation view by an action performed in the firstController.
sharedDelegate is just a helper method:
要在新视图控制器中显示工具栏,只需添加以下内容:
要隐藏工具栏:
在屏幕之间移动时,使用以下代码推送新视图控制器:
如果它具有不同的工具栏状态(隐藏/显示),则隐藏/显示工具栏的漂亮动画将是显示。
To show toolbar in new view controller just add this:
To hide toolbar:
When traveling between screens push new view controller with following code:
and if it has different state of toolbar (hidden/shown) then nice animation of hiding/showing toolbar will be shown.
这里的问题是
UITableView
的框架被设置为不与UIToolbar
重叠。也就是说,它位于 UIToolbar 的正上方。当您将下一个UIViewController
推送到UINavigationController
堆栈时,同时删除UIToolbar
,除了UIWindow
之外,没有任何内容可显示。 code> 在它后面,除非你在它的位置放了一些东西。转换后没有尴尬动画的一种解决方法是将您的
UITableView
放置在UIView
“容器”中,该容器与您的常规视图共享相同的框架,但位于 UIToolbar 下方 以及您希望在过渡期间看到的所需颜色(例如白色)。要实现下重叠,您可以将
UIViewController
设置为wantsFullScreenLayout = YES
。然后,您将确保您的 UITableView 具有与使用容器之前相同的框架。即它位于导航栏下方、工具栏上方。通过编写自定义
UIViewController
并使用它来代替UITableViewController
,或者偷偷摸摸地插入新的UIView
,可以使这变得更加优雅”容器”位于现有UITableViewController
中的UITableView
下方。The issue here is that the
UITableView
's frame is set so that it does not overlap with theUIToolbar
. That is, it sits just above theUIToolbar
. When you push the nextUIViewController
to theUINavigationController
stack, while removing theUIToolbar
, there is nothing to show but theUIWindow
behind it, unless you put something there in its place.One workaround without the awkward animation after transition is to place your
UITableView
in aUIView
"container" that shares the same frame as your regular view, but underlaps theUIToolbar
with the desired colour that you wish to see during the transition (e.g. white).To enact the underlap, you could set your
UIViewController
towantsFullScreenLayout = YES
. You would then ensure that yourUITableView
has the same frame as it would have before the use of the container. i.e. it sits below the navigation bar, and above the toolbar.This can be made more elegant by writing a custom
UIViewController
and use that instead of theUITableViewController
, or by being sneaky and inserting the newUIView
"container" beneath theUITableView
in your existingUITableViewController
.我使用自定义背景图像作为工具栏背景,使用自定义图像作为表格背景。当视图从另一个表格视图来回转换时,我对底部的黑条遇到了同样的问题。不过我
在viewDidLoad中设置了。
这会将背景图像设置为背景的全部潜在大小,如果您有透明的工具栏,则这是有意义的。当您使用标准的不透明工具栏时,这可能不是一个好的解决方法,但对于那些自定义工具栏的人来说,您可以两全其美。
I use a custom background image for the toolbar background, and a custom image for the table background. I was having the same issue with the black bar at the bottom as the view transitioned back and forth from another table view. However I set the
in viewDidLoad.
This sets the background image to the full potential size of the background, which if you had a transparent toolbar would make sense. It's probably not a good workaround when you're using the standard opaque toolbar, but for those of you customizing the toolbar anyway, you can get the best of both worlds.
我同意杰夫的回答。但是,如果我在 viewController 的 -viewDidAppear 方法中隐藏工具栏(通过该方法推送不同的 viewController),则会出现 UI 故障。
为了避免这种情况,我进行了实验,发现在 -viewWillAppear 调用中调用 -setToolbarHidden 确实隐藏了工具栏,但正如问题所述,虽然展开的视图不会被表视图行占用。
为了解决这个问题,我已更改为以下代码,现在它可以正常工作了:
I am in agreement with Jeff's answer. But there is a UI glitch if I hide the toolbar in -viewDidAppear method of the viewController through which different viewControllers are pushed.
To avoid this, I was experimenting and found out that calling -setToolbarHidden in the -viewWillAppear call indeed hides the toolbar, but as the question states, the view though expanded would not be occupied by the tableview rows.
To fix this, I have changed to following code and now it works without the glitch:
管理工具栏状态(即哪个 VC 需要/不需要工具栏)很快就会变得棘手。
我已经成功地遵循了这条规则:
对于每个视图控制器,在
viewWillAppear()
中,决定它是否需要工具栏,然后调用navigationController?.setToolbarHidden (true 或 false,animated:animated)
分别。这样,每个视图控制器都会以正确的工具栏状态开始,并且您不必担心在视图时“恢复”工具栏状态。控制员被解雇。
Managing the toolbar state (i.e. which VC needs/doesn't need the toolbar) gets tricky quickly.
I've had success with following this rule:
For each view controller, in
viewWillAppear()
, decide if it needs a toolbar or doesn't, then callnavigationController?.setToolbarHidden(true or false, animated: animated)
respectively.This way, each view controller starts out with the correct toolbar state and you don't have to worry about "restoring" the toolbar state when the view controller is dismissed.
这只是在黑暗中进行的一次疯狂尝试,但也许您应该在隐藏工具栏后让运行循环运行一次:
This is just a wild stab in the dark but maybe you should let the runloop run once after hiding the toolbar:
我遇到了同样的问题,这是对我有用的解决方案。假设您要将
SomeUIViewController
推送到导航堆栈上。在
SomeUIViewController
的接口中定义这个(私有)ivar:实现
SomeUIViewController
的以下方法:这个想法是你想要隐藏导航控制器拥有的工具栏after
SomeUIViewController
的视图消失了。这样,您就可以避免任何不需要的显示伪影。免责声明
这只是一个答案,显示了所述问题的变通解决方案。它只是为了指出框架内部运作的细节。它还可以作为不向 Apple AppStore 提交的示例。
I had the same problem and here is the solution that worked for me. Say you're pushing
SomeUIViewController
onto your navigation stack.Define this (private) ivar in the interface of
SomeUIViewController
:Implement the following methods of
SomeUIViewController
:The idea is that you want to hide the toolbar owned by the navigation controller after
SomeUIViewController
's view has disappeared. This way, you avoid any unwanted display artifacts.DISCLAIMER
This is merely an answer that shows a workaround solution for the stated question. It is meant solely to point out a detail of the inner workings of the framework. It is also meant as an example of what not to submit to the Apple AppStore.