tableView添加/删除第二部分objective-c

时间:2014-01-12 19:26:48

标签: ios objective-c uitableview

我的tableview(iOS)中有两个部分,第一部分是“收藏夹”行。如果选择accessoryView,它应该将“objects”数组中的选定对象添加到/从“favs”数组中删除,具体取决于该对象是否已存在于该部分中。

我编写的方法几乎可以正常工作,但是当我添加第二行或相同以删除收藏夹时,应用程序崩溃时出现此错误: Terminating app due to uncaught exception NSRangeException', reason: *** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0] 问题是相应数组中对象的索引不一样,所以我无法弄清楚如何正常工作。

以下是一些代码:

-(void)addToFavs:(id)sender{
    UITapGestureRecognizer *gesture = (UITapGestureRecognizer *) sender;
    NSLog(@"Tag = %d", gesture.view.tag);
    //if favorite section is empty
    if ([self.favs isEqualToArray:[@[]mutableCopy]]) {
        NSLog(@"adding favorite");
        [self.favs addObject:[self.objects objectAtIndex:gesture.view.tag]];
        [self.subtitlesFavs addObject:[self.subtitles objectAtIndex:gesture.view.tag]];
        [self.iconsFavs addObject:[self.icons objectAtIndex:gesture.view.tag]];
    }
    //if selected row already exist in favorites array <--HERE IS THE PROBLEM (I THINK)
    else if([[self.objects objectAtIndex:gesture.view.tag] isEqualToString:[self.favs objectAtIndex:gesture.view.tag]]){
        NSLog(@"removing favorite");
        [self.favs removeObjectAtIndex:gesture.view.tag];
        [self.subtitlesFavs removeObjectAtIndex:gesture.view.tag];
        [self.iconsFavs removeObjectAtIndex:gesture.view.tag];
    }else{
        NSLog(@"adding favorite");
        [self.favs addObject:[self.objects objectAtIndex:gesture.view.tag]];
        [self.subtitlesFavs addObject:[self.subtitles objectAtIndex:gesture.view.tag]];
        [self.iconsFavs addObject:[self.icons objectAtIndex:gesture.view.tag]];
    }
    [self.tableView reloadData];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // left image
    UIImageView *image=[[UIImageView alloc] initWithFrame:CGRectMake(7, 7, 30, 30)];
    [image.layer setCornerRadius:image.frame.size.width/2];
    [image setClipsToBounds:YES];
    if(indexPath.section==0){
        image.image=[UIImage imageNamed:[self.iconsFavs objectAtIndex:indexPath.row]];
    }else{
    image.image=[UIImage imageNamed:[self.icons objectAtIndex:indexPath.row]];
    }

    //fav image
    UIImageView *fav = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"favorites.png"]];
    [fav setFrame:CGRectMake(0, 0, 25, 25)];
    [fav setClipsToBounds:YES];
    if(!indexPath.section==0) {
        fav.image=[UIImage imageNamed:@"unfavorites"];
    }

    //cell
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell){
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        cell.textLabel.text=self.objects[indexPath.row];
        cell.detailTextLabel.text =self.subtitles[indexPath.row];
        [cell.contentView addSubview:image];
        cell.accessoryView = fav;

        //Favorites
        cell.accessoryView.userInteractionEnabled = YES;
        cell.accessoryView.tag = indexPath.row;
        UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(addToFavs:)];
        tapped.numberOfTapsRequired = 1;
        [cell.accessoryView addGestureRecognizer:tapped];

        //favorites section contents
        if (indexPath.section == 0)
        {
            cell.textLabel.text=self.favs[indexPath.row];
            [cell.contentView addSubview:image];
            cell.detailTextLabel.text =self.subtitlesFavs[indexPath.row];
        }
    }
    return cell;
}

更新1

我在if条件中使用“isEqualToString”编辑了我的代码,但它仍无法删除它们......

2 个答案:

答案 0 :(得分:1)

这是解决方案。将所有内容移至accessoryButoonTappedForRowWithIndexPath并有四种不同的案例就可以了。另外,请确保在数组中没有相同的字符串,否则将删除所有字符串,您将收到索引错误。

-(void)addToFavs:(id)sender event:(id)event {
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
    if(indexPath!=nil){
        [self tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath];
    }
}

- (void)tableView:(UITableView *)tableView  accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{

    if ([self.favs count]==0) {
        NSLog(@"adding first favorite %@",[self.objects objectAtIndex:indexPath.row]);
        [self.favs addObject:[self.objects objectAtIndex:indexPath.row]];
        [self.subtitlesFavs addObject:[self.subtitles objectAtIndex:indexPath.row]];
        [self.iconsFavs addObject:[self.icons objectAtIndex:indexPath.row]];

    }else if (indexPath.section==0){
        NSLog(@"removing favorite %@",[self.favs objectAtIndex:indexPath.row]);
        [self.favs removeObjectAtIndex:indexPath.row];
        [self.subtitlesFavs removeObjectAtIndex:indexPath.row];
        [self.iconsFavs removeObjectAtIndex:indexPath.row];

    }else if(indexPath.section==1 && [self.favs containsObject:[self.objects objectAtIndex:indexPath.row]]){
        NSLog(@"removing favorite %@",[self.objects objectAtIndex:indexPath.row]);
        [self.favs removeObject:[self.objects objectAtIndex:indexPath.row]];
        [self.subtitlesFavs removeObject:[self.subtitles objectAtIndex:indexPath.row]];
        [self.iconsFavs removeObject:[self.icons objectAtIndex:indexPath.row]];

    }else{
         NSLog(@"adding favorite %@",[self.objects objectAtIndex:indexPath.row]);
        [self.favs addObject:[self.objects objectAtIndex:indexPath.row]];
        [self.subtitlesFavs addObject:[self.subtitles objectAtIndex:indexPath.row]];
        [self.iconsFavs addObject:[self.icons objectAtIndex:indexPath.row]];
    }
    [tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
}

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



    //cell
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell){
        // left image
        UIImageView *image=[[UIImageView alloc] initWithFrame:CGRectMake(7, 7, 30, 30)];
        [image.layer setCornerRadius:image.frame.size.width/2];
        [image setClipsToBounds:YES];
        [image.layer setBorderColor:[UIColor lightGrayColor].CGColor];
        [image.layer setBorderWidth:0.3f];

        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        cell.detailTextLabel.textColor=[UIColor lightGrayColor];
        cell.textLabel.text=self.objects[indexPath.row];
        cell.detailTextLabel.text =self.subtitles[indexPath.row];
        [cell.contentView addSubview:image];

        if(indexPath.section==0){
            image.image=[UIImage imageNamed:[self.iconsFavs objectAtIndex:indexPath.row]];
            cell.textLabel.text=self.favs[indexPath.row];
            cell.detailTextLabel.text =self.subtitlesFavs[indexPath.row];
        }else{
            image.image=[UIImage imageNamed:[self.icons objectAtIndex:indexPath.row]];
        }
        //separetor
        [self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 45, 0, 0)];
        //favorites image button
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        CGRect frame = CGRectMake(0.0, 0.0, 25, 25);
        button.frame = frame;
        button.showsTouchWhenHighlighted = YES;
        [button setImage:[UIImage imageNamed:@"unfavorites.png"] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:@"favorites.png"] forState:UIControlStateSelected];
        [button addTarget:self action:@selector(addToFavs:event:)  forControlEvents:UIControlEventTouchUpInside];
        button.backgroundColor = [UIColor clearColor];
        cell.accessoryView = button;

    }
    return cell;
}

答案 1 :(得分:1)

与您所拥有的完全相似,但无论如何都要尝试:

这是-cellForRowAtIndexPath:方法 -

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle 
                                      reuseIdentifier:CellIdentifier];
    }

    cell.detailTextLabel.textColor = [UIColor lightGrayColor];
    //following commented line not needed
    //cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    // left image
    UIImageView *image = [[UIImageView alloc] init];
    [image setFrame:CGRectMake(7, 7, 30, 30)];
    [image.layer setCornerRadius:image.frame.size.width/2];
    [image setClipsToBounds:YES];
    [image.layer setBorderColor:[UIColor lightGrayColor].CGColor];
    [image.layer setBorderWidth:0.3f];
    [cell.contentView addSubview:image];

    //favorites image button
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setFrame:CGRectMake(0, 0, 25, 25)];
    [button setBackgroundColor:[UIColor clearColor]];
    [button setImage:[UIImage imageNamed:@"unfavorites.png"] forState:UIControlStateNormal];
    [button setImage:[UIImage imageNamed:@"favorites.png"] forState:UIControlStateSelected];
    [button setTag:100];  //tag needed later
    [button addTarget:self action:@selector(addToFavs:event:) forControlEvents:UIControlEventTouchUpInside];
    [button setShowsTouchWhenHighlighted:YES];
    [cell setAccessoryView:button];

    switch(indexPath.section) {
        case 0: { //is first section (favourite)
            image.image = [UIImage imageNamed: self.iconsFavs[indexPath.row]];
            cell.textLabel.text = self.favs[indexPath.row];
            cell.detailTextLabel.text = self.subtitlesFavs[indexPath.row];
            [button setSelected:YES];
        }
        break;
        case 1: { //is second section (all clubs)
            image.image = [UIImage imageNamed: self.icons[indexPath.row]];
            cell.textLabel.text = self.objects[indexPath.row];
            cell.detailTextLabel.text = self.subtitles[indexPath.row];

            //change state of button (thereby change button image)
            if([self.favs containsObject: self.objects[indexPath.row]]) {
                [button setSelected:YES];
            } else {
                [button setSelected:NO];
            }
        }
        break;
    }

    //separator -- do the following on viewDidLoad instead
    //[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 45, 0, 0)];

    return cell;
}

这是-addToFavs:event:方法 -

//No need for `-accessoryButtonTappedForRowWithIndexPath:` method
//it can be done in your following `-addToFavs:event:` method alone:
-(void)addToFavs:(id)sender event:(id)event
{
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:currentTouchPosition];

    switch(indexPath.section) {
        case 0: { //is first section (favourite)
            //remove from favourites

            //get indexPath for appropraite row in second section
            NSUInteger i_indexOfFavInMain = [self.objects indexOfObject:self.favs [indexPath.row]];
            NSIndexPath *indexOfFavInMain = [NSIndexPath indexPathForItem:i_indexOfFavInMain inSection:1];

            [self.favs removeObjectAtIndex:indexPath.row];
            [self.subtitlesFavs removeObjectAtIndex:indexPath.row];
            [self.iconsFavs removeObjectAtIndex:indexPath.row];

            //handle second section button (for the appropriate row)
            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexOfFavInMain];
            UIButton *btnTemp = (UIButton *)[cell viewWithTag:100];
            [btnTemp setSelected:NO];

            //reload first section
            [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
        }
        break;

        case 1: { //is second section (all clubs)
            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
            UIButton *btnTemp = (UIButton *)[cell viewWithTag:100];

            if([self.favs containsObject:self.objects[indexPath.row]]) {
                //remove from favourites
                [self.favs removeObject:self.objects[indexPath.row]];
                [self.subtitlesFavs removeObject:self.subtitles[indexPath.row]];
                [self.iconsFavs removeObject:self.icons[indexPath.row]];

                [btnTemp setSelected:NO];
            } else {
                //add to favourites
                [self.favs addObject: self.objects[indexPath.row]];
                [self.subtitlesFavs addObject: self.subtitles[indexPath.row]];
                [self.iconsFavs addObject: self.icons[indexPath.row]];

                [btnTemp setSelected:YES];
            }
            [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
        }
        break;
    }
}