tags:

views:

2542

answers:

4

I have an app with 2 screens (MainViewController and AboutViewController). Upon the user clicking a button, I'd like to load the AboutViewController screen, which is defined in another XIB.

Seems simple, but I can't seem to find my google-fu today. How do I pull this off?

A: 

NSBundle loadNibNamed:

CiNN
+6  A: 

When you call [AboutViewController init], it's expected to call some form of [super init], which is a synonym for [UIViewController init]. When this happens, your view controller will automatically look for a nib file called (in your case) AboutViewController.xib. If it finds that file, it loads it's contents into your view controller for you.

So basically, all you need to do is initialize your view controller, and make sure it has the same name as the associated nib file.

If you wanted to load a nib file with a different name into your view controller, you could explicitly call initWithNibName:bundle: with the name of whichever nib file you like.

If the standard init (with a same-name nib file) isn't working for you, there are a couple things you could check.

  • the spelling of the class name is the same as the spelling (and case) of the nib file
  • the nib file is included in the project, and not just sitting in the same directory
  • your UIViewController subclass's init method does also call [super init]
  • you are calling your UIViewController subclass's init method
  • you are indeed making your view controller's view visible
Tyler
A: 
if (highScoresTableViewController == nil) {
 HighScoresViewController *aView = [[HighScoresViewController alloc]
             initWithNibName:@"HighScoresView" bundle:[NSBundle mainBundle]];
 if (aView == nil)
  NSLog(@"nil! %s", __PRETTY_FUNCTION__);

 self.highScoresViewController = aView;
 aView.rootViewController = self;
 if (!aView.view)  // doing this to trigger viewWillLoad
  NSLog(@"view not loaded %s", __PRETTY_FUNCTION__);  
 [aView release];
}

[self switchTwoViews:myViewController otherView:highScoresViewController];

And switchTwoViews:

- (void)switchTwoViews:(UIViewController *)view1 otherView:(UIViewController *)view2
{
    /*
     This method is called to switch views.
     It flips the displayed view from the main view to the flipside view and vice-versa.
     */

    UIViewController *coming = nil;
    UIViewController *going = nil;
    UIViewAnimationTransition transition;

    [view1.view setUserInteractionEnabled: NO];
    [view2.view setUserInteractionEnabled: NO];
    if (view1.view.superview == nil) {
     coming = view1;
     going = view2;
     transition = UIViewAnimationTransitionFlipFromLeft;
    }
    else {
     coming = view2;
     going = view1;
     transition = UIViewAnimationTransitionFlipFromRight;
    }
    // coming.view.frame = [UIScreen mainScreen].applicationFrame;
    [coming.view setFrame:CGRectMake(0, 0, 480, 300)];

    // going.view.alpha = 1.0;  //uncomment these lines if we want fading of views
    // coming.view.alpha = 0.0;

    NSArray *viewArray = [[NSArray alloc] initWithObjects:coming, going, nil];
    [coming viewWillAppear:YES];
    [going viewWillDisappear:YES];
    [UIView beginAnimations:@"View Flip" context:viewArray]; {
     [UIView setAnimationDuration:1.0];
     [UIView setAnimationDelegate:self];
     [UIView setAnimationDidStopSelector:@selector(animationDidEnd:finished:context:)];
     [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

     //  coming.view.alpha = 1.0;  //uncomment these lines if we want fading of views
     //  going.view.alpha = 0.0;

     [UIView setAnimationTransition:transition forView:self.view cache:YES];
     [self.view addSubview: coming.view];
    }
    [UIView commitAnimations];

}

- (void) animationDidEnd:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    NSArray *viewArray = context;
    [((UIViewController *)[viewArray objectAtIndex:1]).view removeFromSuperview];
    [[viewArray objectAtIndex:1] viewDidDisappear:YES];
    [[viewArray objectAtIndex:0] viewDidAppear:YES];
    [[[viewArray objectAtIndex:0] view] setUserInteractionEnabled: YES];
    [viewArray release];
}
mahboudz
This code does not answer the question. Or any question.
Steve Weller
I beg to differ. He asked "I'd like to load the AboutViewController screen, which is defined in another XIB". The code above is what I use to load view controllers from their .xib files. Just cause you do it a different way doesn't mean all other ways are incorrect.
mahboudz
+1  A: 

With an About screen you probably just want to show a view and then dismiss it. So rather than use a whole new view controller you can just cover the current view.

Assuming you have an ivar

UIView *aboutUsView;

with the appropriate property.

In your view controller do:

[[NSBundle mainBundle] loadNibNamed:@"AboutUsView" owner:self options:nil]; // Retains top level items
[self.view addSubview:aboutUsView];  // Retains the view
[aboutUsView release];

To remove the view, say in an action connected to a button on the view, do:

[aboutUsView removeFromSuperview], aboutUsView = nil;  // Releases the view
Steve Weller
He specifically said he had two view controllers, "MainViewController and AboutViewController" not a view controller and a view.
mahboudz
Correct. And I specifically said that he may not need both of them to meet his stated goal.
Steve Weller