iBhavik
iBhavik

Reputation: 647

Call Multiple ViewController with UIViewController

In my project I have tableView with 10 cells. And in didSelectRowAtIndexPath all cells have multiple ViewController (files) so, my didSelectRowAtIndexPath looks like

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

if(indexPath.row == 0) {

            CallViewController *viewc = [[CallViewController alloc] initWithNibName:@"CallViewController" bundle:nil];
            [self.navigationController pushViewController:viewc animated:YES];
        }else if(indexPath.row == 1) {
            BirthdayViewController *viewc = [[BirthdayViewController alloc] initWithNibName:@"BirthdayViewController" bundle:nil];
            [self.navigationController pushViewController:viewc animated:YES];
        }

so I don't want these conditions I want my code be clean

Upvotes: 2

Views: 172

Answers (4)

Inder Kumar Rathore
Inder Kumar Rathore

Reputation: 40018

I would suggest you to have an array that contains the Class object of your class and then create object and push like

//view did load

mutableArr = [[NSMutableArray alloc] init];
[mutableArr addObject:[CallViewController class]];
[mutableArr addObject:[BirthdayViewController class]];
....
....

Then in your

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   if (indexPath.row < [mutableArr count]) {
       Class *obj = [mutableArr objectAtIndex:indexPath.row];
       UIViewController *controller = [[objc alloc] initWithNibName:NSStringFromClass(obj) bundle:nil];
       [self.navigationController pushViewController:controller animated:YES];
   }
}

OR if this is looking more weird then you can do like this

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   UIViewController *controller = nil;
   switch(indexPath.row) {
       case 0:
          controller = [[CallViewController alloc] initWithNibName:@"CallViewController" bundle:nil];
          break;
       case 1;
          controller = [[BirthdayViewController alloc] initWithNibName:@"BirthdayViewController " bundle:nil];
          break;
   }
    [self.navigationController pushViewController:controller animated:YES];
}

Upvotes: 3

shannoga
shannoga

Reputation: 19879

You can do this:

Add all your classes to NSArray, and select the correct class by the indexPath.row.

- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
      NSArray * conrollersClasses =@[[CallViewController class],[BirthdayViewController class]];
      UIViewController *controller = [[conrollersClasses[indexPath.row] alloc] init];
      [[self navigationController] controller animated:YES];

}

Upvotes: 1

Moonkid
Moonkid

Reputation: 916

You can create array of strings corresponding to file names and use NSClassFromString function to allocate view controllers

NSArray *viewControllers = [NSArray arrayWithObjects:@"VC1", @"VC2", @"VC3", nil];
id viewController = [[NSClassFromString([viewControllers objectAtIndex:indexPath.row]) alloc] initWithNibName:[viewControllers objectAtIndex:indexPath.row] bundle:nil];
[[self navigationController] pushViewController:viewController animated:YES];
[viewController release];

Upvotes: 1

Mindaugas
Mindaugas

Reputation: 1735

What is your underlying data model for tableview? If you could add additional attribute as ViewController Class Name you could do something like

- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *row = [rowData objectAtIndex:indexPath.row];
Class viewControllerClass =
    NSClassFromString([row objectForKey:@"viewControllerClassName"]);

//Default VC init looks for nib file named as VC afaik, if not, you could
    //add another attribute with init selector name
UIViewController *viewController =
    [[viewControllerClass alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
}

Upvotes: 2

Related Questions