Still Curious about "For the More Curious"


#1

I’ve missed something important, because I haven’t been able to figure out how to make the paging UIScrollView work.

(1) create new window-based project
(2) create a new UIViewController file
(3) add the loadview method shown in the “For the More Curious” section, and …

I know I need to do something to the appDelegate to make this work, but I don’t know what.


#2

You’ll have to instantiate your view controller subclass and then add its view to the window’s list of subviews, thus inserting all of the views created in the view controller’s loadView method into the visible view hierarchy.


#3

Thanks, Joe. That did the trick. I’m trying to make this work in landscape orientation to test my understanding.

The problem seems to be initWithFrame:frame in:
UIView *aView = [[[UIView alloc] initWithFrame:frame] autorelease]

Do you have to define a rectangle manually, or is there a way to use the “preferred” (according to the documentation) applicationFrame method to define the CGRect frame?


#4

You can get a rectangle that encompasses the amount of screen real-estate you have to work with (minus the status bar) by doing the following:

CGRect r = [[UIScreen mainScreen] applicationFrame];

#5

Thanks, Joe. That’s actually the code already given in the book.

I’m trying to resize the view so that it will fill the window in landscape orientation. Currently, in landscape orientation, the view’s bottom half is cut off and the view does not fit the entire width of the landscape-orientated window.


#6

Have you set the autoresizing masks to grow and shrink with the superview?


#7

Like this?

[aview setAutoresizingMask: NSViewHeightSizable];
[aview setAutoresizingMask: NSViewWidthSizable];

[bview setAutoresizingMask: NSViewHeightSizable];
[bview setAutoresizingMask: NSViewWidthSizable];


#8

Close, but a couple of things:

NSViewHeightSizable is the Cocoa version, you’ll need things like UIViewAutoresizingFlexibleWidth for the masks on the iPhone. (Chapter 9 discusses this… Notification and Rotation.)

Also, setAutoresizingMask: needs a combination of all the resizing masks. The way you have it now, both aview and bview only have resizable width - the height portion is replaced the second time you call setAutoresizingMask:.

Therefore, you’ll need code that looks like this:

[aview setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];

Also, for a full screen view, you’ll want to anchor each size of the view to its superview. Add UIViewAutoresizingFlexibleTopMargin as well as the other three (bottom, left, right) and the height/width ones, and it should rotate properly.


#9

The snip of code:


CGRect frame = [[UIScreen mainScreen] applicationFrame];

Does not return a CGRect that takes into account the UITabBar. So when adding a HypnosisView the view draws at 460.0 (pixels?) which leaves a little extra that the user could scroll up and down. Not exactly the desired effect. Other than manually adjusting (by subtracting 49.0) how do we take it into account?

I’m guessing this may be because the UITabBar view and the UIScrollView are siblings… but I am literally taking a stab in the dark with that guess.


#10

A UITabBarController will automatically resize the view of its active view controller to fit, so this shouldn’t be an issue.


#11

Would you mind double checking my code? The UITabBarController doesn’t seem to be automatically resizing…

ViewControllScrollAppDelegate.h

#import <UIKit/UIKit.h>

@interface ViewControllScrollAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end

ViewControllScrollAppDelegate.m

@implementation ViewControllScrollAppDelegate

@synthesize window;


#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
 	
	UITabBarController *tabBarController = [[UITabBarController alloc] init];
	ScrollViewController *svc = [[ScrollViewController alloc] init];
	
	NSArray *viewControllers = [NSArray arrayWithObjects:svc, nil];
	[tabBarController setViewControllers:viewControllers];
	
	[window addSubview:[tabBarController view]];
    [window makeKeyAndVisible];
	
	return YES;
}

- (void)dealloc {
    [window release];
    [super dealloc];
}


@end

ScrollViewControll.h

#import <UIKit/UIKit.h>


@interface ScrollViewController : UIViewController {

}

@end

ScrollViewControll.m

#import "ScrollViewController.h"


@implementation ScrollViewController

- (void)loadView {
	CGRect frame = [[UIScreen mainScreen] applicationFrame];
	
	UIScrollView *sv = [[[UIScrollView alloc] initWithFrame:frame] autorelease];
	
	frame.origin.y = 0;
	UIView *aView = [[[UIView alloc] initWithFrame:frame] autorelease];
	
	frame.origin.x += frame.size.width;
	UIView *bView = [[[UIView alloc] initWithFrame:frame] autorelease];
	
	[aView setBackgroundColor:[UIColor greenColor]];
	[bView setBackgroundColor:[UIColor blueColor]];
	
	[sv addSubview:aView];
	[sv addSubview:bView];
	
	[sv setContentSize:CGSizeMake(2 * frame.size.width, frame.size.height)];
	[sv setPagingEnabled:YES];
	[self setView:sv];
	
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
    [super viewDidUnload];
}

- (void)dealloc {
    [super dealloc];
}

@end

#12

Well, after days and days of trying to figure this out, today, I DID IT! Yay. Time to take myself out for coffee. I’m delighted.

My difficulty is, as always, understanding the instructions, the terminology is like a foreign language to me as I have very little computer language experience. However, little by little I’m starting to understand the words. Once I get the project working I go back and read the words again and relate them to the code and its placement.

Finding what structure to use had me completely baffled for so long. I kept on making mistakes too which didn’t help. This thread helped me a lot.

I’ve become an expert in repeating and repeating the setting up of a project and reading through many examples on the internet of all the different ways of flipping a screen. I’ve learned so much through the difficulty of this little code snippet. Thank you. I’m just so grateful that the code worked when it was put in place.

As mentioned in this thread the structure to select is 1) Window based application project, with a 2) UIViewController sub class file added. Once I worked that out I was on my way.

I was absolutely determined to find the structure within which to place your sample code. Most examples on the internet included the use of the Interface Builder which made things double confusing along with the fact that many examples render the error message “SDK missing”.

Is there a reason why you prefer creating apps programmatically?


#13

I’ve answered my own question about why you choose to create view controllers programatically. I found the answer in your book, which says:

[quote]We will always create view controllers programmatically. Some programmers will instantiate
view controllers inside XIB files. We’ve found this practice leads to projects that are difficult to
comprehend and debug.[/quote]

That makes sense to me.