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

查看:114
本文介绍了使用完成块显示和关闭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.如果需要,请在块外使用__weak引用self并使用它.

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.

最简单的方法是继承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天全站免登陆