views:

47

answers:

2

How does one use an already existing object from another class?

e.g. Have a object of Class1 and want to set its variables from Class2.

What does one import? Is it just necessary to import the Class1, will this make the object available to the class that imported?

In a class e.g. Main Class1 is created and presented

- (IBAction) openClass1 {
    Class1 *c = [[Class1 alloc]initWithNibName:@"Class1" bundle:nil];
    [self presentModalViewController:c animated:NO];
    [c release];
}

Then Class1 would have many properties (I only made one here)

@interface Class1 : UIViewController {
    UIImageView *image;
}
@property(nonatomic, retain) UIImageView *image;
@end

I would like to edit the Class1 variables in Class2 and then dismiss the Class2 view and see the changes in Class1. e.g. a label with new text or a UIImage with another image set to it etc.

+1  A: 

Look again at this line:

Class1 *c = [[Class1 alloc]initWithNibName:@"Class1" bundle:nil];

So what that does is create an instance of Class1. This is a new instance, freshly initialized. And c is a pointer to that new instance.

So once you have c, you can send c message or access c's properties. In your example, you can do something like this right after the line above:

c.image = [UIImage imageNamed:@"foo.png"]; 

And you'll also want to import "Class1.h" so that the compiler is satisfied that Class1 does in fact have a property called 'image'.

It's important to understand, though, what's going on here. You're not importing an object. You're creating an object, an instance of Class1. And then to convince the compiler that it is OK to set that property, you import Class1.h which tells the compiler about all of the @property's and public methods.

Firoze Lafeer
I know this thanks, but that is not what I meant. I already create an instance of class1 in my main class and then present class1. What I want is to be able to set class1's variables from another class(class2) without creating a new instance and losing my current data.
alJaree
Ok, so once you have that pointer c, you can pass that pointer to another object (using a property or an initializer or however you like). You didn't say where you create your instance of "Class2", but Class2 could be defined with a property of type Class1* or an initializer that accepts a Class1*.
Firoze Lafeer
I have it set up as Class1 creates a Class2 instance and presents it, then Class2 creates a class 3 instance and presents it. Then I want to be able to set a UIButton to an IBAction which when pressed creates the appropriate image and displays it on Class1. I would have many buttons and want to be able to set various images. So like a cycle from Class1>Class2>Class3 select button>display image on Class1> repeat.
alJaree
Ok, so you can just keep passing pointers to each VC along the way. Or maybe you need to rethink the design. Maybe keep the current images in another object (some singleton for example) that every VC would have ready access to.
Firoze Lafeer
+1  A: 

What you have here is actually view controller classes. You should not assume that another view controller has it's view loaded. A view controller should be allowed to load it's view lazily and as needed, this is a core concept of Cocoa Touch.

This means you should not access a view controllers view or subviews (like UILabels, and UIImageViews) directly from the outside.

If you want to configure a a view controller to be displayed, they you should probably do that using the designated initializer.

You could for example create Class1 like this:

@interface Class1 : UIViewController {
   UIImage* imageToShow;
   IBOutlet UIImageView* imageView;
}
-(id)initWithImage:(UIImage*)image;
@end

And implement it like this:

@implementation Class1
- (id)initWithImage:(UIImage*)image {
    self = [self initWithNibNamed:@"Class1" bundle:nil];
    if (self) {
        imageToShow = [image retain];
    }
    return self;
}
- (void)dealloc {
    [imageToShow release];
    [super dealloc];
}
- (void)viewDidLoad;
    imageView.image = imageToShow;
}
@end

And then from Class2 you present the view controller Class1 like so:

-(IBAction) openClass1 {
    Class1 *c = [[Class1 alloc] initWithImage:[UIImage imageNamed:@"Test.png"]];
    [self presentModalViewController:c animated:NO];
    [c release];
 }
PeyloW
Great, thanks. Will this openClass1 just reopen the already existing viewcontroller and add the image to it using init? The reason is if I want to add multiple images at different times depending on user actions, I dont want to overwrite or lose what images I have already.
alJaree
@alJaree: No it will only display one image at a time, and it is not intended to be replaceable. Allowing for images to be added is a bigger task. You would then probably want to use an `NSArray* imagesToShow` and expose a method such as `-(void)addImage:(UIImage*)image`to `Class1`. This method would need to update the internal array, as well as the actual UI as needed.
PeyloW
Thanks.What if I create subviews and set an image within these. Then add the subview to the viewcontroller Class1? Or what is the best way to achieve this?
alJaree
@alJaree: Depend on your needs. Most simple case; let `Class1`have a `UItableView` and juts use the array of images as data source. If a more complex UI is needed then `UIScrollView` is probably a good start. Look at the videos from WWDC 2010, or download Apple's exaple code, to get started.
PeyloW