victor bill
victor bill

Reputation: 209

CollectionView and UISegmentedControl error

I have a little problem in my code, I use a CollectionView with segmentedControl but here when I press section 2 or 3 of segmetedControl and I scroll the CollectionView, I get this error

* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayI objectAtIndex:]: index 16 beyond bounds [0 .. 15]'

#define API_V3_CHANNEL_URL @"examples.json"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    [self fetchEntries];
    [self fetchEntriesWinner];
    [self fetchEntriesPhotos];

}

- (void)fetchEntries
{
    NSString *searchURL = [API_V3_CHANNEL_URL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSData *searchData = [NSData dataWithContentsOfURL:[NSURL URLWithString:searchURL]];
    NSDictionary *searchDict =[NSJSONSerialization JSONObjectWithData:searchData options:NSJSONReadingMutableContainers error:nil];
    //self.readArray = [searchDict objectForKey:@"CONTESTS"];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"status == %@", @"LIVE"];
    self.readArray = [[searchDict objectForKey:@"CONTESTS"] filteredArrayUsingPredicate:predicate];

    NSLog(@"%@", self.readArray);

}

- (void)fetchEntriesWinner
{
    NSString *searchURL = [API_V3_CHANNEL_URL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSData *searchData = [NSData dataWithContentsOfURL:[NSURL URLWithString:searchURL]];
    NSDictionary *searchDict =[NSJSONSerialization JSONObjectWithData:searchData options:NSJSONReadingMutableContainers error:nil];
    //self.readArray = [searchDict objectForKey:@"CONTESTS"];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"status == %@", @"ARCHIVED"];
    self.readArrayWinner = [[searchDict objectForKey:@"CONTESTS"] filteredArrayUsingPredicate:predicate];

    NSLog(@"winner array : %@", self.readArrayWinner);

}

- (void)fetchEntriesPhotos
{
    NSString *searchURL = [API_V3_CHANNEL_URL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSData *searchData = [NSData dataWithContentsOfURL:[NSURL URLWithString:searchURL]];
    NSDictionary *searchDict =[NSJSONSerialization JSONObjectWithData:searchData options:NSJSONReadingMutableContainers error:nil];
    //self.readArray = [searchDict objectForKey:@"CONTESTS"];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"status == %@", @"LIVE"];
    self.readArrayPhotos = [[searchDict objectForKey:@"CONTESTS"] filteredArrayUsingPredicate:predicate];

    NSLog(@"%@", self.readArray);

}

- (IBAction)segmentedControlAction:(id)sender
{
    [self.collectionView reloadData];

}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{

    switch (_segmentedControl.selectedSegmentIndex) {
        case 0:
            return [self.readArray count];
            break;

            case 1:
            return [self.readArrayWinner count];
            break;

            case 2:
            return [self.readArrayPhotos count];
            break;

        default:
            break;
    }

    return 0;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{

    static NSString *CellIdentifier = @"pictureCell";

    MSContestListCollectionViewCell *cell = (MSContestListCollectionViewCell *)[self.collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];

    NSDictionary *searchResult = [self.readArray objectAtIndex:indexPath.item];
    NSDictionary *searchResult2 = [self.readArrayWinner objectAtIndex:indexPath.item];
    NSDictionary *searchResult3 = [self.readArrayPhotos objectAtIndex:indexPath.item];

    cell.titleContest.adjustsFontSizeToFitWidth = YES;
    cell.titleContest.minimumScaleFactor = 0.5;

    cell.pictureImageView.layer.cornerRadius = 5;
    cell.pictureImageView.clipsToBounds = YES;

    cell.titleView.layer.cornerRadius = 5;
    cell.titleView.clipsToBounds = YES;

    switch (_segmentedControl.selectedSegmentIndex) {
        case 0: {
            NSString *stringImage = [searchResult objectForKey:@"featuredImage"];

            NSString *image = [NSString stringWithFormat:@"https://srv.mediaswapp.com/%@", stringImage];
            [cell.pictureImageView sd_setImageWithURL:[NSURL URLWithString:image]
                                     placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

            cell.titleContest.text = [searchResult objectForKey:@"description"];
            cell.statusContest.text = [searchResult objectForKey:@"status"];
            break;
        }
        case 1: {
            NSString *stringImage = [searchResult2 objectForKey:@"featuredImage"];

            NSString *image = [NSString stringWithFormat:@"https://srv.mediaswapp.com/%@", stringImage];
            [cell.pictureImageView sd_setImageWithURL:[NSURL URLWithString:image]
                                     placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

            cell.titleContest.text = [searchResult2 objectForKey:@"description"];
            cell.statusContest.text = [searchResult2 objectForKey:@"status"];
            break;
        }
        case 2: {
            NSString *stringImage = [searchResult3 objectForKey:@"featuredImage"];

            NSString *image = [NSString stringWithFormat:@"https://srv.mediaswapp.com/%@", stringImage];
            [cell.pictureImageView sd_setImageWithURL:[NSURL URLWithString:image]
                                     placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

            cell.titleContest.text = [searchResult3 objectForKey:@"description"];
            cell.statusContest.text = [searchResult3 objectForKey:@"status"];
            break;
        }

        default:
            break;
    }

    return cell;
}

@end

Upvotes: 0

Views: 72

Answers (2)

Dhaval Patel
Dhaval Patel

Reputation: 105

Array contain 16 object and you going to find objectAtIndex "16", it mean you finding 17th object in array which not available, so Terminating app with uncaught exception 'NSRangeException'.

Upvotes: 0

luk2302
luk2302

Reputation: 57134

You have to move the following three lines inside the switch case:

NSDictionary *searchResult = [self.readArray objectAtIndex:indexPath.item];
NSDictionary *searchResult2 = [self.readArrayWinner objectAtIndex:indexPath.item];
NSDictionary *searchResult3 = [self.readArrayPhotos objectAtIndex:indexPath.item];

It should be

switch (_segmentedControl.selectedSegmentIndex) {
    case 0: {
        NSDictionary *searchResult = [self.readArray objectAtIndex:indexPath.item];
        NSString *stringImage = [searchResult objectForKey:@"featuredImage"];

        NSString *image = [NSString stringWithFormat:@"https://srv.mediaswapp.com/%@", stringImage];
        [cell.pictureImageView sd_setImageWithURL:[NSURL URLWithString:image]
                                 placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

        cell.titleContest.text = [searchResult objectForKey:@"description"];
        cell.statusContest.text = [searchResult objectForKey:@"status"];
        break;
    }
    case 1: {
        NSDictionary *searchResult2 = [self.readArrayWinner objectAtIndex:indexPath.item];
        NSString *stringImage = [searchResult2 objectForKey:@"featuredImage"];

        NSString *image = [NSString stringWithFormat:@"https://srv.mediaswapp.com/%@", stringImage];
        [cell.pictureImageView sd_setImageWithURL:[NSURL URLWithString:image]
                                 placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

        cell.titleContest.text = [searchResult2 objectForKey:@"description"];
        cell.statusContest.text = [searchResult2 objectForKey:@"status"];
        break;
    }
    case 2: {
        NSDictionary *searchResult3 = [self.readArrayPhotos objectAtIndex:indexPath.item];
        NSString *stringImage = [searchResult3 objectForKey:@"featuredImage"];

        NSString *image = [NSString stringWithFormat:@"https://srv.mediaswapp.com/%@", stringImage];
        [cell.pictureImageView sd_setImageWithURL:[NSURL URLWithString:image]
                                 placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

        cell.titleContest.text = [searchResult3 objectForKey:@"description"];
        cell.statusContest.text = [searchResult3 objectForKey:@"status"];
        break;
    }

    default:
        break;
}

The reason is that when readArray contains 16 elements and you try to display the section for readArray you will also try to access the readArrayWinner at index 16 which might not present since that array is smaller.

Upvotes: 2

Related Questions