我想使用幻灯片效果同时显示和隐藏statusBar和navigationBar。
这是我尝试的方式:
[[UIApplication sharedApplication] setStatusBarHidden:hide withAnimation:UIStatusBarAnimationSlide];
[self.navigationController setNavigationBarHidden:hide animated:animated];
然而,两个动画的持续时间并不相同。状态栏动画需要更长时间。 我发现无法如何指定任何一个动画的持续时间。 我错过了一些明显的东西吗?
答案 0 :(得分:5)
ios-lizard的答案几乎是我想要的,但是在旋转设备时导航栏会重新出现,除非hidden
设置正确。所以这对我有用:
Hidding动画作品/看起来不错YEAH !!。
显示动画没问题,(我希望我可以使用导航栏滑动状态栏,但至少我们不会看到间隙。:D
)
- (void)toggleFullscreen {
UINavigationBar *navBar = self.navigationController.navigationBar;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
float animationDuration;
if(statusBarFrame.size.height > 20) { // in-call
animationDuration = 0.5;
} else { // normal status bar
animationDuration = 0.6;
}
_fullscreen = !_fullscreen;
if (_fullscreen) {
// Change to fullscreen mode
// Hide status bar and navigation bar
[[UIApplication sharedApplication] setStatusBarHidden:YES
withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:animationDuration animations:^{
navBar.frame = CGRectMake(navBar.frame.origin.x,
-navBar.frame.size.height,
navBar.frame.size.width,
navBar.frame.size.height);
} completion:^(BOOL finished) {
[self.navigationController setNavigationBarHidden:YES animated:NO];
}];
} else {
// Change to regular mode
// Show status bar and navigation bar
[[UIApplication sharedApplication] setStatusBarHidden:NO
withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:animationDuration animations:^{
navBar.frame = CGRectMake(navBar.frame.origin.x,
statusBarFrame.size.height,
navBar.frame.size.width,
navBar.frame.size.height);
} completion:^(BOOL finished) {
[self.navigationController setNavigationBarHidden:NO animated:NO];
}];
}
}
答案 1 :(得分:2)
这就是我为我的应用修复此问题的方法。
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
// delta is the amount by which the nav bar will be moved
delta = statusBarFrame.size.height + self.navigationController.navigationBar.frame.size.height;
if(statusBarFrame.size.height>20) { // in-call
animationDuration = 0.5;
}
else { // normal status bar
animationDuration = 0.6;
}
// hide status bar
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
// hide nav bar
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:animationDuration];
self.navigationController.navigationBar.frame = CGRectOffset(self.navigationController.navigationBar.frame, 0.0, -delta);
[UIView commitAnimations];
答案 2 :(得分:1)
显然,没有简单的解决方案可以做到这一点。 Apple必须fix it。
当然,正如以法莲所暗示的那样,一种解决方法就是使用阿尔法褪色。如果你坚持滑动行为,我发现最好只为导航栏设置动画并隐藏/显示statusBar而不需要任何动画。这看起来比滑动状态栏要好得多,因为动画期间条形之间的间隙非常明显。
答案 3 :(得分:1)
这是一个更简洁的方法,它将系统常量用于动画持续时间,并且还处理来电。
请注意,navigationBar是一个插座,statusBarHeight是一个实例变量float。
- (IBAction)toggleControls:(id)sender {
BOOL isHidden = ! [UIApplication sharedApplication].statusBarHidden;
if (isHidden)
statusBarHeight = [UIApplication sharedApplication].statusBarFrame.size.height;
[UIView animateWithDuration:[UIApplication sharedApplication].statusBarOrientationAnimationDuration animations:^{
self.navigationBar.frame = CGRectMake(self.navigationBar.frame.origin.x,
isHidden ? -self.navigationBar.frame.size.height : statusBarHeight,
self.navigationBar.frame.size.width,
self.navigationBar.frame.size.height);
}];
[[UIApplication sharedApplication] setStatusBarHidden:isHidden withAnimation:UIStatusBarAnimationSlide];
}
答案 4 :(得分:1)
nacho4d的回答几乎就是我想要的。但是,他在navBar可见之前改变了navBar的框架。所以我们看不到转换动画。它看起来像navBar突然出现。更重要的是,在显示时,statusBarFrame.size.height等于0.这是他的代码:
[[UIApplication sharedApplication] setStatusBarHidden:NO
withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:animationDuration animations:^{
navBar.frame = CGRectMake(navBar.frame.origin.x,
statusBarFrame.size.height,
navBar.frame.size.width,
navBar.frame.size.height);
} completion:^(BOOL finished) {
[self.navigationController setNavigationBarHidden:NO animated:NO];
}];
在显示时,我们希望我们可以使用导航栏使状态栏滑动。 这是我的回答:
UINavigationBar *navBar = self.navigationController.navigationBar;
[[UIApplication sharedApplication] setStatusBarHidden:hidden withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:0.35 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
// make navigationBar visual
if (!hidden)
{
[self.navigationController setNavigationBarHidden:hidden animated:NO];
}
navBar.frame = CGRectMake(navBar.frame.origin.x,
hidden ? -navBar.frame.size.height : 20,
navBar.frame.size.width,
navBar.frame.size.height);
} completion:^(BOOL finished) {
if (hidden)
{
[self.navigationController setNavigationBarHidden:hidden animated:NO];
}
}];
答案 5 :(得分:0)
这不是一个答案,但它有效。所以我做的是:
// This method gets called by whatever action you want
- (void) toggleShowStatusNavBars:(id)sender {
// Assuming you have a ivar called barsHidden
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4]; // This is IMPORTANT, 0.4s
self.navigationController.navigationBar.alpha = (barsHidden?1.0:0.0);
barsHidden = !barsHidden;
[UIView setAnimationDelegate:self];
[UIView setAnimationWillStartSelector:@selector(setStatusBarHidden)];
[UIView commitAnimations];
}
- (void) setStatusBarHidden {
[[UIApplication sharedApplication] setStatusBarHidden:barsHidden animated:YES];
}
这基本上会同步动画的开始(因为你在导航栏动画开始时调用setStatusBarHidden
。关键部分是状态栏动画似乎需要0.4秒。
这适合我,但如果你找到更好的方法,请在这里发帖。
答案 6 :(得分:0)
您可以使用实例变量来执行此操作:
self.navigationController setNavigationBarHidden:hide animated:animated];
_shouldHideStatusBar = hide;
并实现以下功能:
- (BOOL)prefersStatusBarHidden{
return _shouldHideStatusBar;
}
setNavigationBarHidden:animated 函数会自动调用 prefersStatusBarHidden 函数。如果它没有,您可以使用以下UIViewController方法调用它:
[self setNeedsStatusBarAppearanceUpdate];
当然,您可以选择状态栏隐藏动画样式:
- (UIStatusBarAnimation) preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationSlide;
}