在 NSMutableArray 之间移动 objects 时出错
Error when moving objects between NSMutableArray
在我的 iOS 应用程序中,我有一个 table 视图,它有 2 个部分/2 个数组。我正在尝试将一个 object 从一个 array/section 移动到另一个 array/section。现在第 0 节称为 followedArray,第 1 节称为 dataArray,dataArray 存储构成每个单元格的所有数据。因此,当用户单击我设置的名为 Follow 的按钮时,它应该获取该单元格并将其从 dataArray/Section 1 中删除并将其插入到 followedArray/Section 0 中。但是当我尝试这样做时,我得到一个错误这么说。
错误信息
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3599.6/UITableView.m:1396
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update'
代码:
TableView
- (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 Button
cell.followButton.tag = indexPath.row;
[cell.followButton addTarget:self action:@selector(followButtonClick:) forControlEvents:UIControlEventTouchUpInside];
cell.followButton.hidden = NO;
return cell;
}
小节Headers
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) {
return @"Followed Data";
}
else {
return @"All Data";
}
}
行数
- (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];
}
---------------------------------------- --------------
--这是动作发生的地方--
---------------------------------------- --------------
关注按钮
-(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)
{
NSLog(@"Current Row = %@", indexPath);
// ----- ERROR HERE -----
[self.myTableView beginUpdates];
// ----- Inserting Cell to Section 0 ----- *NOT WORKING*
[followedArray insertObject:[dataArray objectAtIndex:indexPath.row] atIndex:indexPath.row];
NSInteger rowToAdd = indexPath.row;
[self.myTableView insertRowsAtIndexPaths:[NSMutableArray arrayWithObjects:[NSIndexPath indexPathForRow:rowToAdd inSection:0], nil] withRowAnimation:YES];
// ----- 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];
[self.myTableView endUpdates];
}
}
这可能是因为您正在使用 convertPoint 获取所单击单元格的 indexPath。尝试在您的 CustomCell 中创建一个协议并在您的 CustomCell 中实现您的 followButtonClick 并使用委托在您的控制器中使用您的 CustomCell 对象获取回调并使用该对象获取 indexPath。请参考以下代码。
你的CustomCell.h
#导入
@protocol CustomCellDelegate;
@interface CustomCell : UITableViewCell
@property(nonatomic,weak) id<CustomCellDelegate> delegate;
@end
@protocol CustomCellDelegate <NSObject>
-(void)followButtonClickedWithCell:(CustomCell *) cell;
@end
你的CustomCell.m
#import "CustomCell.h"
@implementation CustomCell
...
-(void)followButtonClicked:(UIButton *) sender{
if(self.delegate != nil){
[self.delegate followButtonClickedWithCell:self];
}
}
...
@end
确认你的view controller实现了CustomCellDelegate,在delegate方法中参考下面的代码获取被点击的indexPath
-(void)followButtonClickedWithCell:(CustomCell *) cell{
NSIndexPath *clickedIndexPath = [self.tableView indexPathForCell:cell];
if (clickedIndexPath != nil){
//Implement your logic here
}
}
修改关注按钮代码如下:
关注按钮
-(void)followButtonClick:(UIButton*)sender {
//Use this IndexPath
NSInteger buttonTag = [sender tag];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:buttonTag inSection:<YourSection>];
// Creating an action per tag
if (indexPath != nil)
{
NSLog(@"Current Row = %@", indexPath);
// ----- ERROR HERE -----
[self.myTableView beginUpdates];
// ----- Inserting Cell to Section 0 -----
[followedArray insertObject:[dataArray objectAtIndex:indexPath.row] atIndex:indexPath.row];
NSInteger rowToAdd = indexPath.row;
[self.myTableView insertRowsAtIndexPaths:[NSMutableArray arrayWithObjects:[NSIndexPath indexPathForRow:rowToAdd inSection:0], nil] withRowAnimation:YES];
// ----- 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];
[self.myTableView endUpdates];
}
}
这就是帮助我修复错误的原因,感谢@AliOmari、@Rachel 和@CodeChanger
[self.myTableView beginUpdates];
[followedArray insertObject:[dataArray objectAtIndex:indexPath.row] atIndex:0];
[myTableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[dataArray removeObjectAtIndex:indexPath.row];
NSInteger rowToRemove = indexPath.row;
[self.myTableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObjects:[NSIndexPath indexPathForRow:rowToRemove inSection:1], nil] withRowAnimation:YES];
[self.myTableView endUpdates];
在我的 iOS 应用程序中,我有一个 table 视图,它有 2 个部分/2 个数组。我正在尝试将一个 object 从一个 array/section 移动到另一个 array/section。现在第 0 节称为 followedArray,第 1 节称为 dataArray,dataArray 存储构成每个单元格的所有数据。因此,当用户单击我设置的名为 Follow 的按钮时,它应该获取该单元格并将其从 dataArray/Section 1 中删除并将其插入到 followedArray/Section 0 中。但是当我尝试这样做时,我得到一个错误这么说。
错误信息
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3599.6/UITableView.m:1396
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update'
代码:
TableView
- (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 Button
cell.followButton.tag = indexPath.row;
[cell.followButton addTarget:self action:@selector(followButtonClick:) forControlEvents:UIControlEventTouchUpInside];
cell.followButton.hidden = NO;
return cell;
}
小节Headers
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == 0) {
return @"Followed Data";
}
else {
return @"All Data";
}
}
行数
- (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];
}
---------------------------------------- --------------
--这是动作发生的地方--
---------------------------------------- --------------
关注按钮
-(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)
{
NSLog(@"Current Row = %@", indexPath);
// ----- ERROR HERE -----
[self.myTableView beginUpdates];
// ----- Inserting Cell to Section 0 ----- *NOT WORKING*
[followedArray insertObject:[dataArray objectAtIndex:indexPath.row] atIndex:indexPath.row];
NSInteger rowToAdd = indexPath.row;
[self.myTableView insertRowsAtIndexPaths:[NSMutableArray arrayWithObjects:[NSIndexPath indexPathForRow:rowToAdd inSection:0], nil] withRowAnimation:YES];
// ----- 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];
[self.myTableView endUpdates];
}
}
这可能是因为您正在使用 convertPoint 获取所单击单元格的 indexPath。尝试在您的 CustomCell 中创建一个协议并在您的 CustomCell 中实现您的 followButtonClick 并使用委托在您的控制器中使用您的 CustomCell 对象获取回调并使用该对象获取 indexPath。请参考以下代码。
你的CustomCell.h #导入
@protocol CustomCellDelegate;
@interface CustomCell : UITableViewCell
@property(nonatomic,weak) id<CustomCellDelegate> delegate;
@end
@protocol CustomCellDelegate <NSObject>
-(void)followButtonClickedWithCell:(CustomCell *) cell;
@end
你的CustomCell.m
#import "CustomCell.h"
@implementation CustomCell
...
-(void)followButtonClicked:(UIButton *) sender{
if(self.delegate != nil){
[self.delegate followButtonClickedWithCell:self];
}
}
...
@end
确认你的view controller实现了CustomCellDelegate,在delegate方法中参考下面的代码获取被点击的indexPath
-(void)followButtonClickedWithCell:(CustomCell *) cell{
NSIndexPath *clickedIndexPath = [self.tableView indexPathForCell:cell];
if (clickedIndexPath != nil){
//Implement your logic here
}
}
修改关注按钮代码如下:
关注按钮
-(void)followButtonClick:(UIButton*)sender {
//Use this IndexPath
NSInteger buttonTag = [sender tag];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:buttonTag inSection:<YourSection>];
// Creating an action per tag
if (indexPath != nil)
{
NSLog(@"Current Row = %@", indexPath);
// ----- ERROR HERE -----
[self.myTableView beginUpdates];
// ----- Inserting Cell to Section 0 -----
[followedArray insertObject:[dataArray objectAtIndex:indexPath.row] atIndex:indexPath.row];
NSInteger rowToAdd = indexPath.row;
[self.myTableView insertRowsAtIndexPaths:[NSMutableArray arrayWithObjects:[NSIndexPath indexPathForRow:rowToAdd inSection:0], nil] withRowAnimation:YES];
// ----- 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];
[self.myTableView endUpdates];
}
}
这就是帮助我修复错误的原因,感谢@AliOmari、@Rachel 和@CodeChanger
[self.myTableView beginUpdates];
[followedArray insertObject:[dataArray objectAtIndex:indexPath.row] atIndex:0];
[myTableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[dataArray removeObjectAtIndex:indexPath.row];
NSInteger rowToRemove = indexPath.row;
[self.myTableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObjects:[NSIndexPath indexPathForRow:rowToRemove inSection:1], nil] withRowAnimation:YES];
[self.myTableView endUpdates];