“尝试将第0行插入到第0部分,但更新后第0部分中只有0行”错误

我有一个应用程序,从他们的联系人列表中select一个人,并采取他们的名字,姓氏和电子邮件。 然后把名字保存到一个nsmutablearray中,并把它放到一个可用的视图单元格中。 一旦在模拟器中select了联系人,就会发生我的问题。

码:

。H:

#import <UIKit/UIKit.h> #import <AddressBookUI/AddressBookUI.h> @interface FirstViewController : UIViewController < ABPeoplePickerNavigationControllerDelegate, UITableViewDelegate, UITableViewDataSource> - (IBAction)showPicker:(id)sender; @property (weak, nonatomic) IBOutlet NSString *firstName; @property (weak, nonatomic) IBOutlet NSString *email; @property (weak, nonatomic) IBOutlet NSString *lastName; @property (weak, nonatomic) IBOutlet UITableView *myTableView; @property (strong, nonatomic) NSMutableArray *contacts; @end 

.M:

 #import "FirstViewController.h" @interface FirstViewController () @end @implementation FirstViewController @synthesize firstName; @synthesize email; @synthesize lastName; @synthesize contacts; @synthesize myTableView; - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. contacts = [[NSMutableArray alloc]initWithObjects:nil]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - UITableView Datasource -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return contacts.count; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } cell.textLabel.text = [contacts objectAtIndex:indexPath.row]; return cell; } - (IBAction)showPicker:(id)sender { ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init]; picker.peoplePickerDelegate = self; [self presentModalViewController:picker animated:YES]; } - (void)peoplePickerNavigationControllerDidCancel: (ABPeoplePickerNavigationController *)peoplePicker { [self dismissModalViewControllerAnimated:YES]; } - (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person { [self displayPerson:person]; [self dismissModalViewControllerAnimated:YES]; return NO; } - (BOOL)peoplePickerNavigationController: (ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier { return NO; } - (void)displayPerson:(ABRecordRef)person { NSString* name = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty); self.firstName = name; NSString* last = (__bridge_transfer NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty); self.lastName = last; ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty); NSString *emailId = (__bridge NSString *)ABMultiValueCopyValueAtIndex(emails, 0);//0 for "Home Email" and 1 for "Work Email". self.email = emailId; if (!(contacts)) { contacts = [[NSMutableArray alloc]init]; } [contacts insertObject:firstName atIndex:0]; NSIndexPath * indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; [self.myTableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; } @end 

UITableView必须始终与数据源保持同步。 如果数据源可以在后台线程中更改,则必须特别小心。

当某些内容添加到数据源时,尽快调用beginUpdate / insert / endUpdate。 你不必担心caching这些,UITableView会在确定有足够的CPU时间和资源时caching要执行的更改。

在endUpdates被调用的那一刻,UITable将再次向dataSource询问段数和行数。 如果直接从dataSource中input段和行的数量,则number段和行,加上insertions,minus删除次数必须等于numberOfSections和numberOfRowsInSection的最终调用返回的数字。

最后一个提示:避免将调用混合到“reloadData”和beginUpdate / endUpdate对。 使用一个或另一个,而不是两个。

我遇到了同样的问题。 你所要做的就是改变

 [self.myTableView insertRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationAutomatic];` 

  [self.myTableView beginUpdates]; [self.myTableView insertRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationAutomatic]; [self.myTableView endUpdates]; 

UITableView文档

beginUpdates

Begin a series of method calls that insert, delete, or select rows and sections of the receiver.

当你使用beginUpdates ,你必须调用endUpdates而不是reloadData

你可以查看https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html了解更多的UITableView信息&#x3002;

希望这可以帮助!

我发现这个问题通常发生在我放置一个视图控制器内的一个表视图。 如果你使用的是一个UITableViewController跳转到3。

这些步骤可能有助于:

1:在您的视图控制器.h文件请确保您添加以下内容:

 @interface YourViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> 

2:接下来通过ctrl +拖动你的.h类来为你的表格视图创build一个IBOutlet。 它应该看起来像:

 @property (weak, nonatomic) IBOutlet UITableView *tableView; 

3:下一步是按CTRL +拖动到您的视图控制器图标(见图)

在这里输入图像说明

你需要做两次select:

 - delegate - datasource 

最后,在你的.m文件中,你应该有以下方法:

 - (void) viewWillAppear:(BOOL)animated{ //[self.tableView beginUpdates]; //[self.tableView endUpdates]; [self.tableView reloadData]; } 

您可以使用beginUpDates / endUpdates或reloadData,但Apple文档build议reloadData。

一旦完成你的表应该工作正常。

上面关于实现-tableView:numberOfRowsInSection:的注释是正确的。 断言是检查返回的值,期望它会增加。

但是因为你没有设置你的dataSourceUITableView的调用(或不调用)的方法,不存在,并获得0

你需要将myTableView.dataSource和(因为你也实现了委托协议) myTableView.delegateself

你也可能需要类似的东西

 - (void)viewDidLoad { [super viewDidLoad]; [self.myTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"]; ... } 

除非您在其他地方注册,或者您的故事板上有代码要求的标识符"Cell"的“原型单元”。

您需要维护联系人数组的计数并相应增加。
并在创buildindexPath时,您需要设置适当的indexPathForRow:和段计数(如果需要)。

 - (void)displayPerson:(ABRecordRef)person { .......... [contacts insertObject:firstName atIndex:0]; NSIndexPath * indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; // you cant do this increment appropriately ......... } 

请检查你的tableview数据源和委托方法。 您可能将空数组传递给数据源方法。 获取数据后不要忘记重新加载tableview。