Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/110.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在非全屏和全屏UIViewController之间进行出色的幻灯片切换_Ios_Uiviewcontroller - Fatal编程技术网

Ios 在非全屏和全屏UIViewController之间进行出色的幻灯片切换

Ios 在非全屏和全屏UIViewController之间进行出色的幻灯片切换,ios,uiviewcontroller,Ios,Uiviewcontroller,我有一个不是全屏的视图控制器(有一个状态栏),我想展示一个全屏的模态视图控制器 如果我在动画开始时隐藏状态栏(父视图将消失或模态视图将出现),那么在一段时间内,父视图将在没有状态栏的情况下可见,看起来像一个bug 如果我在动画结束时执行此操作(父视图的ViewDidEnglishe或模态视图的ViewDidDisplay),则状态栏将在模态视图上显示一段时间,即它不会显示为模态视图“covered it” 有什么方法可以很好地做到这一点吗 编辑: 一种可能是创建一个windowLevel=ale

我有一个不是全屏的视图控制器(有一个状态栏),我想展示一个全屏的模态视图控制器

如果我在动画开始时隐藏状态栏(父视图将消失或模态视图将出现),那么在一段时间内,父视图将在没有状态栏的情况下可见,看起来像一个bug

如果我在动画结束时执行此操作(父视图的ViewDidEnglishe或模态视图的ViewDidDisplay),则状态栏将在模态视图上显示一段时间,即它不会显示为模态视图“covered it”

有什么方法可以很好地做到这一点吗

编辑:
一种可能是创建一个windowLevel=alert的UIWindow,至少在动画持续时间内。示例iAd广告似乎很好地覆盖了状态栏,没有另一个窗口,因此它一定是可能的。

我在我的应用程序中使用以下代码:

[[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。

这里有一个似乎有效的解决方案。您可以从我的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];
}
从另一个视图控制器使用它,如下所示:

@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];
}

可能有点麻烦,但您是否考虑过:

  • 使用状态栏以编程方式拍摄第一个视图的屏幕截图(参见此)
  • 创建一个新视图,全屏显示您刚才拍摄的图像(使用
    UIImage
    initWithFrame
  • 隐藏状态栏
  • 显示模态视图控制器
  • 然后,要取消模式视图,只需颠倒步骤即可

    编辑


    不适用于此,因为您无法拍摄状态栏的屏幕截图。

    另一个有趣的小项目。这是我能想到的最好的了。如果您不介意使用自己的容器控制器来管理显示/取消显示视图控制器,这也不算太糟糕。我试着用一种通用的方式做一些事情,但如果需要的话,可以将其应用到带有ContainerViewController的应用程序中

    请注意,我只实现了相当于
    uimodaltransationstylecoververtical
    。您也可以根据自己的喜好自定义动画

    相关动画代码:

    - (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];
                        }];
    }
    
    -(无效)presentViewController:(UIViewController*)viewControllerToPresent
    {   
    //如果没有控制器,则不执行任何操作
    如果(!viewControllerToPresent)返回;
    [\uu viewcontrolleraddobject:viewControllerToPresent];
    CGRect toFrame=viewControllerToPresent.view.frame;
    toFrame.origin=CGPointMake(0,CGRectGetMaxY(self.view.bounds));
    viewControllerToPresent.view.frame=toFrame;
    [UIView转换WithView:self.view
    持续时间:0.2
    选项:UIViewAnimationOptionTransitionNone
    动画:^{
    [[UIApplication sharedApplication]setStatusBarHidden:viewControllerToPresent.wantFullScreenLayout with Animation:UIStatusBarAnimationSlide];
    [self.view addSubview:viewControllerToPresent.view];
    viewControllerToPresent.view.frame=[UIScreen Main Screen].applicationFrame;
    }
    完成:无];
    }
    -(无效)解雇ViewController
    {
    //如果显示第一个控制器,则无需关闭
    
    如果(_viewControllers.count,可以使用performSelector:withDelay:


    告诉状态栏设置动画,然后以正确的延迟启动模态控制器,使其与状态栏动画一致。

    Gabriel,但如果我理解正确,这是一个淡入淡出,而不是幻灯片动画。也许我应该更具体一些。好的,现在我明白你想要什么了。你希望模态视图与stan一起出现吗从底部添加动画并覆盖状态栏。但我认为这是不可能的,因为状态栏是用于应用程序的,而不是用于视图。因此,正如在我的代码中一样,您最多可以在同一动画中隐藏状态栏。然后,当模式视图出现时,状态栏隐藏动画。我已经在关于UIWindow方法的问题中写道,但我不想使用它,因为在状态栏或警报级别上有一个窗口还有很多其他问题。我已经检查过iAd不使用其他窗口。所以你的新要求是不要使用位于状态栏上方的窗口。在我花时间找出解决方案之前知道这一点会很好。汤姆,我已经补充了这一点在回答前2天。您无法对状态栏进行截图。UIGetScreenImage()过去是这样做的,但你不能再这样做了。状态栏是它自己的窗口,你无法获得它的引用,好吧。我认为你的UIWindow解决方案可能是正确的选择。当我们需要在视图控制器之间进行不寻常的转换时,我们在应用程序中使用类似的技术。