简体   繁体   中英

How to add a Cell into a static section UITableView?

I am a little bit confused

   - (IBAction)addEmailField:(id)sender {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        UITableViewCell *Cell = [self.tableView cellForRowAtIndexPath:indexPath];

        [self.tableView beginUpdates];
        [self.tableView  insertRowsAtIndexPaths:indexPath withRowAnimation:UITableViewRowAnimationRight];
        [self.tableView  endUpdates];

    }

this wont even compile, I read the documentation I know I have to pass it an NSarray. but I dont understand how to add the cell into that array

There are 2 possible scenarios to solve your problem:

1. In case when you have a static UITableView, ie all cells set up in XIB or Storyboard, you can't insert or delete cells because your whole table view is configured via Interface Builder and thus can't be modified. A way around this is to configure all cells (including those that need to be shown later) in Interface Builder and then setup their height in runtime:

    // This will show or hide the first row in first section depending on the value of
    // BOOL _firstRowVisible instance variable that you set elsewhere in your code.
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (indexPath.section == 0 && indexPath.row == 0)
            return _firstRowVisible ? 44 : 0;
        return 44;
    }

    // To show or hide the first row in first section.
    // Note that you need to call both -reloadRowsAtIndexPaths:withRowAnimation:
    // and -reloadData to make this work.
    - (IBAction)showOrHideEmailField:(id)sender
    {
        _firstRowVisible = !_firstRowVisible;
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        [self.tableView reloadData];
    }

2. In case you have dynamic cells, you can setup their appearance in Interface Builder, setting each cell type its own Reuse Identifier. Then, in code, in -tableView:cellForRowAtIndexPath: you specify what kind of cell you are going to use by passing the corresponding cell identifier to UITableView's -dequeueReusableCellWithIdentifier:forIndexPath: and set up your cell appropriately.

To make use of -insertRowsAtIndexPaths:withRowAnimation: you need to update your data source first, to keep your view in sync with your model. So for your case the following code might work:

@property (assign, nonatomic) NSInteger numberOfEmailFields;

    #pragma mark - Table View Data Source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 2;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    switch (section) {
        case 0:
            return 6;
        case 1:
            return self.numberOfEmailFields + 1;
        default:
            return 0;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    switch (indexPath.section) {
        case 0:
        {
            switch (indexPath.row) {
                case 0:
                {
                    // Dequeue, set up and return a cell with corresponding reuse identifier
                    static NSString *CellIdentifier = @"MyCell";
                    return [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
                }
                ...
                default:
                    break;
            }
            break;
        }
        default:
            break;
    }
    return nil;
}

- (IBAction)addEmailField:(id)sender
{
    // Update data source
    self.numberOfEmailFields++;

    // Animate rows
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:1];
    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];
}

I created a sample project for your scenario using the dynamic cells approach.

Note that to be able to add cells to a table view you need to use the second scenario, that is, use dynamic cells. This might seem much more work at first, but this approach is more expandable and easier to modify in future.

- (IBAction)addEmailField:(id)sender {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; // lowercase ivar name

    [self.tableView insertRowsAtIndexPaths:@[indexPath]    
                          withRowAnimation:UITableViewRowAnimationRight]; // use @[] for array literals
}

Don't need to specify begin update/end update, should only be used when there a series of actions on a table like inserts, moves, delete etc..

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