Reputation: 16317
I am trying to write a C preprocessor Macro for LLVM that's used like:
vc(@"Browser")
and expands to:
[[BrowserViewController alloc] initWithNibName:@"BrowserViewController" bundle:nil]
The best I can come up with is:
vc(Browser)
which is implemented as:
#define vc(xibName) [[xibName ## ViewController alloc] initWithNibName:[NSString stringWithFormat:@"%@ViewController", @#xibName] bundle:nil]
however to the user this could seem confusing as Browser
on its own (outside of string literals) looks like a token. @"Browser"
would make the intent a little clearer without requiring the user to read the macro.
EDIT:
The motivation behind this seems silly at first glance, but I work on apps for iPhone, iPad and OS X and each has it's own way of instantiating a view controller with a view that is laid out in Interface Builder.
iPad:
[[UIStoryboard storyboardWithName:@"StoryboardPad" bundle:nil] instantiateViewControllerWithIdentifier:@"Browser"];
iPhone:
[[UIStoryboard storyboardWithName:@"StoryboardPhone" bundle:nil] instantiateViewControllerWithIdentifier:@"Browser"];
OS X:
[[BrowserViewController alloc] initWithNibName:@"BrowserViewController" bundle:nil]
Since it's all Objective-C, some of my controllers are reused across platforms, and I don't like to litter my code with conditional compilation statements every time I want a view controller. Plus when working on different platforms on different days of the week it helps to know you can just call vc(@"Browser")
and you'll get what you expect whether it's on and iPad, iPhone or MAC. It's just a question of convention vs configuration.
Upvotes: 0
Views: 289
Reputation: 16317
Turns out a function is the way to implement this:
id InstantiateViewControllerWithXib(NSString *xibName) {
NSString *className = [xibName stringByAppendingString:@"ViewController"];
return [[NSClassFromString(className) alloc] initWithNibName:className bundle:nil];
}
To strictly answer the question, you could then define the desired macro:
#define vc(xibName) InstantiateViewControllerWithXib(xibName)
Upvotes: 0
Reputation: 38728
If you just call
[[BrowserViewController alloc] init];
then UIViewController will search for a xib
with an appropriate name in the following way
If the view controller class name ends with the word “Controller”, as in MyViewController, it looks for a nib file whose name matches the class name without the word “Controller”, as in MyView.nib.
It looks for a nib file whose name matches the name of the view controller class. For example, if the class name is MyViewController, it looks for a MyViewController.nib file.
The above one line of code should be short enough to not justify a macro ;)
Upvotes: 2