3
votes

I'm a newbie programming iOS and I've a problem adding a new cell to a UITableView object. I'm using an storyboard and one of the scenes is a UIViewController that has several subviews: textfields, a tableview, etc. I intend to add rows to this tableView from a detail scene.

I'm able to initially add rows to the table, but I'm not able to add a row afterwards. When I press a button to add the row I call the method '[self.stepsListTableView reloadData];' which produces a call to the method '- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section' and it returns a correct value, including the new array element. But method '- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath' is not called to update the table.

I do not understand what I'm doing wrong.

Details of my source code:

WorkoutDetailsViewController.h

(…)
@interface WorkoutDetailsViewController : UIViewController <StepDetailsViewControllerDelegate, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, weak) id <WorkoutDetailsViewControllerDelegate> delegate;
@property (nonatomic, strong) Workout *workout;
(…)
@property (nonatomic, retain) IBOutlet UITableView *stepsListTableView;
(…)

WorkoutDetailsViewController.m

(…)
@synthesize stepsListTableView;
(…)
- (void)viewDidLoad
{
    [super viewDidLoad];

    addButton.enabled = FALSE;

    workoutNameField.delegate = self;
    if (self.workout == nil) {
        self.workout = [[Workout alloc] init];  
        self.stepsListTableView = [[UITableView alloc] init];
    }  
    self.stepsListTableView.delegate = self;
    self.stepsListTableView.dataSource = self;

}

(…)

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

// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
    //return [self.workout.stepsList count];
    NSInteger counter = 0;
    counter = [self.workout.stepsList count];
    return counter;
}

// Customize the appearance of table view cells.
- (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];
    }
    // Set up the cell...
    // Pending

    return cell;
}

- (void)stepDetailsViewControllerDidDone:(StepDetailsViewController *)controller
{
    [self.workout.stepsList addObject:controller.step];
    NSInteger counter = [self.workout.stepsList count];

    [self.stepsListTableView beginUpdates];

    NSArray *paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:(counter-1) inSection:0]];
    [self.stepsListTableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationTop];

    [self.stepsListTableView endUpdates];

    [self.stepsListTableView reloadData];
}

(…)

Also in the storyboard, I have setup the outlets delegate and dataSource to be the controller view.

Any idea ?

Regards, JoanBa

2
what do you mean you can add initially rows but not afterwards?alecnash

2 Answers

1
votes

I have solved the issue. I have discovered using debugger that method reloadData was called for a different UITableView than the one initialized in viewDidLoad.

I reviewed the UITableView settings in storyboard, which aparently were correct but I have deleted them and created again. Now it works.

In UIViewController header I have the line

@property (nonatomic, retain) IBOutlet UITableView *stepsListTableView;

and in implementation I have commented lines

//self.stepsListTableView.delegate = self;
//self.stepsListTableView.dataSource = self;

And, of course, in storyboard I have defined for the UITableView the following relationships:

Outlets: dataSource, delegate --> UIViewController

Referencing outlet: UITableView --> UIVIewController

That's it !!

0
votes

You may have the table view set to static content. Select the UITableView in Storyboard and in the "Attributes Inspector" section of the menu on the right of screen select the "Content" field under the "Table View" header and set the value to "Dynamic Prototypes".

Screenshot for clarity:

enter image description here

This little trick caught me out several times when I was starting out.