更新:通过下面的“屏幕截图”方法修复。这可行,但是有更优雅的方法吗?
我将如何消除一堆带有动画的模态视图控制器,而不在屏幕上闪烁顶部和底部之间任何呈现的 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
更新:
添加了新的 MyViewController.m 文件用于dealloc 调试。
有趣的是,日志看起来像这样:
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 https://github.com/johnerck/MultipleModals
另外,我读过从其他视图控制器呈现视图控制器 https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html#//apple_ref/doc/uid/TP40007457-CH111-SW1多次。他们甚至说,“例如,如果用户取消当前操作,您可以通过关闭第一个呈现的视图控制器来删除链中的所有对象。关闭视图控制器不仅会关闭该视图控制器,还会关闭它呈现的任何视图控制器。 ”我看到了这种行为,但动画总共显示 3 个视图,而不是预期的 2 个。