For the More Curious


#1

The challenge in this chapter should have been taken from the “For the More Curious” section where the authors describe how to swap views based on rotation. Here’s what I have so far:

First, in HeavyViewController.h I created an ivar for the second view:

I didn’t create one for the original view, because one is automatically created called view. (Although, perhaps I should - won’t view refer to the second view once it becomes the current view?)

Next I created a xib called SecondView. I changed the File’s Owner class to HeavyViewController so that I could make a connection from File’s Owner to the secondView ivar.

Now it gets tricky. According to the description in the book I know I need to subclass HeavyViewController’s view, which probably looks something like this:

…but I’m not exactly sure where to put it. SecondView should only be initialized and added to the view hierarchy once…perhaps the viewDidLoad method of HeavyViewController would be a good spot.

Of course, first I need to actually initialize SecondView, but my designated initializer from the book calls initWithNibName and sets it to HeavyViewController.

The final step should be to override willAnimateRotationToInterfaceOrientation: duration: and swap the view based on the orientation like this:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)x duration:(NSTimeInterval)duration { if (UIInterfaceOrientationIsPortrait(x)) { //Load the original view } else { //Load the second view } }

But since I haven’t figured out how to initialize the second view I certainly don’t know how to reference it here.

This problem has really exposed the gaps in what I thought I had learned about views. I will keep plugging away until I (hopefully!) figure it out, but if anyone has any thoughts…


#2

It’s a good challenge you’ve taken on, and really that’s the point, right?
But I think you’re making things unnecessarily hard on yourself.

If you use a second nib, then you have to load that nib somewhere. (Offhand I don’t know the best place for that.) But if you use the same HeavyViewController.xib file, then it will already be loaded when you need it.

So how do you use the same nib file? There’s nothing that says you can’t drag out a second UIView and put it on the canvas. And you can still connect it to your secondView IBOutlet.

You already have the code (or almost) for adding this view as a subview to the main view. Now it’s just a matter of figuring out how to remove that subview, and coding both in the willAnimate… method. You’re that close!

(Incidentally, when you’re laying out out that second view, note the Orientation option in the Identity Inspector. This lets you design the view in landscape orientation if you like.)


#3

That was a lot easier! (Who knew you could put multiple views in a single nib?) It works, but I have one last question. The authors warned us not to replace the view of the view controller in the willAnimate…method. But isn’t that exactly what I’m doing when I use setView? As in…

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)x duration:(NSTimeInterval)duration { if (x == UIInterfaceOrientationPortrait) { [self setView:firstView]; } else if (x == UIInterfaceOrientationLandscapeLeft) { [self setView:secondView]; } }

Thanks again for all of your help!


#4

Yes, it is.

In your new code you added a reference to firstView, so you don’t lose the original reference in view. I don’t know if that was the authors’ original concern or not, but in rereading the warning it seems to go deeper than that. Because of their warning, I’d be leery of doing this.

An alternative is to use -addSubview: as you had previously, then -removeFromSuperview: to remove it.

- (void) willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation) toInterfaceOrientation 
                                          duration: (NSTimeInterval) duration
{
    if( UIInterfaceOrientationIsPortrait( toInterfaceOrientation )) {
        [secondView removeFromSuperview];
    }
    else {
        [[self view] addSubview: secondView];
    }
}

And you’re quite welcome. :slight_smile: