Reputation: 87
everywhere on the internet I find examples of how to add rows into a table view by having a special row "Add Row" with a green plus. But I don't want that.
I want to have a plus button in the titlebar of MyTableViewController, and invoke some Modal Add View Controller with a XIB file with just a single text field to fill it in. In this Modal Add View Controller I want to fill in this text field, and after I press Done, Modal Add View Controller dismisses, and I want to find that text added to a MyTableViewController table view.
I have a property in my MyTableViewController to hold all the lines of it:
@property (nonatomic, retain) NSMutableArray *list;;
I just can't get adding rows to work. I don't see where I could do the
[list addObject:];
Here's the code of the MyTableViewController addItem method which I invoke, when a user presses a plus button in the titlebar:
- (IBAction) addItem: (id) sender;
{
NSLog(@"Adding item...");
//Preparing "Add View" which has a single text field
AddViewController *addViewController = [[AddViewController alloc] init];
addViewController.title = @"Add Item";
UINavigationController *modalController = [[UINavigationController alloc]
initWithRootViewController:addViewController];
[addViewController release];
// Showing the prepared Add View controller modally
[self.navigationController presentModalViewController:modalController animated:YES]
NSLog(@"Modal controller has been presented.");
[modalController release];
}
And here is the code in the AddViewController, which is invoked after the textfield is typed in and pressing Done in the titlebar:
- (IBAction) done: (id) sender
{
NSLog(@"Reached Done");
if (textField != nil) {
self.fieldText = textField.text;
}
NSLog(@"About to dissmiss modal controller...");
[[self parentViewController] dismissModalViewControllerAnimated:YES];
NSLog(@"Modal controller has been dismissed.");
}
Upvotes: 1
Views: 1527
Reputation: 8357
After you dismiss your modal controller:
[self addObjectToMyModel:newObject];
such that if you called [tableView reloadData]
it would show up, but you don't need to call that, instead:
you need to know where the new object will appear in your table, determine the indexPath, and:
NSIndexPath *indexPathOfInsertedCell = …;
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPathOfInsertCell]
withRowAnimation:UITableViewRowAnimationFade];
Upvotes: 0
Reputation: 16193
It is pretty common to create a delegate protocol for such Add Controller and make the parent controller its delegate.
When the Add Controller is "done" (i.e. not cancelled with a possible Cancel button), it calls a delegate method, say, addControllerIsDone:
to let the parent table view controller know that it should take the set value, add it to the list, and dismiss the Add controller.
You could also pass the list to the Add Controller and let it add the set value itself before the [parentViewController dismissModalViewControllerAnimated:YES]
call.
It depends whether you want to keep the control of the list in your table view controller or you want to pass it to the Add Controller.
And after the Add Controller is dismissed, you can either figure out where the cell for new entry should be added in the tableView and insert it with a nice animation, reload the section (animation also possible) or whole tableView (animation not possible).
@class AddViewController;
@protocol AddViewControllerDelegate <NSObject>
- (void)controllerIsDone:(AddViewController *)controller;
@end
@interface AddViewController : UIViewController
@property (nonatomic, assign) id<AddViewControllerDelegate> delegate;
@end
And the 'done' code
- (IBAction) done: (id) sender
{
......
[self.delegate controllerIsDone:self];
NSLog(@"About to dissmiss modal controller...");
[[self parentViewController] dismissModalViewControllerAnimated:YES];
NSLog(@"Modal controller has been dismissed.");
}
And the MyViewController:
@interface MyViewController : UIViewController <AddViewControllerDelegate>
@end
So it has to implement the controllerIsDone:
method. Like this for example:
- (void)controllerIsDone:(AddViewController *)controller
{
[self.list addObject:controller.textField.text];
}
As the AddViewController dismisses itself, MyViewController doesn't have to do it in the delegate method. But the good practice would be that if you popped up the modal view controller, you should also dismiss it, just for symmetry's sake. ;)
In this case, of course the textField has to be a publicly accessible property.
I'm sure you'll figure out the second option.
Read up on Decorator pattern in Cocoa Fundamentals Guide.
Upvotes: 2