Search code examples
iphoneiosimageuipickerview

UIPickerView disappearing images inside picker


I'm trying to build "slot machine" game using UIPickerView. I populate it using UIImageView. Problem is that, random images in picker view disappear after every spin, and randomly shows again. It happens on device with ios 5.1.1, but on device with ios4.2.1 and simulator it works perfectly. Right now I'm using CircularPickerView but before I used UIPickerView and problem was the same. Here's screenshot: http://axgrzesiek.w.interii.pl/licznik.PNG

GraViewController.h:

#import <UIKit/UIKit.h>

#import "CircularPickerView.h"
@interface GraViewController : UIViewController
    <UIPickerViewDataSource, UIPickerViewDelegate> {
        CircularPickerView *picker;
        UILabel *winLabel;
        NSArray *column1;
        NSArray *column2;
        NSArray *column3;


}
@property(nonatomic, retain) IBOutlet CircularPickerView *picker;
@property(nonatomic, retain) IBOutlet UILabel *winLabel;
@property(nonatomic, retain) NSArray *column1;
@property(nonatomic, retain) NSArray *column2;
@property(nonatomic, retain) NSArray *column3;
-(IBAction)spin;

@end

GraViewController.m:

- (IBAction)spin { 
    BOOL win = NO;
    int numInRow = 1; 
    int lastVal = -1; 
    for (int i = 0; i < 3; i++) {
        int newValue = arc4random() % [self.column1 count];
        if (newValue == lastVal) 
            numInRow++;
        else
            numInRow = 1;

        lastVal = newValue; 
        //if (newValue < [self.column1 count] || newValue >= (2 * [self.column1 count]) ) {
            //newValue = newValue % [self.column1 count];
            //newValue += [self.column1 count];
        [self.picker selectRow:newValue inComponent:i animated:YES];


        //}
        NSLog(@"kol:%d %d",i, newValue);
        //[picker reloadComponent:i]; 
        if (numInRow >= 3)
            win = YES;
    } 
    if (win)
        winLabel.text = @"WIN!"; 
    else 
        winLabel.text = @"";

    //[picker reloadAllComponents];
    //[self performSelector:@selector(moveIntoPosition) withObject:nil afterDelay:0.5f];



- (void)viewDidLoad { 

    NSString  *title=@"Gra";
    [self setTitle:title];

    UIImage *seven = [UIImage imageNamed:@"jeden.png"]; 
    UIImage *bar = [UIImage imageNamed:@"dwa.png"]; 
    UIImage *crown = [UIImage imageNamed:@"trzy.png"]; 
    UIImage *cherry = [UIImage imageNamed:@"cztery.png"]; 
    UIImage *lemon = [UIImage imageNamed:@"piec.png"]; 
    UIImage *apple = [UIImage imageNamed:@"szesc.png"];
    for (int i = 1; i <= 3; i++) { 
        UIImageView *sevenView = [[UIImageView alloc] initWithImage:seven]; 
        UIImageView *barView = [[UIImageView alloc] initWithImage:bar]; 
        UIImageView *crownView = [[UIImageView alloc] initWithImage:crown]; 
        UIImageView *cherryView = [[UIImageView alloc] initWithImage:cherry]; 
        UIImageView *lemonView = [[UIImageView alloc] initWithImage:lemon];
        UIImageView *appleView = [[UIImageView alloc] initWithImage:apple]; 
        NSArray *imageViewArray = [[NSArray alloc] initWithObjects:
                                    sevenView, barView, crownView, cherryView, lemonView, appleView, nil];
        NSString *fieldName = [[NSString alloc] initWithFormat:@"column%d", i];
        [self setValue:imageViewArray forKey:fieldName];
        //column1=[[NSArray alloc]initWithArray:imageViewArray];
        //column2=[[NSArray alloc]initWithArray:imageViewArray];
        //column3=[[NSArray alloc]initWithArray:imageViewArray];
        [fieldName release];
        [imageViewArray release];
        [sevenView release]; 
        [barView release]; 
        [crownView release]; 
        [cherryView release]; 
        [lemonView release]; 
        [appleView release];
        //[picker selectRow: [self.column1 count] * (48 / 2) inComponent:i-1 animated:NO];
    }


}


- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {

    NSString *arrayName = [[NSString alloc] initWithFormat:@"column%d", component+1];
    NSArray *array = [self valueForKey:arrayName];
    [arrayName release];
    return [array objectAtIndex:row];

}

Solution

  • I think the problem might be in the way you're reusing views for your picker - you should not cache UIImageViews yourself (probably UIPickerView tries to use the same UIImageView in multiple places, so one of those places stays unoccupied).

    Correct way will be to store UIImage instances and fill UIImageView that may be cached by picker. Boilerplate code (not tested):

    - (void) viewDidLoad{
     ...
     Here cache UIImages, not UIImageViews
     ...
    }
    
    - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
    
        NSString *arrayName = [[NSString alloc] initWithFormat:@"column%d", component+1];
        NSArray *array = [self valueForKey:arrayName];
        [arrayName release];
        UIImage *image = [array objectAtIndex:row];
    
        if (!view){
           view = [[[UIImageView alloc] init] autorelease];
        }
        [(UIImageView*)view setImage:image];
        return view;
    }