0

So in my table view, I have an array called dataArray and it's getting its objects from a server using JSON. I added a button to each cell and when the button is clicked the cell is supposed to move to another section/ or another array called followedArray to be more exact. Now the cells are transferring to the other section but after moving 6 cells I get an error that saids this. All arrays are NSMutableArray. Also, I'm new to iOS so try to work with me, thank you.

2016-10-26 17:27:19.569 CustomCellApp[3212:198103] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 6 beyond bounds [0 .. 4]'

---------------------

Side note, I can make a separate error post but I have another issue, the images displaying in the cells are being changed to other images when switching sections, using the pod SDWebImage.

---------------------

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

if (!isFiltered) {

    if (section == 0) {
        return [followedArray count];
    }
    else if (section == 1) {
        return [dataArray count];
    }
 }
return [filteredArray count];

}

---------------------

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) {
    return @"Followed Data";
}
else {
    return @"All Data";
 }
}

---------------------

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
    cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

// Configuring the cell
Data * dataObject;
if (!isFiltered) {

    if (indexPath.section == 0) {
        dataObject = [followedArray objectAtIndex:indexPath.row];
    }
    else if (indexPath.section == 1) {
        dataObject = [dataArray objectAtIndex:indexPath.row];
    }
}
else {
    dataObject = [filteredArray objectAtIndex:indexPath.row];
}

// Loading Images
if (!isFiltered) {
  // Exception Breakpoint Here
    NSURL * imgURL = [[dataArray objectAtIndex:indexPath.row] valueForKey:@"dataURL"];
    [cell.myImageView setContentMode:UIViewContentModeScaleAspectFit];
    [cell.myImageView sd_setImageWithURL:imgURL placeholderImage:[UIImage imageNamed:@"no-image.png"] options:SDWebImageRefreshCached];
}else{
    NSURL * imgURL = [[filteredArray objectAtIndex:indexPath.row] valueForKey:@"dataURL"];
    [cell.myImageView setContentMode:UIViewContentModeScaleAspectFit];
    [cell.myImageView sd_setImageWithURL:imgURL placeholderImage:[UIImage imageNamed:@"no-image.png"] options:SDWebImageRefreshCached];
}

// Loading Follow Button
cell.followButton.tag = indexPath.row;
[cell.followButton addTarget:self action:@selector(followButtonClick:) forControlEvents:UIControlEventTouchUpInside];
cell.followButton.hidden = NO;

 return cell;
}

---------------------

-(void)followButtonClick:(UIButton *)sender {

// Adding row to tag
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.myTableView];
NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:buttonPosition];

// Creating an action per tag
if (indexPath != nil)
{

    // Change Follow to Following
    [sender setImage:[UIImage imageNamed:@"follow.png"] forState:UIControlStateNormal];
    cell.followButton.hidden = YES;
    cell.followedButton.hidden = NO;


    // ----- ERROR BEGINS HERE ----- //
    [self.myTableView beginUpdates];

    // ----- Inserting Cell to Section 0 ----- *CAUSING PROBLEMS*
      // Exception Breakpoint Here
    [followedArray addObject:[dataArray objectAtIndex:indexPath.row]];
    [myTableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:followedArray.count-1 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];

    NSLog(@"indexPath.row = %ld", (long)indexPath.row);

    // ----- Removing Cell from Section 1 ----- *WORKING*
    [dataArray removeObjectAtIndex:indexPath.row];
    NSInteger rowToRemove = indexPath.row;
    [self.myTableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObjects:[NSIndexPath indexPathForRow:rowToRemove inSection:1], nil] withRowAnimation:YES];

    NSLog(@"Array =%@",followedArray);

    [self.myTableView endUpdates];
    // ----- ERROR ENDS HERE ----- //
 }
}

---------------------

WokerHead
  • 947
  • 2
  • 15
  • 46
  • why you are get the position of user click to get the cell, actually the cells in tableview are reused so if i clicked on cell number 4 maybe it will be the same position for cell number 8, so what you are expecting the indexPath to be ? You must to implement the button action inside the cell it self and make delegate when ever he clicked the button to get the right index path – Ali Omari Oct 26 '16 at 22:11
  • @AliOmari Is that what can be causing the error? What should I do to fix it? – WokerHead Oct 26 '16 at 22:14
  • Maybe that's not the reason but you are doing it in wrong way. so let's fix this first and move on to the next step. You must to add the action of the button inside the cell and pass the view controller as delegate for this cell so you can call the view controller when the button is pressed. – Ali Omari Oct 26 '16 at 22:15
  • @AliOmari the technique of using the `indexPathForRowAtPoint` will work, since a button can only be clicked if it is on screen, and if it is on screen reuse can't be an issue. I agree that a delegate pattern is cleaner, but it isn't the problem here. – Paulw11 Oct 26 '16 at 22:30
  • @BroSimple which actual line does the array bounds exception occur on? Set an exception breakpoint. – Paulw11 Oct 26 '16 at 22:31
  • @Paulw11 thanks for giving me this information :) But i think the problem is that he adding an object from array which he removes after a line [followedArray addObject:[dataArray objectAtIndex:indexPath.row]]; [dataArray removeObjectAtIndex:indexPath.row]; I think that what causes the problem, because he added an object that he removes it. – Ali Omari Oct 26 '16 at 22:36
  • @Paulw11I set an exception breakpoint, it broke in this line in cellForRowAtIndexPath, in // Loading Images. " NSURL * imgURL = [[dataArray objectAtIndex:indexPath.row] valueForKey:@"dataURL"]; ". Not in the else but in the if. – WokerHead Oct 26 '16 at 23:23
  • @Paulw11and after clicking random cells, it broke here now [followedArray addObject:[gamesArray objectAtIndex:indexPath.row]]; inside Follow Button – WokerHead Oct 26 '16 at 23:27
  • @AliOmari what do you think I should do? you said add the action of button inside the custom cell class? – WokerHead Oct 27 '16 at 00:44
  • @BroSimple this step for clean code, but the problem i think because you are adding an object that you are removing after. Remember that Objective c is pointers. – Ali Omari Oct 27 '16 at 06:56
  • @AliOmari thats a good point, what do you recommend? – WokerHead Oct 27 '16 at 13:09
  • @BroSimple can you upload your code on github, i think i'll find the solution quickly. – Ali Omari Oct 27 '16 at 13:21
  • @BroSimple I'll get back to as soon as possible – Ali Omari Oct 27 '16 at 19:36
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126866/discussion-between-ali-omari-and-brosimple). – Ali Omari Oct 27 '16 at 20:38
  • Post the answer what make the issue fixed . – Vinodh Oct 28 '16 at 13:08

1 Answers1

0

This is what helped me fix the errors I was having. Credits to @AliOmari for helping me out.

In cellForRowAtIndexPath

// Configuring the cell
Data * dataObject;
if (!isFiltered) {

    if (indexPath.section == 0) {
        dataObject = [followedArray objectAtIndex:indexPath.row];
        [cell populateCell:dataObject isFollowed:YES indexPath:indexPath parentView:self];
    }
    else if (indexPath.section == 1) {
        dataObject = [dataArray objectAtIndex:indexPath.row];
        [cell populateCell:dataObject isFollowed:NO indexPath:indexPath parentView:self];
    }
}
else {
    dataObject = [filteredArray objectAtIndex:indexPath.row];
    [cell populateCell:dataObject isFollowed:NO indexPath:indexPath parentView:self];
}
return cell;

Inside my Button

    [self.myTableView beginUpdates];

    // ----- Inserting Cell to Section 0 -----
    [followedArray insertObject:[dataArray objectAtIndex:indexPath.row] atIndex:0];
    [myTableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
    //NSLog(@"indexPath.row = %ld", (long)indexPath.row);

    // ----- Removing Cell from Section 1 -----
    [dataArray removeObjectAtIndex:indexPath.row];
    NSInteger rowToRemove = indexPath.row;
    [self.myTableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObjects:[NSIndexPath indexPathForRow:rowToRemove inSection:1], nil] withRowAnimation:YES];
    //NSLog(@"Array =%@",followedArray);

    [self.myTableView endUpdates];
WokerHead
  • 947
  • 2
  • 15
  • 46