jjzjj

ios - 取消交互式 UINavigationController 弹出手势不会调用 UINavigationControllerDelegate 方法

coder 2023-07-25 原文

如果您拖动 UIViewController 的边缘以在 UINavigationController 中开始交互式弹出转换,当前下方的 UIViewController 具有 viewWillAppear: 被调用,然后是 UINavigationControllerDelegate 方法 navigationController:willShowViewController:animated:

如果取消转换(即被拖动的 Controller 放回原来的位置而不弹出),viewWillAppear:viewDidAppear: 会在顶 View Controller 上调用正如预期的那样,但是委托(delegate)方法 navigationController:willShowViewController:animated:navigationController:didShowViewController:animated: 不是。考虑到调用了 UIViewController View 生命周期方法,似乎至少应该调用其中一个或两个。我想知道这是故意的还是 UINavigationController 中的错误。

我真正需要的是能够在我的 UINavigationController 子类或其 UINavigationControllerDelegate 中看到交互式 pop 何时被取消。有没有明显的方法可以做到这一点?

编辑

我仍在寻找解决方案,但我想提一下,我已将此问题报告为 Apple 的错误。查看文档,没有理由不调用这些委托(delegate)方法,尤其是考虑到确实调用了等效的 View 生命周期方法。

edit2

我的雷达票 (16823313) 今天(2015 年 5 月 21 日)关闭并标记为预期。 :(

Engineering has determined that this issue behaves as intended based on the following information:

This is actually the correct behavior. The navigation transition that's happening from B -> A, if you cancel it mid-transition, you won't get the didShowViewController: method. A cancellation of this transition shouldn't be considered a transition from A -> B because you never actually reached A.

view[Will/Did]Appear should still be called as expected too.

这种情况非常令人失望,因为它违反直觉,但我下面的回答中的解决方法在可预见的 future 应该可以正常工作,至少对于我的用例而言。

最佳答案

对于任何感兴趣的人,我发现了两种在 UINavigationControllerDelegate 级别解决此问题的方法。

  1. 使用 KVO 观察 interactivePopGestureRecognizerstate 属性。不幸的是,取消转换不会将状态更改为 UIGestureRecognizerStateFailed,而只是更改为 UIGestureRecognizerStateEnded,因此您需要编写一些额外的代码来跟踪发生的情况,如果您需要区分取消或完成的 pop。

  2. 经过测试,这可能是更好的解决方案:使用 navigationController:willShowViewController:animated: 方法向转换协调器添加通知 block 。它看起来像这样:

    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        [[self transitionCoordinator] notifyWhenInteractionEndsUsingBlock:^(id<UIViewControllerTransitionCoordinatorContext> context)
        {
            if([context isCancelled])
            {
                UIViewController *fromViewController = [context viewControllerForKey:UITransitionContextFromViewControllerKey];
                [self navigationController:navigationController willShowViewController:fromViewController animated:animated];
    
                if([self respondsToSelector:@selector(navigationController:didShowViewController:animated:)])
                {
                    NSTimeInterval animationCompletion = [context transitionDuration] * (double)[context percentComplete];
    
                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((uint64_t)animationCompletion * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                        [self navigationController:navigationController didShowViewController:fromViewController animated:animated];
                    });
                }
    
    
            }
        }];
    }
    

一开始我对使用这个解决方案犹豫不决,因为文档不清楚你是否可以设置多个(因为在那种情况下,如果一个不知情的 View Controller 也设置了自己的通知 block ,它可能要么替换这个,要么被这个替换)。不过在测试之后,它似乎不是 1:1 的关系,您可以安全地添加多个通知 block 。

编辑

我编辑了上面的代码以延迟 navigationController:didShowViewController:animated: 调用,使其仅在动画应该完成以更接近预期的默认行为时调用。

关于ios - 取消交互式 UINavigationController 弹出手势不会调用 UINavigationControllerDelegate 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23484310/

有关ios - 取消交互式 UINavigationController 弹出手势不会调用 UINavigationControllerDelegate 方法的更多相关文章

  1. ruby - Highline 询问方法不会使用同一行 - 2

    设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. ruby-on-rails - 如何在 ruby​​ 交互式 shell 中有多行? - 2

    这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式ruby​​shell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f

  4. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  5. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  6. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  7. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  8. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  9. ruby-on-rails - prawnto 显示新页面时不会中断的表格 - 2

    我有可变数量的表格和可变数量的行,我想让它们一个接一个地显示,但如果表格不适合当前页面,请将其放在下一页,然后继续。我已将表格放入事务中,以便我可以回滚然后打印它(如果高度适合当前页面),但我如何获得表格高度?我现在有这段代码pdf.transactiondopdf.table@data,:font_size=>12,:border_style=>:grid,:horizontal_padding=>10,:vertical_padding=>3,:border_width=>2,:position=>:left,:row_colors=>["FFFFFF","DDDDDD"]pdf.

  10. ruby-on-rails - 取消 Rails 数据库连接 - 2

    我正在编写一个将服务器端事件与ActionController::Live结合使用的应用程序。它正在使用puma应用程序服务器。当用户连接等待来自Redis的消息时,消息Controller中的方法保持事件状态。问题是我不想通过这种方法连接到Postgres。我在六个选项卡中打开应用程序后,它有超过五个连接,由config/database.yml文件中的池大小定义,应用程序崩溃。无论如何,在调用该方法时是否可以告诉我的应用它不需要连接到数据库,因为其中没有ActiveRecord查询调用? 最佳答案 一种可能的方法是使用中间件。设

随机推荐