我有两个视图控制器,firstViewControllersecondViewController.我使用这段代码切换到我的secondViewController(我还向它传递了一个字符串):

secondViewController *second = [[secondViewController alloc] initWithNibName:nil bundle:nil];

second.myString = @"This text is passed from firstViewController!";

second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

[self presentModalViewController:second animated:YES];

[second release];

然后,我在secondViewController中使用此代码切换回firstViewController:

[self dismissModalViewControllerAnimated:YES];

所有这些都运行得很好.我的问题是,我如何将数据传递给firstViewController?我想将一个不同的字符串从secondViewController传递到firstViewController.

推荐答案

你需要使用委托协议...以下是如何做到这一点:

在secondViewController的头文件中声明协议.应该是这样的:

#import <UIKit/UIKit.h>

@protocol SecondDelegate <NSObject>
-(void)secondViewControllerDismissed:(NSString *)stringForFirst
@end


@interface SecondViewController : UIViewController
{
    id myDelegate;  
}

@property (nonatomic, assign) id<SecondDelegate>    myDelegate;

不要忘记在实现(SecondViewController.m)文件中合成myDelegate:

@synthesize myDelegate;

在FirstViewController的头文件中,通过以下操作订阅Second Delegate协议:

#import "SecondViewController.h"

@interface FirstViewController:UIViewController <SecondDelegate>

现在,当您在FirstViewController中实例化SecondViewController时,您应该执行以下操作:

// If you're using a view controller built with Interface Builder.
SecondViewController *second = [[SecondViewController alloc] initWithNibName:"SecondViewController" bundle:[NSBundle mainBundle]];
// If you're using a view controller built programmatically.
SecondViewController *second = [SecondViewController new]; // Convenience initializer that uses alloc] init]
second.myString = @"This text is passed from firstViewController!";
second.myDelegate = self;
second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:second animated:YES];
[second release];

最后,在第一个视图控制器的实现文件(FirstViewController.m)中,为secondViewControllerDismissed实现SecondDelegate的方法:

- (void)secondViewControllerDismissed:(NSString *)stringForFirst
{
    NSString *thisIsTheDesiredString = stringForFirst; //And there you have it.....
}

现在,当您要取消第二个视图控制器时,您希望调用在第一个视图控制器中实现的方法.这部分很简单.您所要做的就是在第二个视图控制器中,在解除代码之前添加一些代码:

if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:)])
{
    [self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!"];
}
[self dismissModalViewControllerAnimated:YES];

委托协议非常、非常、非常有用.熟悉一下它们会对你有好处:)

NSNotification是实现此目的的另一种方式,但作为最佳实践,当我希望跨多个viewController或对象进行通信时,我更喜欢使用它.如果你对使用NSNotitification感兴趣,这是我在早些时候发布的一个答案:Firing events accross multiple viewcontrollers from a thread in the appdelegate

编辑:

如果要传递多个参数,则解除之前的代码如下所示:

if([self.myDelegate respondsToSelector:@selector(secondViewControllerDismissed:argument2:argument3:)])
{
    [self.myDelegate secondViewControllerDismissed:@"THIS IS THE STRING TO SEND!!!" argument2:someObject argument3:anotherObject];
}
[self dismissModalViewControllerAnimated:YES];

这意味着您的firstViewController内的Second Delegate方法实现现在将如下所示:

- (void) secondViewControllerDismissed:(NSString*)stringForFirst argument2:(NSObject*)inObject1 argument3:(NSObject*)inObject2
{
    NSString thisIsTheDesiredString = stringForFirst;
    NSObject desiredObject1 = inObject1;
    //....and so on
}

Ios相关问答推荐

如何让AVAudio.installTap()每秒回调125次

RN 0.63支持iOS ProMotion?

PieChartView未以编程方式显示在屏幕上

iOS SwiftUI需要不带箭头显示弹出窗口""

彩色进度线--SWIFT

SwiftUI绑定到特定的一个或多个枚举 case

AVFoundation Camera推出变焦SWIFT

在TVOS中访问SWIFT中的objc++函数时发送给类的无法识别的 Select 符

Flutter 翼项目.升级到XCode 15.0.1`pod install`抛出错误FlutterMacOS.podspec.json 3.13.2的ParserError

应用程序被杀死时如何在 flutter ios 应用程序中播放音频?

拔下设备后,DriverKit USB 驱动程序 (dext) 进程不会终止

为什么@FetchRequest 在删除时不更新和重绘视图?

SwiftUI:同时拖动父视图和子视图,但手指分开

如何在 Swift 中旋转 UIButton 和 UILabel 的文本?

Xcode 8:函数类型不能有参数标签 destruct 我的构建

CoreBluetooth 应用程序到底能在后台做什么?

iOS:如何从 URL 调试新启动应用程序

如何为 UILabel 的背景 colored颜色 设置动画?

ARC - __unsafe_unretained 的含义?

NSURL 到带有 XCTest 的测试包中的文件路径