Agamemnon
Agamemnon

Reputation: 607

NSString placeholder for class name

How do you use a placeholder for the name of a class? I have methods that based on incoming parameters reference other classes by name. In the crude example below I need to be able to load one of three ViewControllers based on the name alone (not an array of ViewControllers as this is just one example).

-(void)loadViewController:(int)vcNumberToLoad
{
    NSString *vcOne = @"firstViewControllerName";
    NSString *vcTwo = @"secondViewControllerName";
    NSString *vcThree = @"thirdViewControllerName";

    NSArray *vcArray = [NSArray arrayWithObjects:vcOne, vcTwo, vcThree, nil];

    NSString *nameOfVCToLoad = [vcArray objectAtIndex:vcNumberToLoad];

    UIViewController |VALUE OF nameOfVCToLoad| = [[UIViewController alloc] init]; // What is the code to get the value of nameOfVCToLoad to be used as the instance name of the UIVC class
    [self.navigationController pushViewController:|VALUE OF nameOfVCToLoad| animated:NO];

}

For example, if the method was run with a parameter of '1'

NSString *nameOfVCToLoad = [vcArray objectAtIndex:vcNumberToLoad]; //this would = secondViewControllerName

UIViewController secondViewControllerName = [[UIViewController alloc] init];
[self.navigationController pushViewController:secondViewControllerName animated:NO];

Other questions seem to intimate that [NSClassFromString:nameOfVCToLoad] could be along the lines of what I need, if so how?

Upvotes: 1

Views: 134

Answers (2)

You are confusing yourselves about object. You are looking for this one

NSClassFromString(vcOne) will help you to do the dynamic class selection

isKindOfClass will help you to identify that whether that class is the given class

-(void)loadViewController:(int)vcNumberToLoad
{
    NSString *vcOne = @"firstViewControllerName";
    NSString *vcTwo = @"secondViewControllerName";
    NSString *vcThree = @"thirdViewControllerName";


    firstViewControllerName *fvc = nil;
    secondViewControllerName *svc = nil;
    thirdViewControllerName *tvc = nil;


    NSArray *vcArray = [NSArray arrayWithObjects:vcOne, vcTwo, vcThree, nil];

    NSString *nameOfVCToLoad = [vcArray objectAtIndex:vcNumberToLoad];


    UIViewController *aLoadedViewController = [[NSClassFromString(nameOfVCToLoad) alloc] init];

    if ([aLoadedViewController isKindOfClass:[NSClassFromString(vcOne)]]) {

        fvc = aLoadedViewController;

    }
    else if ([aLoadedViewController isKindOfClass:[NSClassFromString(vcTwo)]]) {

        svc = aLoadedViewController;

    }
    else if ([aLoadedViewController isKindOfClass:[NSClassFromString(vcThree)]]) {

        tvc = aLoadedViewController;

    }

    [self.navigationController pushViewController:aLoadedViewController animated:NO];

}

Upvotes: 2

skyylex
skyylex

Reputation: 815

Objective-c has Class type, that exists as part of the NSObject.

More accurately will be:

-(void)loadViewController:(int)vcNumberToLoad {
     Class vcOne = [FirstViewControllerName class];
     Class vcTwo = [SecondViewControllerName class];
     Class vcThree = [ThirdViewControllerName class];

     Class viewControllerClass;
     // switch between classes

     UIViewController *viewControllerToPush = [[viewControllerClass alloc] init];
     // push UIViewController
}

Benefit from doing like this is in the type checking at compile time.

Upvotes: 0

Related Questions