【问题标题】:Problem with adding a new row and populating it添加新行并填充它的问题
【发布时间】:2020-03-27 03:16:12
【问题描述】:

我正在尝试使用来自另一个视图控制器的 NSMutablearray 向我的自定义单元格添加一个新行,但是在添加新行时出现错误。 itemsTableView 在 photoCaptureView 中可见,它是 photoCaptureViewController 的视图。因此,当调用 ScannerModalViewController(也在 photoCaptureViewController 中调用)并捕获项目/数据时,一旦将其关闭,就会调用 scannerBarcode 以向我的自定义单元格添加新行并填充它,我收到此错误。

我收到警告和错误。警告是

Warning once only: UITableView was told to layout its visible cells and other contents without
being in the view hierarchy (the table view or one of its superviews has not been added to a
window). This may cause bugs by forcing views inside the table view to load and perform layout 
without accurate information (e.g. table view bounds, trait collection, layout margins, safe
area insets, etc), and will also cause unnecessary performance overhead due to extra layout 
passes. Make a symbolic breakpoint at UITableViewAlertForLayoutOutsideViewHierarchy to catch 
this in the debugger and see what caused this to occur, so you can avoid this action altogether 
if possible, or defer it until the table view has been added to a window. Table view:
<UITableView: 0x1038a9c00; frame = (10 70; 398 794); clipsToBounds = YES; gestureRecognizers =
<NSArray: 0x28165f0c0>; layer = <CALayer: 0x2818ebb20>; contentOffset: {0, 0}; contentSize: 
{398, 60}; adjustedContentInset: {0, 0, 0, 0}; dataSource: <PhotoCaptureViewController: 0x10364a880>>

错误是

Invalid update: invalid number of rows in section 0. The number of rows contained in an existing 
section after the update (3) must be equal to the number of rows contained in that section 
before the update (1), plus or minus the number of rows inserted or deleted from that section 
(1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section 
(0 moved in, 0 moved out).

我的代码是 photoCaptureViewController.h

@interface PhotoCaptureViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, ScannerModalViewControllerDelegate> {
    PhotoCaptureView* photoCaptureView;
    NSMutableArray* barcodeItems;

    ScannerModalViewController* scannerModalViewController;
}

-(void) scanBarcode;
-(void) scannedBarcode:(NSString *) barcode;

@end

photoCaptureViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];

    [photoCaptureView.itemsTableView registerNib:[UINib nibWithNibName:@"BarcodeItemsTableViewCell" bundle:nil] forCellReuseIdentifier:@"BarcodeItemsCell"];
    photoCaptureView.itemsTableView.rowHeight = 60;
    photoCaptureView.itemsTableView.dataSource = self;
    photoCaptureView.itemsTableView.delegate = self;
    [photoCaptureView.itemsTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
}

#pragma mark scannerModalViewController Methods
-(void) scanBarcode  {
    NSLog(@"[%@] Scan Barcode Requested", self.class);

    scannerModalViewController = [[ScannerModalViewController alloc] init];
    scannerModalViewController.delegate = self;
    scannerModalViewController.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:scannerModalViewController animated:YES completion:nil];
}

-(void) scannedBarcode:(NSMutableArray *) barcodes {
    barcodeItems = [[NSMutableArray alloc] init];

    [barcodeItems addObjectsFromArray:barcodes];
    [barcodeItems addObject:@"test"];
    [barcodeItems addObject:@"test1"];
    NSLog(@"%@", barcodes);
    NSLog(@"%@", barcodeItems);

    NSIndexPath* indexPath = [NSIndexPath indexPathForRow:barcodeItems.count-1 inSection:0];
    [photoCaptureView.itemsTableView beginUpdates];
    [photoCaptureView.itemsTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    [photoCaptureView.itemsTableView endUpdates];
}

#pragma mark UITableViewDataSource methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return barcodeItems.count + 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Cell Initialized");
    static NSString *cellIdentifier = @"BarcodeItemsCell";

    BarcodeItemsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    if (cell == nil) {
        cell = [[BarcodeItemsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }

    // Configure the cell...
    cell.barcodeLabel.text = [barcodeItems objectAtIndex:indexPath.row];
    UIImage *btnImage = [UIImage imageNamed:@"barcodeIcon"];
    [cell.leftButton setImage:btnImage forState:UIControlStateNormal];

    NSLog(@"Cell Populated");
    return cell;
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    return true;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [barcodeItems removeObjectAtIndex:indexPath.row];

        [photoCaptureView.itemsTableView beginUpdates];
        [photoCaptureView.itemsTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        [photoCaptureView.itemsTableView endUpdates];
    }
}

@end

【问题讨论】:

    标签: ios objective-c uitableview


    【解决方案1】:

    如果您插入带有insertRowsAtIndexPaths 的项目,您必须指定所有 路径。

    并且beginUpdates /endUpdates` 对单个插入/删除/移动操作无效。

    -(void) scannedBarcode:(NSMutableArray *) barcodes {
        barcodeItems = [[NSMutableArray alloc] init];
    
        [barcodeItems addObjectsFromArray:barcodes];
        [barcodeItems addObject:@"test"];
        [barcodeItems addObject:@"test1"];
        NSLog(@"%@", barcodes);
        NSLog(@"%@", barcodeItems);
    
        NSMutableArray<NSIndexPath *>* indexPaths = [[NSMutableArray alloc] init];
        for (i = 0; i < barcodeItems.count; i++) {
           [indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
        }
    
        [photoCaptureView.itemsTableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
    }
    

    numberOfRowsInSection必须返回

    return barcodeItems.count;
    

    【讨论】:

    • 感谢您的回答!但这仅适用于一种用途,并且警告并没有消失。当我尝试再次显示 scannerModalViewController 并添加另一行时,应用程序崩溃并出现与问题相同的错误。
    • 警告和错误无关。警告包含调试问题的建议。关于错误,您必须保持数据源和表视图同步。
    • 我明白了。但我不知道如何让它们保持同步。
    猜你喜欢
    • 2020-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多