我有一个不是全屏的视图控制器(有一个状态栏),并且想要一个全屏的模态视图控制器。
如果我隐藏动画开头的状态栏(父视图的viewWillDisappear或模态的viewWillAppear),那么在没有状态栏的情况下,父视图将会显示,看起来像一个错误。
如果我在动画结束时(父视图的viewDidDisappear或模态的viewDidAppear)执行此操作,则状态栏将在模态视图上显示片刻,即它不会显示为模态视图“覆盖它”。
有没有办法很好地做到这一点?
一种可能性是至少在动画持续时间内使用windowLevel = alert创建UIWindow。如果没有其他窗口,示例iAd广告似乎很好地覆盖状态栏,因此必须以某种方式实现。
答案 0 :(得分:4)
另一个有趣的小项目。这是我能想到的最好的。如果您不介意使用自己的容器控制器来管理呈现/解除视图控制器,那也不算太糟糕。我尝试以一般方式做事情,但如果需要,可以将其转换为带有ContainerViewController的应用程序。
请注意,我只实现了UIModalTransitionStyleCoverVertical
的等效内容。您也可以自定义动画。
相关动画代码:
- (void)presentViewController:(UIViewController *)viewControllerToPresent
{
// do nothing if no controller
if (!viewControllerToPresent) return;
[__viewControllers addObject:viewControllerToPresent];
CGRect toFrame = viewControllerToPresent.view.frame;
toFrame.origin = CGPointMake(0, CGRectGetMaxY(self.view.bounds));
viewControllerToPresent.view.frame = toFrame;
[UIView transitionWithView:self.view
duration:0.2
options:UIViewAnimationOptionTransitionNone
animations:^{
[[UIApplication sharedApplication] setStatusBarHidden:viewControllerToPresent.wantsFullScreenLayout withAnimation:UIStatusBarAnimationSlide];
[self.view addSubview:viewControllerToPresent.view];
viewControllerToPresent.view.frame = [UIScreen mainScreen].applicationFrame;
}
completion:nil];
}
- (void)dismissViewController
{
// nothing to dismiss if showing first controller
if (__viewControllers.count <= 1) return;
UIViewController *currentViewController = [__viewControllers lastObject];
UIViewController *previousViewController = [__viewControllers objectAtIndex:__viewControllers.count - 2];
[UIView transitionWithView:self.view
duration:0.2
options:UIViewAnimationOptionTransitionNone
animations:^{
[[UIApplication sharedApplication] setStatusBarHidden:previousViewController.wantsFullScreenLayout withAnimation:UIStatusBarAnimationSlide];
CGRect toFrame = currentViewController.view.frame;
toFrame.origin = CGPointMake(0, CGRectGetMaxY(self.view.bounds));
currentViewController.view.frame = toFrame;
}
completion:^(BOOL finished) {
[currentViewController.view removeFromSuperview];
[__viewControllers removeLastObject];
}];
}
答案 1 :(得分:0)
我在我的应用程序中使用此代码执行此操作:
[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation: UIStatusBarAnimationSlide ];
DocumentListViewController * dl = [[DocumentListViewController alloc] initWithNibName:@"DocumentListView" bundle:nil] ;
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:dl];
[dl release];
// Go to the list of documents...
[[self.view superview] addSubview:nav.view];
nav.view.alpha = 0.0 ;
[self hideActivityAlert];
[UIView animateWithDuration:1.0 animations:^{
nav.view.alpha = 1.0; } completion:^(BOOL A){
[self.view removeFromSuperview];
[self release];} ];
动画发生时,状态栏会轻微显示。
当状态栏被隐藏时,您必须确保第一个视图将填充空间。使用具有适当值的属性autoresizingMask。
答案 2 :(得分:0)
这是一个似乎有效的解决方案。您可以从我的TSFullScreenModalViewController派生您想要以模态方式呈现的viewcontroller,或者您可以直接在视图控制器本身中实现代码。
@interface TSFullScreenModalViewController : UIViewController
{
UIWindow* _window;
}
- (void) presentFullScreenModal;
@end
@implementation TSFullScreenModalViewController
- (void) viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear: YES];
[_window resignKeyWindow];
[_window release];
_window = nil;
}
- (void) presentFullScreenModal
{
UIViewController* rvc = [[UIViewController new] autorelease];
rvc.view.backgroundColor = [UIColor clearColor];
_window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds] ;
_window.windowLevel = UIWindowLevelStatusBar+1;
_window.backgroundColor = [UIColor clearColor];
_window.rootViewController = rvc;
[_window makeKeyAndVisible];
[UIApplication sharedApplication].statusBarHidden = YES;
[rvc presentModalViewController: self animated: YES];
[UIApplication sharedApplication].statusBarHidden = NO;
}
@end
导出模态视图控制器,如下所示:
@interface MyModalViewController : TSFullScreenModalViewController
{
}
- (IBAction) onDismiss:(id)sender;
@end
从另一个视图控制器中使用它,如下所示:
- (IBAction) onShowModal:(id)sender
{
MyModalViewController* mmvc = [[MyModalViewController new] autorelease];
[mmvc presentFullScreenModal];
}
最后,像往常一样关闭视图控制器:
- (IBAction) onDismiss:(id)sender
{
[self dismissModalViewControllerAnimated: YES];
}
答案 3 :(得分:0)
可能就像使用performSelector延迟modalViewController的表示一样简单:withDelay:
告诉状态栏动画显示然后以正确的延迟启动模态控制器,使其与状态栏动画一致。