将信息传递给模态视图控制器

Posted

技术标签:

【中文标题】将信息传递给模态视图控制器【英文标题】:Pass Information to Modal View Controllers 【发布时间】:2014-07-21 12:56:25 【问题描述】:

我在这里阅读了一些关于从视图控制器传回数据的文章,我知道这肯定有一些禁忌,但我想询问以这种方式传递数据的最佳实践,并询问是否我在下面做什么可以吗?

我有 3 个视图控制器(ViewControllerA、B 和 C 类),当用户单击按钮(从 A 或 B)时,它会将它们带到 C 使用:

let vc = new ViewControllerC()
self.presentViewController(vc, animated: true, completion: nil)

向前传递数据 所以上面的'self'要么是A,要么是B。我的想法是,如果我想向C发送一些信息,我可以只创建C的一个属性(例如字符串或int等)并在之前分配它我做一个presentViewController。对吗?

即 vc.propertyHere = "我的价值"

传回数据 如果我想将 C 中发生的事情发回 A 或 B,那么最佳做法是什么? 要返回 A 或 B,我知道我可以这样做: self.dismissModalViewControllerAnimated(true)

我是否应该首先实例化 A 或 B(可能通过它们的基类型)并访问类似的属性以获取我想要传回的信息?例如,如果 A 和 B 都从某个类继承,我可以在该类上创建一个属性,然后从 C 访问/设置它。这是正确的举动吗?还是有更好的方法? 即

     callingViewController.myProperty = "my value i'm passing back"

谢谢!

【问题讨论】:

【参考方案1】:

向前传递数据 - 你的实现很好。

传回数据 -

不要再次启动 A 和 B,这是我在新开发人员中看到的常见错误。 A 或 B 已经存在,您从 A/B 来到这个新控制器,您只想将一个值传递回该类。

这里使用的最佳实践是委托设计模式。

步骤:

    创建一个协议,声明要在 A/B 中调用的 a 方法。

    在 C 中实现一个名为 delegate 的属性。

    在呈现视图 C 之前,分配委托。

    只要您想将任何信息传递给 A 或 B,请调用委托方法。

在此处的另一个 SO 答案中解释了实现委托:How do I create delegates in Objective-C?

【讨论】:

【参考方案2】:

对于下坡,您在视图控制器上设置属性的建议在技术上没有问题

vc.propertyHere = "my value"

但是有一种称为Dependancy Injection 的模式可以在父母和孩子之间提供更清晰的对话。

因此,如果您的新视图控制器需要某些功能,您可以在初始化时将其提供给实例。

import Foundation
import UIKit

class ObjectTypeA 
class ObjectTypeB 

class FooVC : UIViewController 

var importantThing:ObjectTypeA!
var otherImportantThing:ObjectTypeB!

init(somethingINeed:ObjectTypeA, somethingElseINeed:ObjectTypeB) 

    importantThing = somethingINeed
    otherImportantThing = somethingElseINeed

    super.init(nibName:nil,bundle:nil)






class BarVC : UIViewController 

    func yo() 

        let object1 = ObjectTypeA()
        let object2 = ObjectTypeB()

        let newVC = FooVC(somethingINeed: object1, somethingElseINeed: object2)

        self.presentViewController(newVC, animated: true, completion: nil)

    


所以继续做你正在做的事情,但在未来看看其他模式。

对于向上传递数据或事件,最好使用其他人描述的委托模式。这样,父母和孩子之间就没有紧密的耦合。任何采用该协议的对象都可以成为委托。

例如

class BlueSuedeShoes

protocol FunkyProtocol 

    func danceLikeElvis(shoes:BlueSuedeShoes)



class LumpyVC:UIViewController  

    var delegate:FunkyProtocol?

    func somethingHappened() 

        let myShoes = BlueSuedeShoes()

        self.delegate?.danceLikeElvis(myShoes)
    

以及实现该协议的类

class SmoothVC:UIViewController,FunkyProtocol 


    func danceLikeElvis(shoes: BlueSuedeShoes) 

        dontStepOn(shoes)

    

    func dontStepOn(shoes:BlueSuedeShoes) 


    



【讨论】:

所以 A 和 B 都将用户重定向到 C。我会定义一个协议(可能在 A 和 B 的基类中?),然后我会像上面那样在 C 中创建一个变量(委托: FunkyProtocol) 并且当我准备好传递我的值时,我只需像您在上面所做的那样调用它,并且可以在 A 中访问该信息。对吗? 是的。在新文件或 A 或 B 中声明协议。在设置 C 时设置委托,记住委托不必是 A/B,它可以是采用该协议的任何东西。在 A/B 中实现协议方法,然后您可以通过这些委托方法传递您的信息。考虑一下 tableview 用来展示自己的所有委托/数据源方法。完全一样,你只是在创建自己的协议【参考方案3】:

您可以使用委托模式来实现这一点。这是一个小例子,请看。

@protocol SecondViewControllerDelegate;

@interface SecondViewController;

SecondViewController : UIViewController

@property (nonatomic, assign) id<SecondViewControllerDelegate> delegate;
@property (nonatomic, retain) NSArray* someArray;

@end

@protocol SecondViewControllerDelegate
- (void)secondViewControllerDidFinish:(SecondViewController*)secondViewController;
@end

SecondViewController.m:

@implementation SecondViewController

@synthesize delegate;
@synthesize someArray;

- (void)dealloc

    [someArray release];
    [super dealloc];


- (void)someMethodCalledWhenUserIsDone

    [delegate secondViewControllerDidFinish:self];

FirstViewController.h:

#import SecondViewController

@interface FirstViewController : UIViewController <SecondViewControllerDelegate>

    ...


@end

FirstViewController.m:

@implementation FirstViewController

- (void)secondViewControllerDidFinish:(SecondViewController*)secondViewController

    NSArray* someArray = secondViewController.someArray
    // Do something with the array


@end

【讨论】:

OP 在 Swift 中执行此操作,而不是 ObjC。

以上是关于将信息传递给模态视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

将现有和活动的手势识别器传递给模态视图控制器

将信息传递给目标 c 的当前视图控制器下的视图控制器

如何将对对象的引用传递给包含在导航控制器中的模态呈现的视图控制器?

通过视图控制器将委托传递给视图控制器

将 NSMutableArray 从模态视图控制器传递到父视图

使用 NSFetchedResultsController 和 CoreData 将选定的行传递给另一个表视图控制器