Designer023
Designer023

Reputation: 2002

objective c setting an object to a class that is not known

I have an array of view controllers (there are more that I have shown):

..
settings = [[settingsSettingTab alloc] initWithNibName:@"settingsTab" bundle:nil];
other = [[otherSettingTab alloc] initWithNibName:@"otherTab" bundle:nil];
..

NSArray *views = [NSArray arrayWithObjects:settings,other, nil];

I then loop through them and assign some details to them before pushing them:

for (int i = 0; i < views.count; i++) {
...
NSString *className = NSStringFromClass([[views objectAtIndex:i] class]);
Class myClass = NSClassFromString(className);

myClass *subView = (myClass*)[views objectAtIndex:i];

[self.scrollView addSubview:subView.view];
}

How can I assign the right class to the *subView. It worked fine when I had only one type of view in my array and then I just used:

settingTab *subView = (settingTab*)[views objectAtIndex:i];

But now I need to check and use the right one. I have googled the question, but I'm not sure of how I would describe it? (dynamic typing? Duck typing?) Any pointers would be really appreciated.

Thanks

EDIT:

Here is the whole code:

NSArray *titles = [NSArray arrayWithObjects: @"Basics", @"Colours", @"Shapes", @"Settings", @"Other", nil];

basics = [[basicsSettingTab alloc] initWithNibName:@"basicsTab" bundle:nil];
colours = [[colorsSettingTab alloc] initWithNibName:@"colorsTab" bundle:nil];
shapes = [[shapesSettingTab alloc] initWithNibName:@"shapesTab" bundle:nil];
settings = [[settingsSettingTab alloc] initWithNibName:@"settingsTab" bundle:nil];
other = [[otherSettingTab alloc] initWithNibName:@"otherTab" bundle:nil];

NSArray *views = [NSArray arrayWithObjects: basics,colours,shapes,settings,other, nil];

for (int i = 0; i < views.count; i++) {


    CGRect frame;
    frame.origin.x = self.scrollView.frame.size.width * i + 20;
    frame.origin.y = 0;

    CGFloat newWidth = 280;
    CGFloat newHeight = 320;
    CGFloat locx = 0;
    CGFloat locy = 0;

    CGRect panel = CGRectMake(locx, locy, newWidth, newHeight);

    frame.size = panel.size;//self.scrollView.frame.size;
    //subview.view.backgroundColor = [colors objectAtIndex:i];

    NSString *className = NSStringFromClass([[views objectAtIndex:i] class]);
    Class myClass = NSClassFromString(className);

    myClass *subView = (myClass*)[views objectAtIndex:i];
    [subView.view setFrame:frame];
    subView.tabTitle.text = [titles objectAtIndex:i];

    [subView.view.layer setCornerRadius:5.0f];
    [subView.view.layer setMasksToBounds:YES];

     subView.delegate = self;

    [self.scrollView addSubview:subView.view];
}

self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * views.count, self.scrollView.frame.size.height);
pageControl.numberOfPages = views.count;

}

Upvotes: 0

Views: 214

Answers (3)

Stuart
Stuart

Reputation: 37053

From your edit, we see that you have a property tabTitle on each of your custom view controllers. I would recommend that you create a new UIViewController subclass that implements tabTitle, and use that as the superclass for each of your custom controllers. That way your code only needs to know that they are all a MyTabViewController class (for want of a better class name!). So in your for loop:

MyTabViewController *subview = (MyTabViewController *)[views objectAtIndex:i];
[subview.view setFrame:frame];
[subview.tabTitle setText:[titles objectAtIndex:i]];

// ...

[self.scrollView addSubview:subView.view];

Everything else (view property for example) is defined by UIViewController, from which all your subclasses are descendants.

EDIT

Incidentally, I would be careful about the naming of your objects - your view controllers are not views. In particular, this might cause confusion where you have subview.view. Perhaps more appropriate would be subviewController.view, or even just controller.view?

Upvotes: 1

Ariel
Ariel

Reputation: 2440

If all of them are subclasses of UIViewController, then just use it:

****
frame.size = panel.size;//self.scrollView.frame.size;
//subview.view.backgroundColor = [colors objectAtIndex:i];

UIViewController* subView = (UIViewController*)[views objectAtIndex:i];

[subView.view setFrame:frame];
****

If you are not doing anything special to every view controller, then you just don't need to know exact class of it as long as it is subclass of some known class...

Hope it helps :)

Upvotes: 1

Dancreek
Dancreek

Reputation: 9544

The properties you are setting are common to all through since they all inherit from UIViewController.

replace:

myClass *subView = (myClass*)[views objectAtIndex:i];

with:

UIViewController *subViewController = (UIViewController *)[views objectAtIndex:i];

Also, do be careful about using the terms "view" and viewController" interchangably. They are not the same thing and can get very confusing/complex when you name things like they are.

Upvotes: 1

Related Questions