Access variable from other view/class

Discussion in 'iOS Programming' started by Scott90, Mar 9, 2011.

  1. Scott90 macrumors 6502

    Joined:
    Jul 14, 2008
    #1
    First of all: I'm quite new to the whole iPhone programming world, so please forgive me any stupidities or basic errors.

    What I'm trying to accomplish is to get a second view to show up with an image based on a randomly selected value from an array that's declared in the first view (which is a different class). For example, the value picked from the array is "apple", and then when the user taps a button, a second view should come up (which I already got working) showing apple.gif.

    Some code to possibly make it clearer:

    Code:
    -(IBAction) showImg {
    
    	Img *imgViewController = [[Img alloc] initWithNibName:@"Img" bundle:nil];
    	
    	[self presentModalViewController:imgViewController animated:YES];
    }
    
    This method is linked to a button, so when the button is tapped, the second view comes up. This works.

    Then, in Img.m I want to do the following:

    Code:
    int random = arc4random() % ([arrayFromFirstView count]);
    
    UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.gif", [arrayFromFirstView objectAtIndex:random]]];
    	
    [imageView setImage:image];
    
    This is part of the viewDidLoad method. Of course, arrayFromFirstView is considered undeclared, because it was only declared in the first view. I do want to have access to it though, I just have no idea how I'd get that.

    Anybody here who could point me in the right direction? Some searching made me think it has to do with delegates, but I haven't been able to find a good article about delegates yet, so I don't know very much about that...

    Thanks!
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    1) Classes don't (in general) access variables. Instances do. The distinction is critical.

    2) Make a property in Img of type UIImageView (assuming that is what imageView is) and set it to the UIImageView instance you want updated (the one owned by the calling object) before you call presentModalViewController:animated:
     
  3. Scott90 thread starter macrumors 6502

    Joined:
    Jul 14, 2008
    #3
    Thanks for your reply!

    Not sure I follow though. I did create a UIImageView property (which is indeed imageView) in Img, and set that to the UIImageView in the secondary view in IB. If I update imageView before calling presentModalViewController:animated:, it tells me imageView is undeclared. Don't know if it has anything to do with it, but I did import Img.h in the .m of the main view.
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    Post the code, both .m and .h, of both classes. At this stage I'm not following what you are doing.
     
  5. Scott90 thread starter macrumors 6502

    Joined:
    Jul 14, 2008
    #5
    Ok, this is the relevant code of the .h of the first view:

    Code:
    @interface FruitViewerViewController : UIViewController {
    
        NSArray *fruits; // Is populated in viewDidLoad (verified this actually happened using NSLog)
    }
    
    The code for that .m:
    Code:
    #import "Img.h"
    
    ...
    
    -(IBAction) showFruitImage {
    	Img *imgViewController = [[Img alloc] initWithNibName:@"Img" bundle:nil];
    	
    	UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%@.gif", [fruits objectAtIndex:random]]];
    
    	[imageView setImage:image]; // Error: undeclared variable imageView
    	
    	[self presentModalViewController:hintViewController animated:YES];
    	[imgViewController release];
    }
    Then this is Img.h:

    Code:
    @interface Hint : UIViewController {
    
    	IBOutlet UIImageView *imageView;
    }
    
    @property(nonatomic, retain) IBOutlet UIImageView *imageView;
    I've connected the IBOutlet to a UIImageView in Img.xib.

    Code for Img.m:

    Code:
    @synthesize imageView; // Kind of unnecessary, but can't do any harm I guess
    -(IBAction) dismissImg {
    	
    	[self dismissModalViewControllerAnimated:YES];
    }
    (Not really relevant, as this is the only method, which is called when the user taps a button in the second/Img view.)
     
  6. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    Of course it's undeclared. It's not an instance variable of that class or declared in scope anywhere. As imageView is a property of Img (or Hint or whatever it is really called) you can access it in the normal way:

    Code:
    [imgViewController.imageView setImage:image];
    
     
  7. Scott90, Mar 9, 2011
    Last edited: Mar 9, 2011

    Scott90 thread starter macrumors 6502

    Joined:
    Jul 14, 2008
    #7
    Ahh, I understood the error and why I got it, I just didn't know how to access imageView from outside its own class, but that's embarrassingly easy. Thanks so much for your help!


    edit:
    I was a little too early. Even though I don't get an error, or anything in the console, the image doesn't show up. If I set the image in the viewDidLoad of Img/Hint (the actual name is Hint, but for the sake of simplicity I called it Img here) it works fine, so I know the connections are made. I can also change one of the buttons in the first view to have an image (which I did just for debugging purposes), so it really is the line "[imgViewController.imageView setImage:image];" that doesn't work for some reason...
     
  8. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #8
    Well this is, somewhat, the problem with using Interface Builder! You will have to delay your call to set the image until the view is loaded from the nib somehow (this is an exercise for you) or use an additional instance variable in Hint (in future post real code, don't change the names etc as this always ends up leading to confusion when you fail to rename in one or more places) to store the image and the set it in viewDidLoad: (again an exercise I leave to you). I'd go for the latter.
     
  9. Scott90 thread starter macrumors 6502

    Joined:
    Jul 14, 2008
    #9
    Yep, that makes sense. I solved it like you recommended, used an extra instance variable to pass on the name of the image, and then in viewDidLoad I actually set the image.

    Again, thanks for your help, I appreciate it!
     

Share This Page