I want to create a UIViewController programmatically. No nibs or storyboards. It will basically be created and then presented, and in its own class it will set up an image to be displayed.
However, whenever I just alloc init a view controller and present it, it comes out black as it is presented.
I assume this is because it lacks its own view?
When I create a raw UIViewController in Storyboard it automatically sets it up with a view, how do I set the view up so like the Storyboard it's the proper device size, changes on rotation, etc.?
Hoping this answer clarifies a few things here, even though there's already an accepted answer. I didn't feel the explanation given there was clear enough, which was probably why the OP didn't follow it at first, causing the OP more confusion and the answerer to get snarky in the comments, which doesn't help anyone. That's not what this site is all about.
Whenever I just alloc init a [UIViewController] and present it, it comes out black as it is presented.
It's not actually black. It's transparent (or more accurately, its view is) so what you're really seeing is the black from whatever is behind the view (in this simple case, most likely the UIWindow itself.)
This is because you are relying on the default implementation of loadView in your UIViewController which simply creates a UIView instance, and a UIView's background property is nil by default, hence it's transparent. When you set this up in interface builder however, it usually sets the backgroundColor property to white for you.
You can of course simply do this yourself in code. Here's an example showing exactly that except I'm using green instead of white so when you present it, you know for sure you're seeing this specific view:
UIViewController* plainViewController = [UIViewController new];
plainViewController.view.backgroundColor = [UIColor greenColor];
Of course it doesn't make much sense to use a UIViewController without subclassing it, but you can. You just have to manage everything externally, just as I did above.
If you do subclass UIViewController, you simply implement your own loadView implementation to create your own UIView (or subclass), but remember, there too it will be transparent unless you explicitly set its backgroundColor as well. Here are a few ways to do exactly that...
In your own UIViewController.m subclass, to initialize the background with the default UIView instance...
- (void) loadView
{
[super loadView]; // Actually loads and assigns the default view
// Set the background on the default view
self.view.backgroundColor = [UIColor greenColor];
}
or to use a custom UIView subclass...
- (void) loadView
{
// Create and initialize your custom view
MyCustomUIView* myCustomUIView = [MyCustomUIView new];
myCustomUIView.backgroundColor = [UIColor greenColor];
// You're setting the view so do *not* call [super loadView]
self.view = myCustomUIView;
}
You can also initialize the background in viewDidLoad, like so (this works for either of the versions above.
- (void) viewDidLoad
{
// Set the background on whatever view is being managed
// regardless of where/how it was created
self.view.backgroundColor = [UIColor greenColor];
}
Note: when using viewDidLoad:
loadView entirely as it's not needed as super will now handle creating the view.loadView but delete the line where you're setting the backgroundColor property since you're now doing that in viewDidLoad.The benefit with all three of these approaches however is now the view's initialization is contained within your UIViewController making reuse much easier.
On a side note, a UIWindow is itself a subclass of UIView, and thus, it also has a backgroundColor property (which is also nil by default of course.) As such, if you change the backgroundColor property of the window to say purple, that's what you would have seen instead of black (that is until you set the background color on the view, which completely covers the window.)
I assume this is because it lacks its own view?
Hopefully the above-stated reasons clarified this assumption is wrong. It is actually there, just transparent.
The act of simply accessing the view property of a UIViewController will create the view if it doesn't exist already. Since presenting a newly instantiated UIViewController requires accessing its view property to have something to actually present, that is when the view is created. However, in the case above where I explicitly access the view property so I can set the backgroundColor property on it, that was the point in time when the view was created.
Anyway, hope this clarifies a little more what you were seeing and what's actually going on behind the scenes. Its actually pretty simple to create and use ViewControllers programmatically once you get the hang of it. Even so, it's still far easier to use storyboards or even NIBs with Interface Builder since you can visually see what you're doing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With