简体   繁体   中英

Obj-C- Add new row to TableView when cell is tapped?

I've got a tableview that allows users to add an item (a row) to an invoice (the tableview) when an existing row is tapped. That said, I can't seem to add an empty row because my code is trying to set the information in the cell with data from my specified array, but naturally, the count in the array is different from my data source (as I want the count to be +1).

Eg I want to return 3 cells even if there are only 2 dictionaries in my array, and the third cell should be empty.

I want this because the third cell allows my user to fill out empty fields, while the fields in the previous two rows are populated with their already input data. Here's how I'm trying to return the extra row right now, but as mentioned above, it crashes my app due to the imbalance of dictionaries returned in my array.

Here's my code so far:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
   
    self.allItems = [[NSMutableArray alloc] init];
    self.itemDetails = [[NSMutableDictionary alloc] init];

}

//TableView delegates
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return 1;
   
    
}




-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {


    return self.allItems.count + 1;

}



-(UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
    

        static NSString *ClientTableIdentifier = @"InvoiceDetailsTableViewCell";
        
       InvoiceDetailsTableViewCell *cell = (InvoiceDetailsTableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:ClientTableIdentifier];
        
        if (cell == nil)
        {
            NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"InvoiceDetailsTableViewCell" owner:self options:nil];
            cell = [nib objectAtIndex:0];
            
        }
    
    if (self.allItems.count == 0) {
        
    } else {
        
        cell.itemName.text = [self.allItems valueForKey:@"Item Name"][indexPath.row];
     
        
    }
    
        return cell;
        
    
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
   InvoiceDetailsTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
   
    NSString *itemTitle = cell.itemName.text;
    NSString *itemDescrip = cell.itemDescrip.text;
    NSString *itemCost = cell.itemCost.text;
    NSString *itemTax = cell.itemTax.text;
    
    
    [self.itemDetails setValue:itemTitle forKey:@"Item Name"];

    [self.itemDetails setValue:itemDescrip forKey:@"Item Description"];
    
    [self.itemDetails setValue:itemCost forKey:@"Item Cost"];
  
    [self.itemDetails setValue:itemTax forKey:@"Item Tax Rate"];

    [self.allItems addObject:self.itemDetails];
    
    [self.tableView reloadData];

}

One significant problem is the line that says:

cell.itemName.text = [self.allItems valueForKey:@"Item Name"][indexPath.row];

Since your row count exceeds the number of items in your array, you will want to check the row number before accessing the array:

NSInteger row = indexPath.row;
if (row < self.allItems.count) {
    cell.itemName.text = self.allItems[row][@"Item Name"]; // personally, I’d get row first, and then keyed value second
} else {
    cell.itemName.text = @"";
}

You want to check to make sure that the current row is not the last (blank) row.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM