开发者

Pass messages between two independent UIViews

What is the easiest way to 开发者_Python百科pass information between UIViews? If i have 2 standalone views that push and pop from the navigation bar and I want from one UIview to do some logic when a button pressed on the second UIview??

Is the right way is to use delegates? or is there a simple way with the interface builder? I know that I cannot drag button to action that is not on the same view in IB

thanks


You use the NSNotificationCenter to send messages to any other class that has registered an interested in that topic. Really easy :)

Notification Programming Guide


Here's the easiest thing. Ready to have your mind blown with how simple this can really be?

The following code demonstrates how to share a data object between two view controllers:

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];
}

Okay, so! One view controller has a NSString called *mystring and declares it as a @property with the retain setter semantics. The second one has a NSString called *mystring and declares it as a @property with the assign setter semantic (and, importantly, DOESN'T release it in -(void)dealloc. This is memory-safe, although it does depend on the previous VC not releasing the object away from the current one!).

Then when the first VC instantiates the second one, it assigns its mystring field to the new VC's field. The new VC accepts that object and assigns it on its own @property. Now anything you do to that variable in VCTwo is ALSO happening on the value that's referred to in VCOne. They're literally sharing that pointer now. Both view controllers have a handle on the same piece of memory.

Why not use retain inside VCTwo? Because the setter method that's synthesized when you say retain clears and resets the variable when it is set. They become separate objects, and they're not actually synced up. You can pass values between view controllers that way, but not references.

If you find yourself having issues with the object going away because it's getting released upstream (as a result of memory warnings, perhaps), you can always explicitly call [mystring retain] and keep it around. Just be sure you DO release it in -(void)dealloc if you do that.


The easiest way is to use delegate, init the secondViewController with:

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

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


This is exactly what the responder chain is meant for. Every UIView and UIViewController on the iPhone is a subclass of UIResponder. Additionally UIViews and UIViewControllers are both automatically added to the responder chain for you.

The responder chain is a way to send messages between responders. You can send messages to objects directly or you can pass them down the responder chain. This functionality is automatically implemented on UIButton's.

If you have a reference to view2 you can add view2 as a target of a button like so:

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

If you do not have a reference you can add a target to a button like so:

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

Setting the target to nil means the action will be past down the responder chain until a responder is found that responds to the buttonClicked: selector.

For more information take a look at UIControl documentation and UIResponder documentation.


I use NSUserDefaults. You can save the specified Item in the App, launch it in the next view, and be able to launch it again if you go back to the first view! For example...


//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];

Now this is assuming that the data is NOT an NSInteger, an NSString, or a boolean value. In that case you would use: [prefs setInteger: forKey:]; [prefs setBool: forKey:]; for the declaration, and [prefs IntegerforKey:] [prefs BoolforKey:] for recalling.

The above syntax also works for doubles and floats.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜