views:

431

answers:

3

Hi all, I have a problem with arrays and passing images between views that I would like some help on! So the background is that I have:

• RootViewController (which handles my table view)

• CommunicationViewController which handles the detail of the selected element from the table

• SelectSlideViewController which displays an image clicked on from the CommunicationViewController and allows the user to select a different one from the camera roll

So the problem:

• In the CommunicationViewConroller, I have the following code if the user clicks on a button:

- (IBAction) selectSlide:(id) sender
{
 if(self.selectSlideView == nil)
 {
 SelectSlideViewController *viewController = [[SelectSlideViewController alloc]
           initWithNibName:@"SelectSlideViewController" bundle:[NSBundle mainBundle]];
  self.selectSlideView = viewController;
  [viewController release];
 }

 [self.navigationController pushViewController:self.selectSlideView animated:YES];
 self.selectSlideView.cmn = cmn;
 self.selectSlideView.title = cmn.name;
 self.selectSlideView.imageView.image = self.myImage5;
}

And the above code works, if for, example, I click on button 5, as it sets image5 to the view in the “SelectSlideViewController”.

However, I would like to have multiple buttons using the same “selectSlide” action – and to do that, I need to figure out which button was pressed, and then assign the correct image to the “SelectSlideViewController” from an array of images (or a series of if-else statements which is clunky).

• So my revised code is as follows, but it doesn’t work with the array – any thoughts?:

- (IBAction) selectSlide:(id) sender
{
 if(self.selectSlideView == nil)
 {
 SelectSlideViewController *viewController = [[SelectSlideViewController alloc]
             initWithNibName:@"SelectSlideViewController" bundle:[NSBundle mainBundle]];
  self.selectSlideView = viewController;
  [viewController release];
 }

 NSUInteger tmpInt = -1;
 tmpInt = [buttonArray indexOfObject:sender];

 [self.navigationController pushViewController:self.selectSlideView animated:YES];
 self.selectSlideView.cmn = cmn;
 self.selectSlideView.title = cmn.name;

 NSLog(@"The int was %d",tmpInt);
 NSLog(@"This is the image array size %d ",[imageArray count]); 

 If(tmpInt >-1 && tmpInt <9)
 {
  self.selectSlideView.imageView.image = [imageArray objectAtIndex:tmpInt];
 }
 /** this code works, but is a bit clunky:
 if(tmpInt == 0)
  self.selectSlideView.imageView.image = self.myImage1;
 else if (tmpInt == 1)
  self.selectSlideView.imageView.image = self.myImage2;
 else if (tmpInt == 2)
  self.selectSlideView.imageView.image = self.myImage3;
 else if (tmpInt == 3)
  self.selectSlideView.imageView.image = self.myImage4;
 else if (tmpInt == 4)
  self.selectSlideView.imageView.image = self.myImage5;
 else if (tmpInt == 5)
  self.selectSlideView.imageView.image = self.myImage6;
 else if (tmpInt == 6)
  self.selectSlideView.imageView.image = self.myImage7;
 else if (tmpInt == 7)
  self.selectSlideView.imageView.image = self.myImage8;
 else if (tmpInt == 8)
  self.selectSlideView.imageView.image = self.myImage9; 
 **/
}

I have definitely confirmed that the imageArray is of size 9, and that it is picking the correct index from the array, however the SelectSlideViewController doesn't display the image, if accessed from the array. It displays it if accessed using the clunky if-else statements.

A: 

You could try to load the images directly the first time, then cache afterwards. (I've excluded the caching code, and the scaling code, but you can add them after you get the image).

   If(tmpInt >-1 && tmpInt <9)
     {
      // Check if already cached
         self.selectSlideView.imageView.image = [self getButtonImages:tmpInt];
      // add scaling code here for smaller image

     }

In @implementation you can add:

 - (UIImage) getButtonImages:(NSInteger)index
    {   
        UIImage* myImage = [UIImage imageNamed:@"image%d.jpg", index];
        return myImage;
    }
Jordan
Thanks - I will try this and get back to you - seems like a neat way of doing it. I would like to understand where I am going wrong with the arrays though. I have done Java programming before, but this Objective-C stuff is slightly different so it can get a bit confusing...
trilithium
So I tried this, and it didn't work. Just so I understand the code - when this code is executed, if tmpInt = 1, is it looking for a file called myImage1, or is it looking for a variable called myImage1?Unfortunately I havent got detail on the exception thrown at this stage. Any thoughts?
trilithium
I didn't add the extension of course.
Jordan
Ahh, ok - understood. The problem is that the images (other than the default one) are not stored on the filesystem. They are in a database and are retrieved an assigned to the communicationView.myImageX (where 0 < X < 10 ). So is there a way of referencing the UIImage that the myImageX is referring to? This is why I was using an array, as I could assign the image from the relevant position in the array to the UIImageView.
trilithium
Didn't read your response close enough. Since the image is loaded from a database, this isn't going to work. Let me read through your code.
Jordan
Hi Jordan,Just to clarify, by caching, do you mean after retrieving the image from the database, I need to store it to the filesystem under imageX.jpg (perhaps in the "updateButtonImages" method), and then retrieve it from the filesystem in "getButtonImages"?
trilithium
Any thoughts as to why I can't access the UIImage in the imageArray? It seems strange that the UIImage in the relevant index in the array does not get assigned to "self.selectSlideView.imageView.image", but that it works when I assign it to the actual variables: myImage1, myImage2 ... myImage9
trilithium
My first thought was that the images in the array weren't being retained. But that doesn't seem to be the case. You sure imageArray is being retained?
Jordan
In my header file, i have the following entry: @property(nonatomic, retain) NSMutableArray * imageArray;Looks like my statement just above wasn't clear: UIImage myImage1 = [UIImage imageNamed:@"image1.jpg"]; [imageArray addObject:myImage1]; self.selectSlideView.imageView.image = myImage1; //this works self.selectSlideView.imageView.image = [imageArray objectAtIndex:1]; //doesn't work NSLog(@"This is the image array size %d ",[imageArray count]); //this outputs value of "9"So it could be that the imageArray is not being retained - but how do I ensure it is being retained?
trilithium
Where are you doing this in your code?imageArray=[[NSMutableArray alloc] init]
Jordan
Rather, this in your code, since you have it as a property. self.imageArray=[[NSMutableArray alloc] init]
Jordan
I allocated the imageArray in the rootController, before displaying page with the buttons. It turns out that the array method does work, however i observe the following behaviour:- I click on a button which should diplay a new view with a larger version of the image on the button- When I run the simulator, the first button press always results in an image not being displayed in the new view- However if I go back and click on the same button (or indeed another button), the correct image is displayedOnly the first button press (and i have tried different buttons, but same result)
trilithium
So to clarify:1) Using arrays seems to work apart from the first button click, using the code (self.selectSlideView.imageView.image = [imageArray objectAtIndex:tmpInt];)2) I assign "imageArray=[[NSMutableArray alloc] init]" in the rootViewController before displaying the view with the buttons
trilithium
A: 

I load the array in a method called - (void) updateButtonImages, which is called by the RootViewController when someone clicks on a table cell element:

- (void) updateButtonImages
{   
    if(self.myImage1 == NULL)
    {
     NSLog(@"No image");
     self.myImage1 = [UIImage imageNamed:@"image1.jpg"];
    }
    UIImage* mySmallImage1 = [myImage1 scaleToSize:CGSizeMake(88.0f,75.0f)];
    [imageBtn1 setImage:mySmallImage1 forState:UIControlStateNormal];
    [buttonArray addObject:imageBtn1]; 
    [imageArray addObject:myImage1];

    if(self.myImage2 == NULL)
    {
     self.myImage2 = [UIImage imageNamed:@"image1.jpg"];
    }
    UIImage* mySmallImage2 = [myImage2 scaleToSize:CGSizeMake(88.0f,75.0f)];
    [imageBtn2 setImage:mySmallImage2 forState:UIControlStateNormal];
    [buttonArray addObject:imageBtn2]; 
    [imageArray addObject:self.myImage2];

    /**do this for myImage2, myImage3 .... myImage9 **/
}

And it is called by the RootViewController in the following method:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    testMcgrathAppDelegate *appDelegate = (testMcgrathAppDelegate *)[[UIApplication sharedApplication] delegate];
    Communication *cmn = (Communication *)[appDelegate.communications objectAtIndex:indexPath.row];

    if(self.communicationView == nil)
    {
     CommunicationViewController *viewController = [[CommunicationViewController alloc]
                initWithNibName:@"CommunicationViewController" bundle:[NSBundle mainBundle]];
     self.communicationView = viewController;
     [viewController release];
    }
    [self.navigationController pushViewController:self.communicationView animated:YES];
    self.communicationView.cmn = cmn;
    self.communicationView.title = cmn.name;
    [self.communicationView.communicationMeetingName setText:cmn.name];
    [self.communicationView.communicationTopic setText:cmn.topic];
    [self.communicationView.communicationMeetingDate setText:cmn.meetingDate];
    [self.communicationView.communicationEducationalObjective setText:cmn.educationalObjective];
    [self.communicationView.communicationMeetingSponsor setText:cmn.meetingSponsor];
    [self.communicationView.needToKnow1 setText:cmn.needToKnow1.description];
    [self.communicationView.needToKnow2 setText:cmn.needToKnow2.description];
    [self.communicationView.needToKnow3 setText:cmn.needToKnow3.description];


    if(cmn.needToKnow1.image1 == NULL)
    {
     NSLog(@"In rootview, about to add a null image");
    }
    else
    {
     NSLog(@"In rootview, about to add a correct image");
    }

    self.communicationView.myImage1 = cmn.needToKnow1.image1;
    self.communicationView.myImage2 = cmn.needToKnow1.image2; 
    self.communicationView.myImage3 = cmn.needToKnow1.image3;
    self.communicationView.myImage4 = cmn.needToKnow2.image1;
    self.communicationView.myImage5 = cmn.needToKnow2.image2;
    self.communicationView.myImage6 = cmn.needToKnow2.image3;
    self.communicationView.myImage7 = cmn.needToKnow3.image1;
    self.communicationView.myImage8 = cmn.needToKnow3.image2; 
    self.communicationView.myImage9 = cmn.needToKnow3.image3;

    self.communicationView.buttonArray = [[NSMutableArray alloc] init];
    self.communicationView.imageArray = [[NSMutableArray alloc] init]; 

    [self.communicationView updateButtonImages];

}
trilithium
A: 

Here is the solution to the above problem (credited to "JSD" from www.iphonedevsdk.com):

Since selectSlideView.imageView was loaded from a nib the view wasn't loaded the first time through.

I had to include the following line of code before I assigned images from my Array to the view:

[selectSlideView view];
trilithium