Reputation: 7769
I've got a PHP background, but I'm beginning to learn Objective-C, so that I can develop apps for the iPhone. So far things are going pretty well, but I've got a question that I haven't been able to find and answer to yet after googling and mining a number of different forums.
My app has to create a number of views, each with it's own uinque title bar. In order to do this, my code looks something like this for each view:
xViewController = [ [ XViewController alloc ] init ];
xNavController = [ [ UINavigationController alloc ]
initWithRootViewController: xViewController
];
xNavController.tabBarItem = [ [ UITabBarItem alloc ]
initWithTitle: @"My Info"
image: [ UIImage imageNamed: @"my_info.png" ]
tag: 3
];
This works, but what I'd like to do is to create a method that will return a nav controller when sent a string as a message, so I don't have to do all this for each view. The issue I am having is that the first line needs to allocate an object based on a class name passed to it as a string (i.e. XViewController needs to be taken from a string passed to the method), but I don't know how to treat a string as a class name. I know it's possible, because the UIApplicationMain() can use a string to call the app delegate class. How can I do it?
I'm sorry if any of this doesn't make sense, I'm still in the early stages of learning a new language!
Upvotes: 2
Views: 4063
Reputation:
If you have multiple TableViewCells loaded from NIBs, the code to load the individual NIBs gets ugly if you don't do something with dynamic loading.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// header
if (indexPath.row == 0) {
cellHeader *cell = (cellHeader *)[self loadCell:identHeader];
return cell;
// load more
} else if (indexPath.row == lastRow) {
loadMore *cell = (loadMore *)[self loadCell:identLoadMore];
return cell;
}
// default
cellDefault *cell = (cellDefault *)[self loadCell:identDefault];
return cell;
}
- (id)loadCell:(NSString *)className {
id cell = [tweetsView dequeueReusableCellWithIdentifier:className];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:className owner:nil options:nil];
for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[UITableViewCell class]]) {
cell = currentObject;
break;
}
}
}
return cell;
}
Upvotes: 1
Reputation: 25271
If I understand your problem correctly you don't need dynamic classes to make this work. Why not create, for each view controller class, its unique title
and image
method that just returns the unique title and image for that view controller. Then create a super class for your view controller classes with dummy title
and image
methods.
Your code above will then look something like this:
- (UINavigationController *)getNavController:(XGenericViewController *)viewController
{
UINavigationController *xNavController = [ [ UINavigationController alloc ]
initWithRootViewController: viewController
];
xNavController.tabBarItem = [ [ UITabBarItem alloc ]
initWithTitle: [viewController title]
image: [viewController image]
tag: 3
];
return [xNavController autorelease];
}
Upvotes: -1
Reputation: 78353
As well as using the runtime, you can do it just using Cocoa-touch methods:
NSString* theClassName = /* assume this exists */
Class theClass = NSClassFromString(theClassName);
NSObject* myObject = [[theClass performSelector:@selector(alloc)] init];
// do something with the new object instance
Upvotes: 19