Creating Widgets (Views) Programmatically

I've demonstrated how to add widgets to a view within a XIB file, but they can also be created in code.

The main view within the Gas Can Manager is based on a table view. A table can have several sections, and each section can have a header and a footer. I'll use this fact to add a UIButton at both the top and bottom of the table's section. I'll then wire each button to call a method when it's clicked.

In GasCansViewController.h, I'll add pointers to manage two buttons:

  1. #import <UIKit/UIKit.h>
  2.  
  3. @interface GasCansViewController : UITableViewController {
  4. UIButton *importButton;
  5. UIButton *createButton;
  6. }
  7.  
  8. @end

In the implementation file, I add two methods. The first provides the TableViewController the header, and the second provides the footer widget (view):

  1. -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  2. if (!importButton) {
  3. importButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  4. importButton.frame = CGRectMake(0, 0, 100, 40);
  5. [importButton setTitle:@"Import..." forState:UIControlStateNormal];
  6. [importButton addTarget:self action:@selector(importContent:) forControlEvents:UIControlEventTouchDown];
  7. }
  8. return importButton;
  9. }
  10.  
  11. -(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
  12. if (!createButton) {
  13. createButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  14. createButton.frame = CGRectMake(0, 0, 100, 40);
  15. [createButton setTitle:@"Create..." forState:UIControlStateNormal];
  16. [createButton addTarget:self action:@selector(addContent:) forControlEvents:UIControlEventTouchDown];
  17. }
  18. return createButton;
  19. }

Since both methods are virtually identical, I'll comment on the header method only.

  • Line 2: This method will be called multiple times, so only create the view once.
  • Line 3-5: Instantiate a button, and set it's frame and title properties. (In this example, the frame is essentially ignored.)
  • Line 6: Instruct iOS to invoke the importContent method when the button is clicked.

It's also necessary to specify how "tall" each header / footer should be. For now, I've simply hard-coded these values.

  1. -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  2. return 50;
  3. }
  4.  
  5. -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
  6. return 50;
  7. }

The importContent method is as follows:

  1. -(void) importContent:(id)sender {
  2. GasCanLoadingViewController *loading = [[GasCanLoadingViewController alloc] init];
  3. [[self navigationController] pushViewController:loading animated:YES];
  4. }

This method instantiates a new view and pushes it onto the navigationController stack. (I'll create this view in a different section.)

Running the application creates a screen like this: