简体   繁体   English

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

[英]“Attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update” Error

I have an app that is selecting a person from their contacts list and takes their First name, last name and email. 我有一个应用程序,从他们的联系人列表中选择一个人,并采取他们的名字,姓氏和电子邮件。 It then saves the first name to a nsmutablearray and puts it into a uitableview cell. 然后它将名字保存到nsmutablearray并将其放入uitableview单元格中。 My problem occurs once the contact is selected in the simulator. 一旦在模拟器中选择了联系人,我的问题就出现了。

Code: 码:

.h: 。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: .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 must be kept in sync with the data source at all times. UITableView必须始终与数据源保持同步。 Special care must be taken if the data source can change in a background thread. 如果数据源可以在后台线程中更改,则必须特别小心。

When something is added to the data source, call beginUpdate/insert/endUpdate as soon as possible. 当某些内容添加到数据源时,请尽快调用beginUpdate / insert / endUpdate。 You don't have to worry about caching these, the UITableView will cache changes to be executed when it determines there is enough cpu time and resources. 您不必担心缓存这些,UITableView会在确定有足够的CPU时间和资源时缓存要执行的更改。

The moment endUpdates is called, the UITable will ask the dataSource for the number of sections and rows again. 调用endUpdates时,UITable将再次询问dataSource的节和行数。 If your number of sections and row feeds directly from the dataSource, then number sections and rows, plus insertions, minus deletions must equal the numbers returned by the end calls for numberOfSections and numberOfRowsInSection. 如果直接来自dataSource的节和行的数量,则数字节和行,加上插入,减去删除必须等于numberOfSections和numberOfRowsInSection的结束调用返回的数字。

One last tip: avoid mixing calls to 'reloadData' and beginUpdate/endUpdate pairs. 最后一个提示:避免混合调用'reloadData'和beginUpdate / endUpdate对。 Use one or the other, not both. 使用其中一个,而不是两个。

I have encountered same problem as this. 我遇到了同样的问题。 All you have to do is change 你所要做的就是改变

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

to

 [self.myTableView beginUpdates];

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

 [self.myTableView endUpdates];

From UITableView Documentation 来自UITableView文档

beginUpdates

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

when you use beginUpdates , you must call endUpdates and not reloadData . 当您使用beginUpdates ,您必须调用endUpdates而不是reloadData

You can check https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html for more UITableView information. 您可以访问https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html以获取更多UITableView信息。

Hope this helps! 希望这可以帮助!

The comments above about implementing -tableView:numberOfRowsInSection: are correct. 以上关于实现-tableView:numberOfRowsInSection:的注释是正确的。 The assertion is checking the returned value expecting it will increase. 断言正在检查返回的值,期望它会增加。

However since you didn't set your dataSource on the UITableView its calling (or not calling) a method that doesn't exist and getting 0 . 但是,由于您没有在UITableView上设置dataSource ,因此调用(或不调用)一个不存在且获得0

You need to set the myTableView.dataSource and (since you also implement the delegate protocol) myTableView.delegate to self . 您需要将myTableView.dataSource和(因为您也实现委托协议) myTableView.delegateself

You're also likely to need something like 你也可能需要类似的东西

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

Unless you're registering that somewhere else or your storyboard has a "Prototype Cell" with the identifier "Cell" which your code asks for. 除非您在其他地方注册,否则您的故事板上会有一个“原型单元”,其中包含您的代码所要求的标识符"Cell"

I find this problem commonly occurs when I am placing a table view inside of a View Controller. 我发现当我在View Controller中放置一个表视图时,通常会发生此问题。 If you're using a UITableViewController jump to 3. 如果您正在使用UITableViewController跳转到3。

These steps may help: 这些步骤可能有所帮助

1: In your View Controller .h file make sure you add the following: 1:在View Controller .h文件中,确保添加以下内容:

@interface YourViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>

2: Next create an IBOutlet for your table view by ctrl + drag to your .h class. 2:接下来通过ctrl +拖动到你的.h类为你的表视图创建一个IBOutlet。 It should look like: 它应该看起来像:

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

3: Next step is to ctrl + drag to your View Controllers icon (see image) 3:下一步是按住Ctrl键并拖动到View Controllers图标(见图)

在此输入图像描述

You need to do this twice selecting: 您需要选择两次:

- delegate
- datasource

Finally, in your .m file, you should have the following method: 最后,在.m文件中,您应该使用以下方法:

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

    [self.tableView reloadData];
}

You can use either beginUpDates/endUpdates or reloadData, however Apple docs recommend reloadData. 您可以使用beginUpDates / endUpdates或reloadData,但Apple文档建议使用reloadData。

Once done your table should work fine. 完成后,您的表应该可以正常工作。

You need to maintain count for contacts array and increment accordingly. 您需要维护联系人数组的计数并相应地增加。
and while creating indexPath you need to set appropriate indexPathForRow: and section count(if required). 在创建indexPath时,您需要设置适当的indexPathForRow:和section count(如果需要)。

- (void)displayPerson:(ABRecordRef)person
{

  ..........

[contacts insertObject:firstName atIndex:0];

NSIndexPath * indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; // you cant do this increment appropriately

 .........
}

Please check your tableview datasource and delegate methods. 请检查您的tableview数据源和委托方法。 You may be passing empty array to datasource methods. 您可能正在将空数组传递给数据源方法。 And don't forget to reload tableview after getting data. 并且不要忘记在获取数据后重新加载tableview。

I know it's stupid - I got the same error because I forgot to set the delegate and dataSource. 我知道这是愚蠢的 - 我得到了同样的错误,因为我忘了设置委托和dataSource。

So after inserting rows and doing tableView.endUpdates() the tableView thought it must have some rows - but due to the unlinked dataSource , it has not. 因此,在插入行并执行tableView.endUpdates() ,tableView认为它必须有一些行 - 但由于未链接的dataSource ,它没有。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 “尝试将第0行插入第0部分,但更新后第0部分只有0行” - 'attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update' 尝试将第0行插入第0部分,但更新后第0部分只有0行 - attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update Swift-“尝试将第0行插入第0节,但更新后第0节只有0行” - Swift - “attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update” 尝试将第 3 行插入第 0 节,但更新后第 0 节中只有 3 行 - attempt to insert row 3 into section 0, but there are only 3 rows in section 0 after the update 拖放时出现错误“尝试将第 4 行插入第 1 节,但更新后第 1 节中只有 4 行” - Getting an error "attempt to insert row 4 into section 1, but there are only 4 rows in section 1 after the update" while drop and drag SwiftUI 应用程序因“尝试将第 2 行插入第 0 部分,但更新后第 0 部分中只有 2 行”错误而崩溃 - SwiftUI app crash with “attempt to insert row 2 into section 0, but there are only 2 rows in section 0 after the update” error 尝试插入行时“尝试将第 0 行插入第 0 节,但更新后第 0 节中只有 0 行” - "attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update" when trying to insert row 在表中插入一行时,“试图将第0行插入第0部分,但更新后第0部分只有0行” - 'attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update' when inserting a row into a table &#39;NSInternalInconsistencyException&#39;,原因:“试图将第0行插入第0节,但更新后第0节只有0行” - 'NSInternalInconsistencyException', reason: 'attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update' &#39;NSInternalInconsistencyException&#39;,原因:“试图将第4行插入第0节,但更新后第0节只有4行” - 'NSInternalInconsistencyException', reason: 'attempt to insert row 4 into section 0, but there are only 4 rows in section 0 after the update'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM