繁体   English   中英

如何解除一堆带动画的模态视图控制器而不在屏幕上闪烁顶部和底部之间的任何呈现的VC?

[英]How to dismiss a stack of modal view controllers with animation without flashing on screen any of the presented VCs between the top and bottom?

更新:通过下面的“屏幕截图”方法大纲修复。 这有效但有更优雅的方式吗?

我如何解除一堆带有动画的模态视图控制器而不在屏幕上闪烁顶部和底部之间的任何呈现的VC? 尝试使用动画执行此操作无效。 请参阅下面的代码和描述我的问题的内联注释。 您可以将此代码复制/粘贴到Xcode中的新项目中,以便亲自查看您是否愿意!

//
//  ViewController.m
//  MultipleModals
//

#import "ViewController.h"
#import "MyViewController.h"
#import "MyHelper.h"

@interface ViewController ()

@end

@implementation ViewController

static BOOL doAgain = YES; // So when red appears again, we don't endlessly cycle (for testing)
- (void)viewDidAppear:(BOOL)animated
{
    // Invoke super
    [super viewDidAppear:animated];

    // Prevent loop when we dismiss all the way back to red (for testing)
    if (doAgain)
    {
        // Okay here's where the demo code starts...

        // PRESENTING a full stack of modals WITHOUT animation WORKS and results in the user
        // only seeing orange when this red view controller "appears" (red never actually appears, which is great)...

        MyViewController *purple = [[MyViewController alloc] init];
        purple.title = @"purple"; // For use in MyViewController's dealloc method
        purple.view.backgroundColor = [UIColor purpleColor];
        [self presentViewController:purple animated:NO completion:^{ // Purple successfully gets presented and the user never sees purple, great.
            NSLog(@"Purple?");
            MyViewController *green = [[MyViewController alloc] init];
            green.view.backgroundColor = [UIColor greenColor];
            green.title = @"green"; // For use in MyViewController's dealloc method
            [purple presentViewController:green animated:NO completion:^{ // Green successfully gets presented and the user never sees green, great.
                NSLog(@"Green?");
                MyViewController *orange = [[MyViewController alloc] init];
                orange.view.backgroundColor = [UIColor orangeColor];
                orange.title = @"orange"; // For use in MyViewController's dealloc method
                [green presentViewController:orange animated:NO completion:^{ // Orange successfully gets presented and the user DOES see orange, great.
                    NSLog(@"Orange?");

                    // FIXED MY ISSUE STARTING HERE

                    // Comment out the following code to toggle between
                    // the "flashing purple issue" and "the desired outcome" (single
                    // animation from top to bottom regardless of how many VCs are
                    // on the stack, i.e. no flashing).

                    // Get orange screenshot
                    UIImage *orangeScreenShotImage = [MyHelper screenshot];
                    UIImageView *orangeScreenShotImageView = [[UIImageView alloc] initWithImage:orangeScreenShotImage];

                    // Give purple an orange screenshot since orange will just "flash away" and then purple will animate
                    // away but we'll disguise purple to appear as if it's orange by layering a screenshot of orange on purple. Boom.
                    [purple.view addSubview:orangeScreenShotImageView];

                    // FIXED MY ISSUE ENDING HERE

                    // FOR TESTING PURPOSES... dismiss after 5 seconds...
                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                        doAgain = NO; // Prevent viewDidAppear loop (related to my testing code)...

                        // THIS IS MY BUG HERE. WHEN I WANT TO **ANIMATE** THE DISMISSAL OF ORANGE ALL THE WAY BACK TO RED, HOWEVER, I SEE PURPLE FOR A FLASH BEFORE RED!! WHY?

                        // If I do not animate, things work as expected and I go from orange directly back to red in one flash. Why can't I go from orange back red WITH ANIMATION without seeing a flash of purple?
                        BOOL animateDismissalOfOrangeBackToRed = YES; // YES causes me to see a flash of purple before red, why?
                        [self dismissViewControllerAnimated:animateDismissalOfOrangeBackToRed completion:^{
                            NSLog(@"Back to red...");
                        }];
                    });
                }];
            }];
        }];
    }
}

- (void)viewDidLoad
{
    // Invoke super
    [super viewDidLoad];

    // Set self's background color
    self.view.backgroundColor = [UIColor redColor]; // Color of self, root VC
}

@end

MyViewController.m(使我们能够使用自定义dealloc方法进行调试)

//
//  MyViewController.m
//  MultipleModals
//

#import "MyViewController.h"

@interface MyViewController ()

@end

@implementation MyViewController

- (void)dealloc
{
    NSLog(@"Inside dealloc self.title = %@", self.title);
}

@end

更新:为dealloc调试添加了新的MyViewController.m文件。

有趣的是,日志看起来像这样:

2014-11-20 10:06:28.847 MultipleModals[5470:946774] Purple?
2014-11-20 10:06:28.851 MultipleModals[5470:946774] Green?
2014-11-20 10:06:28.853 MultipleModals[5470:946774] Orange?
2014-11-20 10:07:04.055 MultipleModals[5470:946774] Inside dealloc self.title = orange
2014-11-20 10:07:04.056 MultipleModals[5470:946774] Inside dealloc self.title = green
2014-11-20 10:07:04.565 MultipleModals[5470:946774] Back to red...
2014-11-20 10:07:04.566 MultipleModals[5470:946774] Inside dealloc self.title = purple

更新:我添加了一个示例项目,以便您可以非常轻松地观察第一个句柄: https//github.com/johnerck/MultipleModals

另外,我已经多次阅读过来自其他视图控制器的视图控制器 他们甚至说,“例如,如果用户取消当前操作,您可以通过关闭第一个呈现的视图控制器来删除链中的所有对象。解雇视图控制器不仅会解除视图控制器,还会解除它所呈现的任何视图控制器。 “ 我看到这种行为,但动画总共显示3个视图,而不是预期的2个。

这不是一个bug。 self.presentedViewController仅为self.presentedViewController (“purple”)更改删除动画,但不为所有嵌套的VC dismissViewControllerAnimated 当“purple”收到有关使用动画删除的消息时,它会删除所有presentedViewController而不显示动画。 然后你会看到没有嵌套控制器的“紫色”动画。 要检查这一点,您只需创建自己的VC类并检查-dealloc方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM