可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Being new to Cocoa, I'm having a few issues with Interface Builder
, UIViewController
and friends.
I have a UIViewController
subclass with a UIView
defined in a xib, and with the controller's view outlet connected to the view. The xib's "file's owner" is set as myViewcontroller subclass.
In this one instance, the following code to load the controller/view (from the main view controller) doesn't work as expected:
if ( self.myViewController == nil )
{
self.myViewController = [[MyViewController alloc]
initWithNibName:@"MyViewController" bundle:nil];
}
[self.navigationController
pushViewController:self.myViewController animated:YES];
In MyViewController's methods, I have placed breakpoints and log messages to see what is going on:
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
NSLog(@"initWithNibName\n");
}
return self;
}
-(void)viewDidLoad {
[super viewDidLoad];
NSLog(@"viewDidLoad\n");
}
Expected result
Both -initWithNibName
and -viewDidLoad
methods are called, and myViewController's view is displayed.
Observed result
Only -initWithNibName
is called, the view is not displayed.
Have I missed something? Can anyone recommend anything to check? (Particularly in the wondrously opaque Interface Builder tool).
回答1:
RE: SOLUTION FOUND!!!!!
Indeed that seems to be a working solution, however the real trick is not in setting the view.hidden
property to NO, what makes the view load from the nib file is the calling of the UIViewController's
view method, the view only actually gets loaded from the nib when the view method is called for the first time.
In that sense, a simple [viewController view]
message would force the view to load from the nib file.
回答2:
Ok, I have a partial answer - maybe the gurus can explain some more. The problem is:
[self.navigationController pushViewController:myViewController animated:YES];
Looking more closely, in this case self.navigationController
is nil - so the push message is going no-where.
Instead, if I send:
[self.view addSubview:self.myViewController.view];
Then the view appears and -viewDidLoad
is called.
I'm not entirely sure why self.navigationController
is not set in this instance - the only thing I can think of is that self
is a subclass of UIViewController
rather than UITableViewController
(where the pushViewController
code came from).
Also, silently allowing messages to go to nil seems like a bad idea, although these answers say otherwise. See also my question here.
Final edit:
Answers in comments below, I've realised the display function that I was actually after (given myViewController is modal) is:
[self presentModalViewController:myViewController animated:YES];
Thanks everyone for their helpful responses.
回答3:
SOLUTION FOUND!!!!!
Even something as innocuous as this makes the viewDidLoad
method call happen.
Insert this right after alloc initWithNibName
viewController.view.hidden = NO; //calls viewDidLoad
回答4:
Simply use
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
//Your Code here
}
instead of the viewDidLoad method.
回答5:
Chances are that you might not have linked the supposed ViewController
in main.storyboard
from the Identity Inspector
to the custom class
you created. You might be able to navigate to that controller from other view controllers via segues but any of viewDidLoad()
, viewWillAppear()
etc. won't be executed.
回答6:
make sure that the view outlet in File's Owner (your viewController subclass) is connected to the actual view (i.e. the 480X320 canvas you see on your screen that you use to build your UI)
回答7:
It looks like a capitalization problem to me. You're referencing the class MyViewController
instead of the property myViewController
in the call to pushViewController.
回答8:
Check your run log for errors. Almost certainly, the NIB is not loading, and there should be an error to that effect. The most likely cause for that is failure to put it in the bundle. Look in your "Copy Resources" build phase and make sure that the XIB is actually being copied. Build for the simulator, and go down into the build directory and make sure that the NIB is in the .app bundle.
回答9:
Another reason, somewhat obvious in retrospect: if viewController.view
is set in code, then the viewDidLoad event will not trigger.