簡體   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