I've been trying to understand View Controllers and Views and even after watching some of the classes on iTunesU, I'm still having some trouble implementing them programmatically. I'm hoping someone can clarify a bit.
So I'm trying to create a UIViewController which in turn creates its view.
The program is broken up in the following classes: ProgramNameAppDelegate.h and .m ApplicationRootViewController.h and .m
From the AppDelegate, I create the UIWindow and UIViewController. Part开发者_StackOverflow社区ial code goes like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
_window = [ [UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if (!_window)
{
[self release];
return NO;
}
_rootViewController = [ [ApplicationRootViewController alloc] init];
if (!_rootViewController)
{
NSLog(@"No _rootViewController");
[self release];
return NO;
}
[_window addSubview:[_rootViewController view]];
[_window makeKeyAndVisible];
return YES;
}
In the ApplicationRootViewController I call init. My UIView is created in loadView as such:
- (void)loadView
{
NSLog(@"In loadView");
[super loadView];
CGRect _frame = [[UIScreen mainScreen] applicationFrame];
UIView* _rootView = [[UIView alloc] initWithFrame:_frame];
[_rootView setBackgroundColor:[UIColor redColor]];
self.view = _rootView;
return;
}
The problem I'm having is apparently the program is creating the view, however, it is never displaying the view that I created until the app resigns active. Once I go out of the app and come back in, the view is there. I have tried several other things, but it always behaves the same.
I would eventually like to for the controller to create the view from a subclassed UIView.h and .m file.
Thanks,
Kevin
From the docs:
Your custom implementation of loadView method should not call super.
So, get rid of [super loadview]
and it should work;)
Also, if you want to use a custom view (Subclass of UIView
). Alloc/Init using initWithFrame:
and when referring self.view from uiviewcontroller you will have to cast it like so:
[(MyView *)self.view myMethod];
As simple as that ;)
EDIT: Suppose you make a class like this:
//MyView.h
@interface MyView : UIView{
...
}
- (void) doSomething:(NSString *)string;
@end
//MyView.m
#import MyView.h
@implementation MyView
... write your implementation here
@end
then in the UIViewController, in loadView do:
//don't forget to #import "MyView.h"
-(void) loadView{
MyView *myView = [[MyView alloc] initWithFrame:CGRectMake(...)];
self.view = (UIView *)myView;
[myView release];
}
then when referring your view somewhere else in the controller:
- (void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[(MyView *)self.view doSomething:@"something"];//1
[self.view setBackgroundColor:[UIColor greenColor]];//2
}
In //1
you should cast because your are calling doSomething:
method (or it could be a property as well), which is declared/defined in MyView
and not in UIView
. If you don't cast you will get a warning but it will work.
In //2
you don't need to cast since setBackgroundColor:
is a method defined in UIView
class ;)
Objective-C is very flexible and will allow to cast many things, so you have to be careful because casting is like telling the compiler: "trust me, is not a UIView, is MyVIew" and the compiler will obey you. But if you were wrong your app will crash when attempting to call doSomething:
because it does not exist in UIView
.
精彩评论