在两个独立的UIViews之间传递消息

时间:2010-07-22 11:36:42

标签: iphone objective-c

在UIViews之间传递信息的最简单方法是什么? 如果我有两个独立的视图,从导航栏推送和弹出,我想从一个UIview在第二个UIview上按下按钮时做一些逻辑?

正确的方法是使用代表吗? 或者有一个简单的方法与界面构建器? 我知道我无法将按钮拖动到IB中不在同一视图上的动作

感谢

5 个答案:

答案 0 :(得分:1)

您使用NSNotificationCenter将消息发送到已注册对该主题感兴趣的任何其他类。真的很容易:)

Notification Programming Guide

答案 1 :(得分:0)

最简单的方法是使用delegate,使用以下命令初始化secondViewController:

UIViewController *secondVC = [[UIViewController alloc] initWithDelegate:firstVC callback:callback];

[firstVC.navigationController pushViewController:secondVC animated:YES];

答案 2 :(得分:0)

这是最简单的事情。准备好让你的思绪变得如此简单?

以下代码演示了如何在两个视图控制器之间共享数据对象:

VCOne.h

@interface VCOne : UIViewController {
    NSString *mystring;
}

@property (nonatomic, retain) NSString *mystring;

@end

VCOne.m

@implementation VCOne

@syntheize mystring;

-(void)viewDidLoad {
    //you probably wouldn't do it here, but just so it has a 
    //place to live, I'm doing it in viewDidLoad...
    VCTwo *two = [[VCTwo alloc] initWithNibName:@"VCTwoView" bundle:nil];
    two.mystring = self.mystring;
    [self.navigationController pushViewController:two animated:YES];
    [two release];
}
-(void)dealloc {
    [mystring release];
    [super dealloc];
}

VCTwo.h:

@interface VCTwo : UIViewController {
    NSString *mystring;
}

//nb the "assign" in the following line where you're probably
//used to seeing "retain"!!
@property (nonatomic, assign) NSString *mystring;

@end

VCTwo.m:

@implementation VCTwo

@synthesize mystring;

-(void)viewDidLoad {
    self.mystring = @"I set this string inside VCTwo!";
}    

-(void)dealloc {
    [super dealloc];
}

好的,好吧!一个视图控制器有一个名为* mystring的NSString,并将其声明为带有retain setter语义的@property。第二个有一个名为* mystring的NSString,并将其声明为assign setter语义的@property(重要的是,不要在-(void)dealloc中释放它。这是内存安全的,尽管它是确实依赖于之前的VC没有将对象从当前的对象中释放出来!)。

然后当第一个VC实例化第二个VC时,它将其mystring字段分配给新VC的字段。新VC接受该对象并将其分配给自己的@property。现在你在VCTwo中对该变量做的任何事情都发生在VCOne中引用的值上。他们现在正在分享这个指针。两个视图控制器都在同一块内存上有一个句柄。

为什么不在VCTwo中使用retain?因为当你说retain时合成的setter方法在设置时清除并重置变量。它们成为单独的对象,并且它们实际上并未同步。您可以在视图控制器之间传递值,但不能传递引用。

如果你发现自己遇到问题,因为它正在上游发布(可能是因为内存警告),你可以随时明确地调用[mystring retain]并保持它。如果你这样做,请确保你在-(void)dealloc中发布它。

答案 3 :(得分:0)

这正是响应者链的意思。 iPhone上的每个UIView和UIViewController都是UIResponder的子类。另外,UIViews和UIViewControllers都会自动添加到响应程序链中。

响应者链是一种在响应者之间发送消息的方法。您可以直接向对象发送消息,也可以将其传递给响应者链。此功能在UIButton上自动实现。

如果您有对view2的引用,则可以将view2添加为按钮的目标,如下所示:

[button addTarget:view2 action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];

如果您没有引用,可以将目标添加到按钮,如下所示:

[button addTarget:nil action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];

将目标设置为nil意味着操作将在响应者链中过去,直到找到响应buttonClicked:选择器的响应者为止。

有关详细信息,请查看UIControl documentationUIResponder documentation

答案 4 :(得分:0)

我使用NSUserDefaults。您可以在App中保存指定的项目,在下一个视图中启动它,如果您返回第一个视图,则可以再次启动它!例如......


//Saving the file - use in the first view controller
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:somedataobject];
[prefs setObject:colordata forKey:@"DataKey"]

//Recalling the file - use in 2nd view
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSData *objectData = [prefs objectForKey:@"DataKey"];
Object *someobject = [NSKeyedUnarchiver unarchiveObjectWithData:objectData];

现在假设数据不是NSInteger,NSString或布尔值。在这种情况下,您将使用: [prefs setInteger: forKey:]; [prefs setBool: forKey:]; 声明,和 [prefs IntegerforKey:] [prefs BoolforKey:] 召回。

以上语法也适用于doubles and floats