I'm trying to use two buttons to cycle through an array of images. I'm using a buttonPressed function that identifies the tag of the left or right button, and should change the image that is displayed. Problem is, the function works perfectly when going right (incrementing the array), but if I try to go left (decrement) the program crashes. I've tried changing the values the variables are initialized to and the values used to cycle the arrays, but nothing seems to fix it. Any help is greatly appreciated.
.h
// FirstViewController.h
// TabTemplate
//
// Created by Paul R Woidke on 6/1/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
#include <stdlib.h>
@interface FirstViewController : UIViewController {
UIImageView* hat;
UIImageView* shirt;
UIImageView* pants;
UIImageView* shoes;
NSArray *hatArray;
NSArray *shirtArray;
NSArray *pantsArray;
NSArray *shoesArray;
}
@property (nonatomic, retain) IBOutlet UIImageView* hat;
@property (nonatomic, retain) IBOutlet UIImageView* shirt;
@property (nonatomic, retain) IBOutlet UIImageView* pants;
@property (nonatomic, retain) IBOutlet UIImageView* shoes;
@property (nonatomic, retain) IBOutlet NSArray* hatArray;
@property (nonatomic, retain) IBOutlet NSArray* shirtArray;
@property (nonatomic, retain) IBOutlet NSArray* pantsArray;
@property (nonatomic, retain) IBOutlet NSArray* shoesArray;
- (IBAction)buttonPressed:(id) sender;
- (IBAction)lockButtonPressed:(id) sender;
- (IBAction)weatherButtonPressed:(id) sender;
- (IBAction)randomizeButtonPressed:(id) sender;
@end
.m
// FirstViewController.m
// TabTemplate
//
// Created by Paul R Woidke on 6/1/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "FirstViewController.h"
@implementation FirstViewController
@synthesize hat;
@synthesize shirt;
@synthesize pants;
@synthesize shoes;
@synthesize hatArray;
@synthesize shirtArray;
@synthesize pantsArray;
@synthesize shoesArray;
NSInteger hatImage;
NSInteger shirtImage;
NSInteger pantsImage;
NSInteger shoesImage;
-(void) displayOutfit {
UIImage *hatImg = [hatArray objectAtIndex:hatImage];
[hat setImage:hatImg];
UIImage *shirtImg = [shirtArray objectAtIndex:shirtImage];
[shirt setImage:shirtImg];
UIImage *pantsImg = [pantsArray objectAtIndex:pantsImage];
[pants setImage:pantsImg];
UIImage *shoesImg = [shoesArray objectAtIndex:shoesImage];
[shoes setImage:shoesImg];
}
- (IBAction)buttonPressed:(id) sender {
NSInteger senderLabel = [sender tag];
switch (senderLabel) {
//Going right
case 2:
NSLog(@"Hat number: %d", hatImage);
NSLog(@"Hat Array count: %d", [hatArray count]);
if (hatImage == [hatArray count])
hatImage = 0;
UIImage *hatImg2 = [hatArray objectAtIndex:hatImage];
[hat setImage:hatImg2];
hatImage++;
break;
case 4:
if (shirtImage == [shirtArray count])
shirtImage = 0;
UIImage *shirtImg2 = [shirtArray objectAtIndex:shirtImage];
[shirt setImage:shirtImg2];
shirtImage++;
break;
case 6:
if (pantsImage == [pantsArray count])
pantsImage = 0;
UIImage *pantsImg = [pantsArray objectAtIndex:pantsImage];
[pants setImage:pantsImg];
pantsImage++;
break;
case 8:
if (shoesImage == [shoesArray count])
shoesImage = 0;
UIImage *shoesImg2 = [shoesArray objectAtIndex:shoesImage];
[shoes setImage:shoesImg2];
shoesImage++;
break;
//Going left
case 1:
if (hatImage == 0)
hatImage = 3;
UIImage *hatImg = [hatArray objectAtIndex:hatImage];
[hat setImage:hatImg];
hatImage--;
break;
case 3:
if ((shirtImage) == 0)
shirtImage = [shirtArray count];
UIImage *shirtImg = [shirtArray objectAtIndex:shirtImage];
[shirt setImage:shirtImg];
shirtImage--;
break;
case 5:
if ((pantsImage) == 0)
pantsImage = [pantsArray count];
UIImage *pantsImg2 = [pantsArray objectAtIndex:pantsImage];
[pants setImage:pantsImg2];
pantsImage--;
break;
case 7:
if ((shoesImage) == 0)
shoesImage = [shoesArray count];
UIImage *shoesImg = [shoesArray objectAtIndex:shoesImage];
[shoes setImage:shoesImg];
shoesImage--;
break;
}
}
- (IBAction)lockButtonPressed:(id) sender {
NSLog(@"Lock Button Pressed");
}
- (IBAction)weatherButtonPressed:(id) sender {
NSLog(@"Weather Button Pressed");
}
- (IBAction)randomizeButtonPressed:(id) sender {
NSLog(@"Randomize Button Pressed");
int randHat = rand() % [hatArray count];
int randShirt = rand() % [shirtArray count];
int randPants = rand() % [pantsArray count];
int randShoes = rand() % [shoesArray count];
NSLog(@"hat %d\nshirt %d\npants %d\nshoes %d", randHat, randShirt, randPants, randShoes);
hatImage = randHat;
shirtImage = randShirt;
pantsImage = randPants;
shoesImage = randShoes;
[self displayOutfit];
}
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
//Generate image arrays
hatArray = [[NSArray arrayWithObjects:
[UIImage imageNamed:@"h1.png"],
[UIImage imageNamed:@"h2.png"],
[UIImage imageNamed:@"h3.png"],
nil] retain];
shirtArray = [[NSArray arrayWithObjects:
[UIImage imageNamed:@"s1.png"],
[UIImage imageNamed:@"s2.png"],
[UIImage imageNamed:@"s3.png"],
[UIImage imageNamed:@"s4.png"],
[UIImage imageNamed:@"s5.png"],
[UIImage imageNamed:@"s6.png"],
nil] retain];
pantsArray = [[NSArray arrayWithObjects:
[UIImage imageNamed:@"p1.png"],
[UIImage imageNamed:@"p2.png"],
[UIImage imageNamed:@"p3.png"],
[UIImage imageNamed:@"p4.png"],
nil] retain];
shoesArray = [[NSArray arrayWithObjects:
[UIImage imageNamed:@"ss1.png"],
[UIImage imageNamed:@"ss2.png"],
[UIImage imageNamed:@"ss3.png"],
nil] retain];
hatImage = 0;
shirtImage = 0;
pantsImage = 0;
shoesImage = 0;
UIImage *hatImg = [hatArray objectAtIndex:hatImage];
[hat setImage:hatImg];
UIImage *shirtImg = [shirtArray objectAtIndex:shirtImage];
[shirt setImage:shirtImg];
UIImage *pantsImg = [pantsArray objectAtIndex:pantsImage];
[pants setImage:pantsImg];
UIImage *shoesImg = [shoesArray objectAtIndex:shoesImage];
[shoes setImage:shoesImg];
[super viewDidLoad];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.hat = nil;
self.shirt = nil;
self.pants = nil;
self.shoes = nil;
self.hatArray = nil;
self.shirtArray = nil;
self.pantsArray = nil;
self.shoesArray = nil;
}
- (void)dealloc {
[hat release];
[shirt release];
[pants release];
[shoes release];
[hatArray release];
[shirtArray release];
[pantsArray release];
[shoesArray release];
[super dealloc];
}
@end
Console output (displays array count and value of current image):
[Session started at 2011-06-16 16:30:50 -0400.]
2011-06-16 16:31:03.192 TabTemplate[2478:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 3 beyond bounds [0 .. 2]'
*** Call stack at first throw:
(
0 CoreFoundation 0x00db3be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f085c2 objc_exception_throw + 47
2 CoreFoundation 0x00da980c -[__NSArrayI objectAtIndex:] + 236
3 TabTemplate 0x000026c8 -[FirstViewController buttonPressed:] + 569
4 UIKit 0x002bca6e -[UIApplication sendAction:to:from:forEvent:] + 119
5 UIKit 0x0034b1b5 -[UIControl sendAction:to:forEvent:] + 67
6 UIKit 0x0034d647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
7 UIKit 0x0034c1f4 -[UIControl touchesEnded:withEvent:] + 458
8 UIKit 0x002e10d1 -[UIWindow _sendTouchesForEvent:] + 567
9 UIKit 0x002c237a -[UIApplication sendEvent:] + 447
10 UIKit 0x002c7732 _UIApplicationHandleEvent + 7576
11 GraphicsServices 0x016e9a36 PurpleEventCallback + 1550
12 CoreFoundation 0x00d95064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
13 CoreFoundation 0x00cf56f7 __CFRunLoopDoSource1 + 215
14 CoreFoundation 0x00cf2983 __CFRunLoopRun + 979
15 CoreFoundation 0x00cf2240 CFRunLoopRunSpecific + 208
16 CoreFoundation 0x00cf2161 CFRunLoopRunInMode + 97
17 GraphicsServices 0x016e8268 GSEventRunModal + 217
18 GraphicsServices 0x016e832d GSEventRun + 115
19 UIKit 0x002cb42e UIApplicationMain + 1160
20 TabTemplate 0x00002012 main + 84
21 TabTemplate 0x00001f92 start + 54
)
terminate called after throwing an instance of 'NSException'
[Session started at 2011-06-16 16:31:13 -0400.]
2011-06-16 16:31:15.966 TabTemplate[2481:207] Hat number: 0
2011-06-16 16:31:15.968 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:16.390 TabTemplate[2481:207] Hat number: 1
2011-06-16 16:31:16.391 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:16.790 TabTemplate[2481:207] Hat number: 2
2011-06-16 16:31:16.791 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:17.446 TabTemplate[2481:207] Hat number: 3
2011-06-16 16:31:17.447 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:17.902 TabTemplate[2481:207] Hat number: 1
2011-06-16 16:31:17.903 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:18.199 TabTemplate[2481:207] Hat number: 2
2011-06-16 16:31:18.199 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:18.526 TabTemplate[2481:207] Hat number: 3
2011-06-16 16:31:18.527 TabTemplate[2481:207] Hat Array count: 3
2011-06-16 16:31:20.503 TabTemplate[2481:207] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 3 beyond bounds [0 .. 2]'
*** Call stack at first throw:
(
0 CoreFoundation 0x00db3be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f085c2 objc_exception_throw + 47
2 CoreFoundation 0x00da980c -[__NSArrayI objectAtIndex:] + 236
3 TabTemplate 0x000026c8 -[FirstViewController buttonPressed:] + 569
4 UIKit 0x002bca6e -[UIApplication sendAction:to:from:forEvent:] + 119
5 UIKit 0x0034b1b5 -[UIControl sendAction:to:forEvent:] + 67
6 UIKit 0x0034d647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
7 UIKit 0x0034c1f4 -[UIControl touchesEnded:withEvent:] + 458
8 UIKit 0x002e10d1 -[UIWindow _sendTouchesForEvent:] + 567
9 UIKit 0x002c237a -[UIApplication sendEvent:] + 447
10 UIKit 0x002c7732 _UIApplicationHandleEvent + 7576
11 GraphicsServices 0x016e9a36 PurpleEventCallback + 1550
12 CoreFoundation 0x00d95064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
13 CoreFoundation 0x00cf56f7 __CFRunLoopDoSource1 + 215
14 CoreFoundation 0x00cf2983 __CFRunLoopRun + 979
15 CoreFoundation 0x00cf2240 CFRunLoopRunSpecific + 208
16 CoreFoundation 0x00cf2161 CFRunLoopRunInMode + 97
17 GraphicsServices 0x016e8268 GSEventRunModal + 217
18 GraphicsServices 0x016e832d GSEventRun + 115
19 UIKit 0x002cb42e UIApplicationMain + 1160
20 TabTemplate 0x00002012 main + 84
21 TabTemplate 0x00001f92 start + 54
)
terminate called after throwing an instance of 'NSException'
In your "going left" cases you're setting the array index out of bounds. For example:
if ((shirtImage) == 0)
shirtImage = [shirtArray count];
The last item in an array has the index [arrayObj count] - 1
.
In fact, you're setting the value of shirtImage anywhere in the range 1..arrayLength, where it should be in the range 0..arrayLength-1. I'd suggest you increment/decrement your index first, then check its bounds, then index into the array. For example:
case 2:
// increment the index
hatImage++;
// wrap around if you've gone beyond the bounds of the array
if (hatImage == [hatArray count])
hatImage = 0;
// Index into the array
[hat setImage:[hatArray objectAtIndex:hatImage]];
NSRangeException - that means you've overrun the bounds of an array.
An aside: You're declaring these as IBOutlet
properties. What are you hooking them up to?
@property (nonatomic, retain) IBOutlet NSArray* hatArray;
@property (nonatomic, retain) IBOutlet NSArray* shirtArray;
@property (nonatomic, retain) IBOutlet NSArray* pantsArray;
@property (nonatomic, retain) IBOutlet NSArray* shoesArray;
User contributions licensed under CC BY-SA 3.0