开发者

Defining an index for an image array in Objective C

I've been trying to figure out how to have a UIImageView with a next and previous button which when clicked will go to the next or previous image in the array. So far, here's what I have.

In my .h file I have declared:

IBOutlet UIImageView *imageView;
NSArray *imageArray;

And I also added:

-(IBAction) next;

In the .m file I have:

-(void) viewDidLoad;
{
    imageArray = [[NSArray arrayWithObjects: 
                [UIImage imageNamed:@"1.png"], 
                  [UIImage imageNamed:@"2.png"], 
                  nil] retain];
}

Now here is where I'm struggling. I have the IBAction defined as follows in my .m:

-(IBAction)next 
{
     if (currentImage + 1 == [imageArray count])
     {
         currentImage = 0;
     }
     UIImage *img = [imageArray objectAtIndex:currentImage];
     [imageView setImage:img]; 
     currentImage++;
}

My problem is that I do not know where to define the currentImage index integer or how to define it. Is it in the header? The implementation? And how exactly do I declare it?

To be h开发者_开发问答onest I'm not even 100% sure the code I currently have is right, although I think if I can define the index, it will work.

Any advice?


This is how I would do it. (I've changed the name of a few instance variables: currentImage sounds like it could be a pointer to an image (UIImage *) rather than just an integer value; adding Index to the end makes that more clear. It may be obvious now that it's an integer, but when you revisit this code (or other code you write) in a month, it may be less obvious; or maybe that's just me)...

MDSlideshowController.h:

#import <UIKit/UIKit.h>
@class MDBilboBaggins;

@interface MDSlideshowController : NSObject {
   IBOutlet UIImageView   *imageView;
   NSArray                *imageArray;
   NSUInteger             currentImageIndex;
   BOOL                   someOtherVariable;
   MDBilboBaggins         *bilboBaggins;
   // keep adding more instance variables as needed
}
- (IBAction)previous:(id)sender;
- (IBAction)next:(id)sender;
@end

MDSlideshowController.m:

#import "MDSlideshowController.h"
#import "MDBilboBaggins.h"
// you could perhaps define currentImageIndex here, but see notes below:
// NSUInteger currentImageIndex = 0;

@implementation MDSlideshowController
  // `currentImageIndex` is automatically initialized to 0 during init
  // `someOtherVariable` is automatically initialized to 0 (NO) during init
-(void) viewDidLoad
{
imageArray = [[NSArray arrayWithObjects: 
                [UIImage imageNamed:@"1.png"], 
                  [UIImage imageNamed:@"2.png"], 
                  nil] retain];
     [imageView setImage:[imageArray
                 objectAtIndex:currentImageIndex]];
}
- (IBAction)previous:(id)sender {
    if (currentImageIndex == 0) {
        currentImageIndex = [imageArray count] - 1;
    } else {
        currentImageIndex--;
    }
    [imageView setImage:[imageArray objectAtIndex:currentImageIndex]];
}
- (IBAction)next:(id)sender {
    if (currentImageIndex + 1 >= [imageArray count]) {
        currentImageIndex = 0;
    } else {
        currentImageIndex++;
    }
    [imageView setImage:[imageArray objectAtIndex:currentImageIndex]];
}
@end

Basically, you put instance variables right underneath the ones you've already defined. They can be of almost any type. You can use the types Cocoa Touch knows about, or classes you make yourself. In this example, I said that there was a special class named MDBilboBaggins by using the @class MDBilboBaggins statement. Then, I add the #import "MDBilboBaggins.h" part in the .m file: this can help speed up compile times.

As I mentioned in the comment, you could perhaps define the currentImageIndex variable inside the .m file, however, it would be a static variable that is common to, and shared, by all instances of the class. This can be useful in some situations, but create issues in others. For example, imagine we have 2 slideshow controllers, each with different images created and showing slides in 2 different windows. If they were modifying a shared currentImageIndex variable, they'd mess each other up if you would switch between them and start clicking Previous and Next indiscriminately. That's why in this case it might make more sense to just make it an instance variable by defining it other your other instance variables in the .h file.

[EDIT] Regarding the :(id)sender parameter: in this example, it wasn't used at all, I generally do it out of habit, since in some circumstances, it can save a lot of code, and simplify things dramatically. For example, say you had 9 different buttons and you wanted each button to load a specific image (or perform a specific operation). Now, you could define 9 separate methods like - (IBAction)button1Clicked;, or you could do it the easy way and just define a single - (IBAction)loadImage:(id)sender method. In your nib file, you would give each button a different tag (an NSInteger value), like 1 − 9. Then in your single method you could do this:

- (IBAction)loadImage:(id)sender {
   NSInteger buttonTag = [(NSButton *)sender tag];
   [imageView setImage:[UIImage imageNamed:
       [NSString stringWithFormat:@"image%ld.png",buttonTag]]];
}

In this case, sender is the object that sends the message, which would be the button that was clicked on. Though admittedly a contrived example, by providing that one additional parameter, I probably saved 100 lines of needless code and complexity of having 9 separate methods.

[EDIT #2] Replaced the one pseudo-coded (written in Safari) next: method with actual code from one of my apps that I know works.

Hope this helps...


you need to declare the currentindex in the header like so:

NSInteger currentImage;

This way the value is saved throughout the views lifetime

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜