在canEditRowAtIndexPath上返回NO,但如果滚动则可以编辑

时间:2013-10-17 03:58:05

标签: objective-c cocoa-touch uitableview

所以我一直在寻找这个有趣的问题的答案,但我没有太多运气。基本上我在初始应用程序启动时预装了一个UITableView,其中包含一些使用CoreData的对象,以及用户添加更多内容的能力。

我允许删除表中的单元格,除了我初始预加载的项目。因此,我在canEditRowAtIndexPath方法中执行检查,如果所选项目是这些预先加载的项目之一,则返回NO。一切都很好,直到我向下滚动足够远的一个项目在屏幕外,然后当它快照回来不应该编辑的项目时,现在可以编辑。

我对iOS开发很新,所以我希望这是一个相当业余的问题 - 但我似乎无法找到答案。

感谢任何帮助。

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
 {
     DataLayer *dl = [DataLayer alloc];

     // Get all items from Favorites
     NSArray *results = [dl FetchAll:@"Favorites"];

     // Get currently selected cell properties
     FavoritesTableCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
     Favorites *fav = [Favorites alloc];
     NSMutableArray *genItems = [[NSMutableArray alloc] init];

     // Get only records that are default app items
     for(int a = 0; a < [results count]; a++){
         fav = [results objectAtIndex:a];

         if ([fav.generic isEqualToNumber:[NSNumber numberWithInt:1]]) {
             [genItems addObject:fav];
         }
     }

     // Loop through default items to determine if editable
     for (int i = 0; i < [genItems count]; i++) {
         fav = [genItems objectAtIndex:i];

         if ([fav.title isEqualToString:[selectedCell.nameLabel text]]) {
             return NO;
         }
     }
     return YES;
 }

1 个答案:

答案 0 :(得分:2)

问题的根源在于此方法基于表格视图单元格(selectedCell)的内容而不是模型的答案。

表视图重用单元格。当它们从视图中滚动时,出现的“新”单元格实际上是在表格另一侧消失的同一对象。因此,selectedCell不适合应该放​​入模型的问题。

代码需要像这样构建:

您的模型是一个NSMutableArray,它以您添加的几个项目开头。您需要知道哪些项目是原件,而不是要删除:

@property (nonatomic, strong) NSMutableArray *favorites;
@property (nonatomic, assign) NSMutableArray *genericFavorites;

// at init, imagine these strings are your preloaded core data

[self.genericFavorites addObject:@"generic favorite object a"];
[self.genericFavorites addObject:@"generic favorite object b"];
[self.favorites addItemsFromArray:self.genericFavorites];

您将self.favorites用作模型,即当表格视图询问numberOfRowsInSection时,您将回答self.favorites.count。在cellForRowAtIndexPath中,您将在self.favorites[indexPath.row]中查找该项目,并使用该对象中的数据配置该单元格。 self.genericFavorites只是帮助您记住哪些对象是原创的,而不是由用户添加。

如果订单仍然固定,那么你的canEditRow逻辑很简单:

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
    return indexPath.row >= self.genericFavorites.count;
}

但是,如果你的代码暗示,用户可以重新排序这些项目,那么你的canEditRow还有更多的工作要做,但它可以在不参考表格单元格的情况下完成这项工作(正如我所指出的那样,它是不可靠的):

// get the object at indexPath.row from our model.  Answer NO if that object was preloaded
// from the app (if genericFavorites containsObject:), YES otherwise

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath

    Favorite *favorite = self.favorites[indexPath.row];   // this is your model after user has edited, reordered, etc
    return ![self.genericFavorites containsObject:favorite];
}