使用完成块呈现和关闭 UIViewController - 没有协议和委托 [英] present and dismiss UIViewController with completion blocks - without protocols and delegates

查看:15
本文介绍了使用完成块呈现和关闭 UIViewController - 没有协议和委托的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从 VC1 的实例中呈现一个 VC2 的实例,并传递一个完成块,当 VC2解雇自己.传递的完成块将是对 VC1 实例的方法调用.

I would like to present an instance of VC2 from an instance of VC1 and pass it a completion block to be executed when the VC2 dismisses itself. The passed completion block will be a method call on the VC1 instance.

这样做的正确方法是什么?

What would be the correct way of doing this?

虽然通常从 VC1 呈现 VC2 是:

While presenting VC2 from VC1 normally is:

    VC2 *vc2 = [[VC2 alloc] init];
    [self presentViewController:vc2 animated:YES completion: nil];

在 VC2 中

    [self dismissViewControllerAnimated:YES completion: nil];

(ps 通常我会在 VC2 中像这样关闭 VC2 - 即调用协议中声明的 VC1 方法

(ps normally I would dismiss VC2 like this in VC2 - ie call a VC1 methods declared in a protocol

  [self.delegate dismissVC2]; // basically meaning VC1 to dismiss VC2

...但我想 VC2 也可以自行解散 - 但是我不确定这是否总是可以的.

...but I guess VC2 can dismiss itself too - however I am not sure this is ALWAYS ok.

虽然在 Apple 文档中,他们仍然推荐授权方案 - 但是自我解雇也有效.

While in the Apple docs, they still recommend delegation scheme - however self dismissing works too.

您也可以对此发表评论吗?)

Could you comment on this as well?)

我想在 VC2 中做这样的事情:

I would like to do sth like this in VC2:

    [self dismissViewControllerAnimated:YES completion: passedBlockFromVC1];

当呈现 VC2 时,将此 passedBlockFromVC1 以某种方式传递给 VC2 - 同时包含 VC1 方法.

And when presenting VC2 pass this passedBlockFromVC1 somehow to VC2 - while containing a VC1 method.

这样做的正确方法是什么?

What would be the correct way of doing this ?

总而言之,我正在寻找一种从 VC1 呈现 VC2 的解决方案,当 VC2 被解除时,它会在完成时调用 VC1 方法 - 所有这些都不需要定义协议或使用委托(我发现这对某些人来说非常麻烦在这种情况下扩展 - 但非常可靠)

In summary, I am looking for a solution to present VC2 from VC1 and when VC2 get's dismissed it calls a VC1 method at completion - all without the need to define a protocol or use a delegate (which I find quite cumbersome to some extend in this case - BUT extremely reliable)

是否可行并推荐使用?

非常感谢!

推荐答案

这是可能的,但您必须注意保留循环.请记住,块将捕获其中引用的任何变量,包括 self.如果 VC1 保持对 VC2 的强引用,那么注意不要让块也对 VC1 有强引用.如果需要,在块外对 self 进行 __weak 引用并使用它.

This is possible but you have to watch out for retain cycles. Remember that a block will capture any variables referenced within it including self. If VC1 keeps a strong reference to VC2 then be careful not to let the block have a strong reference to VC1 as well. If needed make a __weak reference to self outside the block and use that.

有关使用块的保留循环以及如何避免它们的更多信息,请参阅 Apple 文档.

最简单的方法是继承 UIViewController 并创建自己的方法和属性来实现这一点.

The easiest thing to do would be to subclass UIViewController and make your own methods and properties to achieve this.

您可以声明一个属性来将块存储为实例变量,如下所示:

You can declare a property to store a block as an instance variable like so:

@property (nonatomic, copy) dispatch_block_t completionBlock;

使用标准的 libdispatch 块类型.

using the standard libdispatch block type.

然后定义一些设置方法:

Then define some methods for setting this up:

-(void)presentViewController:(UIViewController *)viewController animated:(BOOL)animated completion:(void (^)(void))completion dismissCompletion:(dispatch_block_t)dismissCompletion{
    self.completionBlock = dismissCompletion;
    [super presentViewController:viewController animated:animated completion:completion];
}

然后覆盖dismiss方法以调用完成块(如果有).

then override the dismiss method to call the completion block if there is one.

-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion{
    if (self.completionBlock && ! completion){
        [super dismissViewControllerAnimated:flag completion:self.completionBlock];
        self.completionBlock = nil;
        return;
    }
    [super dismissViewControllerAnimated:flag completion:completion];
}

这篇关于使用完成块呈现和关闭 UIViewController - 没有协议和委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆