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

2024-04-17

更新:通过下面的“屏幕截图”方法修复。这可行,但是有更优雅的方法吗?

我将如何消除一堆带有动画的模态视图控制器,而不在屏幕上闪烁顶部和底部之间任何呈现的 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 个。


这不是一个错误。您仅更改删除动画self.presentedViewController(“紫色”)当dismissViewControllerAnimated但不适用于所有嵌套 VC。当“紫”收到带动画删除的消息时,会删除所有presentedViewController没有动画。然后您会看到没有嵌套控制器的“紫色”动画。要检查这一点,您可以简单地创建自己的 VC 类并检查 -dealloc 方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • Java编译器选择错误的重载[重复]

    这个问题在这里已经有答案了 Test public void test MyProperties props new MyProperties props setProperty value new Date StringUtils isN
  • 更新实体框架中的数据库架构

    我安装了 VS SP1 并使用了实体框架 我从现有数据库创建了一个架构并尝试了一些基本操作 除了数据库架构更新之外 大部分进展顺利 我以各种基本方式更改了数据库 添加了一个新表 删除了一个表 向现有表添加新列 从现有表中删除一列 更改了现有
  • linux 日期命令中的无效日期错误

    在脚本中我使用命令 CURRENT DATE tmp date d CURRENT DATE Y m d 它给出了错误date invalid date Y m d 可能是什么原因 我知道变量 CURRENT DATE 有其值 date d
  • 使用所需的优化标志重新构建 Tensorflow

    预先感谢您的考虑 我刚刚使用以下命令安装了tensorflow 在已安装Ubuntu 16 04和CUDA 8 0的新机器上 程序 http www nvidia com object gpu accelerated application
  • 溢出-y滚动即使没有溢出也总是显示

    我正在做 与内容分开滚动 JQuery Mobile 面板 我做了什么 https forum jquery com topic scroll inside panel 我应用这个 css 来实现我所做的事情 但问题是 Overflow y
  • Celery + SQLAlchemy:DatabaseError:(DatabaseError)SSL错误:解密失败或坏记录mac

    当在启用 SSL 的 postgresql 数据库上使用 celery 和多个工作线程时 有时会触发标题错误 我使用 Flask SQLAlchemy 配置 正如这里提到的 https github com celery celery is
  • 防止 PHP 中的目录遍历但允许路径

    我有一个基本路径 whatever foo and GET path 应该是相对的 但是 如何在不允许目录遍历的情况下完成此操作 读取目录 eg 无法正确过滤 好吧 一种选择是比较真实路径 basepath foo bar baz real
  • Azure 文件存储内容类型始终为 application/octet-stream

    目前 当我使用以下内容构建 URL 时 我遇到了 Azure 文件存储问题共享访问签名 SAS 令牌 https learn microsoft com en us azure storage common storage dotnet s
  • 如何使用Python在多进程中运行pycuda

    我有一个可以在单个进程中运行的 pycuda 代码 python的多进程可以支持在多个子进程中运行这段代码吗 如果我尝试 我会发现我犯了一个错误 我做错了吗 我尝试用python的进程实现一个简单的多进程 发现会出错 import pycu
  • Java 反射调用原始类型的构造函数

    我的测试框架中有一个方法 可以根据传入的参数创建类的实例 public void test Object constructorArgs throws Exception Constructor
  • 如何在 Automapper 中使用数据集?

    我目前使用数据读取器作为源 但我想改用数据集 datareader AutoMapper Mapper CreateMap
  • 确定事务中无法执行的T-SQL/DDL

    有多种语句和系统过程无法在事务中执行 并出现错误消息 不允许 例如 create database 或 无法执行 例如 exec sp addrole 是否存在一条或一组规则来指示事务中是否不允许给定的过程 语句 有其列表吗 不是 Micr
  • 使用 AWS CodeBuild 构建 Windows 容器

    我正在开始使用 AWS 的 CI CD 功能 到目前为止 我已经基于 microsoft windowsservercore 映像在 Windows Server 2016 本地创建了 docker 映像 并将其手动推送到 ECR 亚马逊容
  • 内联块 div 中的文本将其向下推[重复]

    这个问题在这里已经有答案了 今天早上我发现了一个奇怪的 CSS 问题 我希望 CSS 专家能帮助我 在这个演示 http jsfiddle net 7HBCe 为什么红色 div 中的文本将其向下推 我预计这两个 div 会彼此相邻 谢谢
  • 删除Elasticsearch中类型的文档

    我想使用 HTTP REST api 删除 Elasticsearch 中某一类型中索引的所有文档 但我不想删除该类型的映射 如何在 URL 中构建查询来执行此操作 执行命令前 索引 映射状态 截图取自elasticsearch头插件网络界
  • 你能帮助解释我的 svn diff 输出吗?

    我正在使用 SVN DIFF 比较两个文件夹 一个在分支中 一个在主干中 目的是确定更改列表 然后我对分支中的文件进行了一些更改 但输出显示我已经在主干中修改了它们 为什么会出现这种情况 有没有更好的命令来获取我正在寻找的结果 我现在使用的
  • 具有 EasyIn 动画,然后按顺序缩放动画,因为缩放动画会永远重复

    我想要在 onAppear 上为文本信息和 SF 符号添加一个 escapeIn moveUp 动画 此后 我只希望 SF 符号永远按比例放大和缩小 目前 我已经设法永远缩小规模 但是当我设法链接时 easeIn moveUp 动画也会永远
  • Julia 似乎没有使用字符串来执行插值

    官方文档指出 连接和字符串插值调用string 将对象转换为字符串形式 然而 以下最小工作示例似乎证明了其他情况 type MyType x Int end import Base string Base string m MyType w
  • ... 不支持谷歌地图 Javascript API。使用其他浏览器

    我正在使用两个不同的第三方程序 不同的公司 它们显然使用 Google Maps Javascript API 当他们加载地图时 会显示世界地图 但会显示一条错误消息 Der von Ihnen verwendete Browser wir
  • 如何用动画消除一堆模态视图控制器而不在屏幕上闪烁顶部和底部之间任何呈现的 VC?

    更新 通过下面的 屏幕截图 方法修复 这可行 但是有更优雅的方法吗 我将如何消除一堆带有动画的模态视图控制器 而不在屏幕上闪烁顶部和底部之间任何呈现的 VC 尝试用动画来做到这一点是行不通的 请参阅下面的代码和描述我的问题的内嵌注释 您可以