我试图使用iOS 8中添加的新功能 - 在用户滚动表格视图时隐藏导航栏(类似于移动Safari的功能)。我在[{1}}的{{1}}方法中将hidesBarsOnSwipe
的属性UINavigationController
设置为YES
:
viewDidAppear
滚动视图时,导航栏会隐藏。到现在为止还挺好。但状态栏仍然可见,我的表格视图内容通过它显示,看起来很难看:
我尝试将UITableViewController
设置为- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if([self.navigationController respondsToSelector:@selector(hidesBarsOnSwipe)]) {
self.navigationController.hidesBarsOnSwipe = YES;
}
}
或调整表格视图的edgesForExtendedLayout
,但它没有帮助。是否有其他解决方案可以隐藏状态栏和导航栏,或者使其不透明?
答案 0 :(得分:39)
实际上这很容易做到。您只需要将导航isNavigationBarHidden属性与状态栏连接起来。
<强>目标C 强>
- (BOOL)prefersStatusBarHidden {
return self.navigationController.isNavigationBarHidden;
}
Swift&lt; = 2.3
override func prefersStatusBarHidden() -> Bool {
return navigationController?.navigationBarHidden ?? false
}
Swift 3.0
override var prefersStatusBarHidden: Bool {
return navigationController?.isNavigationBarHidden ?? false
}
并确保您的应用程序.plist文件中有“查看基于控制器的状态栏外观”=“YES”。
答案 1 :(得分:30)
建立anas的答案,我有一个有效的解决方案(我假设tableViewController
是你的UITableViewController
个实例):
在UINavigationController
子类中(或者也可能来自tableViewController
):
- (void)viewDidLoad {
if ([self respondsToSelector:@selector(barHideOnSwipeGestureRecognizer)]) {
// iOS 8+
self.hidesBarsOnSwipe = YES;
[self.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipe:)];
}
}
- (void)swipe:(UISwipeGestureRecognizer *)recognizer {
BOOL shouldHideStatusBar = self.navigationController.navigationBar.frame.origin.y < 0;
tableViewController.hideStatusBar = shouldHideStatusBar;
[UIView animateWithDuration:0.2 animations:^{
[tableViewController setNeedsStatusBarAppearanceUpdate];
}];
}
在tableViewController
:
@property(nonatomic, getter = shouldHideStatusBar) BOOL hideStatusBar;
- (BOOL)prefersStatusBarHidden {
return [self shouldHideStatusBar];
}
如果这不适合你,请告诉我。一些不明显的事情:
self.navigationController.navigationBar.frame.origin.y
为-44(导航栏的负高度),可见时为20(状态栏的高度)。即使在动画期间也没有中间,所以负值==隐藏和非负值==可见。UIViewController
内的UINavigationController
内有一个UITabBarController
,直到我在prefersStatusBarHidden
上覆盖UIViewController
后才能生效。< / LI>
setNeedsStatusBarAppearanceUpdate
包裹起来,否则您的内容可能会超过20分。答案 2 :(得分:8)
该新属性附带barHideOnSwipeGestureRecognizer
。
来自UINavigationController Class Reference:
您可以根据需要更改手势识别器,但不能 更改其委托,您不能删除默认目标对象 以及配置它的动作。不要试图替换它 通过覆盖财产来识别手势。
但您可以添加目标:
[self.navigationController setHidesBarsOnSwipe:YES];
[self.navigationController.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipeGesture:)];
...并在回调中做任何你想做的事情:
- (void)swipeGesture:(UIPanGestureRecognizer*)gesture
{
// Tweak the status bar
}
您可能需要手动打开手势状态,找出何时隐藏/显示状态栏等。希望有所帮助!
答案 3 :(得分:3)
@iOSergey的答案非常完美!
以下是 Swift 1.2中的解决方案。将以下代码添加到视图.swift文件:
override func prefersStatusBarHidden() -> Bool {
return self.navigationController!.navigationBarHidden as Bool
}
答案 4 :(得分:3)
如果要使用动画隐藏状态栏:
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return .Slide
}
override func prefersStatusBarHidden() -> Bool {
return navigationController?.navigationBarHidden ?? false
}
答案 5 :(得分:2)
经过多次努力,我终于能够解决这个问题。
将以下代码添加到UIViewController的viewDidLoad函数中:
//为状态栏创建纯色背景(在Swift代码中)
让statusFrame = CGRectMake(0.0,0,self.view.bounds.size.width,
UIApplication.sharedApplication()。statusBarFrame.size.height)var statusBar = UIView(frame:statusFrame)
statusBar.backgroundColor = UIColor.whiteColor()
self.view.addSubview(状态栏。)
您正在做的是在导航栏下方创建一个实心栏。当导航栏向上移动时,实心条也向上移动并且在状态栏后面。
唯一的问题是,当您向侧面旋转屏幕时,即使状态栏消失,白色条仍然存在。
答案 6 :(得分:1)
好吧,我花了一整天的时间来做这件事,希望这可以帮助一些人。有一个barHideOnSwipeGestureRecognizer
。所以你可以为相应的UIPanGesture
创建一个监听器,注意如果导航栏被隐藏,那么它的y原点是-44.0;否则,它是0(不是20,因为我们隐藏了状态栏!)。
在你的视图控制器(swift 2)中:
// Declare at beginning
var curFramePosition: Double!
var showStatusBar: Bool = true
self.navigationController?.barHideOnSwipeGestureRecognizer.addTarget(self, action: "didSwipe:")
...
override func viewDidLoad(){
self.navigationController?.hidesBarsOnSwipe = true
curFramePosition = 0.0 // Not hidden
self.navigationController?.barHideOnSwipeGestureRecognizer.addTarget(self, action: "didSwipe:")
...
}
func didSwipe(swipe: UIPanGestureRecognizer){
// Visible to hidden
if curFramePosition == 0 && self.navigationController?.navigationBar.frame.origin.y == -44 {
curFramePosition = -44
showStatusBar = false
prefersStatusBarHidden()
setNeedsStatusBarAppearanceUpdate()
}
// Hidden to visible
else if curFramePosition == -44 && self.navigationController?.navigationBar.frame.origin.y == 0 {
curFramePosition = 0
showStatusBar = true
prefersStatusBarHidden()
setNeedsStatusBarAppearanceUpdate()
}
}
override func prefersStatusBarHidden() -> Bool {
if showStatusBar{
return false
}
return true
}
答案 7 :(得分:0)
另一种方法是添加另一个视图(在tableview或collectionview或webview或scrollview之上或其他任何视图上方)并将视图的顶部约束设置为&#34; Superview.Top&#34;及其底部约束&#34;顶部布局指南.Bottom&#34; ,设置视图的背景颜色 就是这样,你甚至可以在没有任何代码的Interface Builder中完成所有操作。 如果你想响应那个事件,你可以在视图的边界变化中添加一个keypath观察者,或者对视图进行子类化并覆盖它的边界setter ......
答案 8 :(得分:0)
您需要将导航isNavigationBarHidden属性与状态栏连接起来。
return self.navigationController.isNavigationBarHidden;