On my last tutorial post I demonstrated how one would add a UIToolbar to a UITableViewController for the case where you would want a UITableViewController to be the main view, rather than embedding a UITableView in a custom UIViewController.
I will now explain how to do the opposite, which is embedding a UITableView in your own custom view (for showing lists or options, or dynamically updated data). I will go through creating the UIView, and adding hooks to a UITableView inside our new custom view.
In my case, I needed to add a “Recent Searches” table on a custom view that had a search bar. Rather than using the one given by Interface Builder, lets build our own to learn how to do this.
First, create a UIViewController by adding a new file. Make sure that when creating it, the UITableViewController checkbox is NOT on, and that the “Create XIB for user interface” checkbox IS on. This will create the .m, the .h and the XIB files.
Lets start off by creating our outlets in the .h file to create our hooks for the search bar and the table view:
@interface EmbeddedTableView : UIViewController {
IBOutlet UISearchBar* search;
IBOutlet UITableView* recentSearchesTable;
}
@property (nonatomic, retain) UISearchBar* search;
@property (nonatomic, retain) UITableView* recentSearchesTable;
@end
Since we’re going to be implementing the UITableView callbacks, we need to implement a couple of delegates, so change the @interface line to look like the following:
@interface EmbeddedTableView : UIViewController <UITableViewDelegate, UITableViewDataSource> {
Dont forget to synthesize the search bar and the table in your class file’s .m:
@implementation EmbeddedTableView @synthesize search; @synthesize recentSearchesTable; ...
OK, now on to the interface. Double-click the XIB file in XCode to open up Interface Builder.
You should now see the View hierarchy and an empty view window. Go ahead and drag a Search Bar (UISearchBar) onto the top of the empty View. We should have the following at this point:
We’re going to leave the hook for the UISearchBar for another tutorial as it would complicate things slightly and deviate from the subject of this post. So let’s go ahead and add the UITableView to the view we’ve created. Drag a TableView to our view with the search bar. Let it expand to fill the empty area. We should now have the following:
Next, open up the inspector for the TableView so we can connect the outlets. If the Inspector is open, it is the 2nd tab, otherwise go to Tools->Connections Inspector (Command-2).
We want to drag the + button to the File’s Owner element in our hierarchy for the 2 Outlet items (dataSource, delegate) and do the same for the Referencing Outlet. When you let go of the button on the File’s Owner for this last item, it should give you the option to choose the recentSearchesTable. The inspector should look like this now:
Now, finally time to start writing some code! Save the XIB, and lets go back to XCode. If you want to connect the SearchBar, follow the same process as above. Since we’ve set up the outlet for the SearchBar, when you go to connect the Referencing Outlet, you should have the option to pick the ‘search’ outlet which we defined previously to be our UISearchBar.
We now have the basics set up. We have our Outlets connected to the interface objects, we have set up our delegate declarations, and now its time to write the implementation.
In your source .m file, we need to add our table delegate and dataSource callbacks:
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
// 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] autorelease];
}
// Set up the cell...
cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:15];
cell.textLabel.text = [NSString stringWithFormat:@"Cell Row #%d", [indexPath row]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// open a alert with an OK and cancel button
NSString *alertString = [NSString stringWithFormat:@"Clicked on row #%d", [indexPath row]];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertString message:@"" delegate:self cancelButtonTitle:@"Done" otherButtonTitles:nil];
[alert show];
[alert release];
}
That’s pretty much it. If you had started with a Window Based app, it would be necessary to add a couple things in your App Delegate. Your ApplicationDidFinishLaunching should look like the following:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
UINavigationController* navController = [[UINavigationController alloc] init];
EmbeddedTableView* tView = [[EmbeddedTableView alloc] initWithNibName:@"EmbeddedTableView" bundle:[NSBundle mainBundle]];
[navController pushViewController:tView animated:YES];
[tView release];
[window addSubview:navController.view];
[window makeKeyAndVisible];
}
And we should add a title to our Table View class:
- (void)viewDidLoad {
self.title = @"Search";
[super viewDidLoad];
}
Compile, run and you should have the following as your first view:
Clicking on one of the items should bring up an alert like we designed it to do:
NOTE: In the sample project, I’ve used a text view in place of the search bar. This way you can get a feel for how you can have multiple types of views embedded in a single controller.
Here is a link to the sample project: TableViewTut
|
|
Pingback: Aboveground Systems
Pingback: KD Munoz
Pingback: Georges Stephan