【问题标题】:Navigation change doesn't get triggered when calling it inside callback block在回调块中调用导航更改时不会触发它
【发布时间】:2018-03-09 10:14:17
【问题描述】:

我的任务是在更大的 Objective-C 应用程序中进行一些小调整。

我想要做的是当用户点击列表中的一个项目时,将执行计算,根据结果,导航应该弹回根目录并显示错误。因为我无法访问完成计算的类中的 NavigationController,所以我尝试传递一个“回调块”。

[self.baseBehaviour processInfo:info completion: ^(BOOL finished) {
  NSLog(finished ? @"YES" : @"NO");
  // pop back to root controller
  [self.navigationController popToRootViewControllerAnimated:YES];
 }];

我一直传递该块,直到计算完成并调用回调。它似乎工作正常,因为我可以在日志中看到是或否,但由于某种原因没有触发导航。这似乎也不是范围界定问题,因为 self 似乎是同一个引用(我什至尝试为 navigationController 创建一个新变量,但这也无济于事)。

如果我取出 [self.navigationController popToRootViewControllerAnimated:YES]; 并将其移出回调(因此它会立即执行),它会完美运行。但显然这对我没有帮助,因为当时我并没有确定是否需要回去。

我是否遗漏了一些明显的东西,或者有办法(在调试器中)查看为什么动画没有被触发?

感谢您的帮助。

编辑:

我在测试时尝试过这个,但它似乎也没有工作:

    [self.baseBehaviour processInfo:self.info completion: ^(BOOL finished) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(finished ? @"YES" : @"NO");
            // pop back to root controller
            [self.navigationController popToRootViewControllerAnimated:YES];
        });
    }];

EDIT2:

看来这毕竟可能是一个范围界定问题。我注意到当我执行 `` 时它在调试器中为 nil。

NSArray *viewCtrls = [self.navigationController viewControllers]; // 3 elements

[self.baseBehaviour processInfo:self.info completion: ^(BOOL finished) {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(finished ? @"YES" : @"NO");
        // pop back to root controller
        NSArray *viewCtrls = [self.navigationController viewControllers]; // nil
        [self.navigationController popToRootViewControllerAnimated:NO];
    });
}];

如何将某些东西“传递”到回调块中,例如导航控制器?

【问题讨论】:

  • 完成块将在辅助线程中执行。所以在那里创建一个主线程(NSOperationQueueNSThread),然后弹出到根控制器。
  • 我已经用另一个代码 sn-p 更新了我的答案,遗憾的是它也不起作用。是否有可能因为另一个动画(推送)已经在运行而没有触发动画?
  • 在最后一个参数中,传递 NO 而不是 YES。我还编辑了my answer

标签: ios objective-c uinavigationcontroller


【解决方案1】:

在主线程中执行,例如:

dispatch_async(dispatch_get_main_queue(), ^{[self.navigationController popToRootViewControllerAnimated:YES];});

这可能对你有帮助

【讨论】:

    【解决方案2】:

    只需在主线程上运行即可。

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.navigationController popToRootViewControllerAnimated:true];
    });
    

    【讨论】:

    • 感谢您的回答,我已经尝试过了,很遗憾没有成功。
    • 请检查rootViewController,是不是你想要的?
    • 我是这么认为的,否则我把它放在回调之外也行不通,对吧?
    【解决方案3】:

    完成块将在辅助线程中执行。推送或弹出视图控制器必须在主线程中。所以在那里创建一个主线程并弹出到根控制器

        [self.baseBehaviour processInfo:info completion: ^(BOOL finished) {
          NSLog(finished ? @"YES" : @"NO");
          // pop back to root controller
    dispatch_async(dispatch_get_main_queue(), ^{[self.navigationController popToRootViewControllerAnimated:YES];});
    
    
         }];
    

    您在评论中的问题:- 是否有可能因为另一个动画(推送)已经在运行而没有触发动画? 答:- 如果您遇到动画故障问题,请在弹出视图控制器时传递NO,如下所示:-

    dispatch_async(dispatch_get_main_queue(), ^{[self.navigationController popToRootViewControllerAnimated:NO];});
    

    【讨论】:

    • 感谢您的快速回复。我更新了我的答案,遗憾的是它没有用。
    • 那还是不行。问题是它根本不会被触发,所以它根本不会返回。如果另一个导航已在运行,是否会阻止导航更改?
    • 其他导航是什么?其他导航控制器也在推送或弹出视图控制器?
    • 我更新了我的答案,也许这毕竟是一个范围问题。
    猜你喜欢
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    • 2017-01-25
    • 2014-01-26
    • 2010-10-09
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    相关资源
    最近更新 更多