Procedure to set up a scroll view


#1

[Update: I added some code and results]
Now that I went through the book, I thought I’d try to graph some values in a scrollView (since there will probably be a lot of values) used within a Navigation Controller. So, using ideas from chapter 6 and 11, my sequence is as follows:

In my AppDelegate, I set the window to mainScreen.bounds (although I’ve also tried applicationFrame). I create a MenuViewController (UITableViewController), instantiate a NavigationController, init it with the MenuViewController, and set it to the windows’ RootViewController. Selecting Summary in MenuViewController’s table instantiates a GraphViewController (UIViewController), and pushes it on the NavigationController. GraphViewController’s loadView instantiates a graphScrollView (UIScrollView), which is set as GraphViewController’s view. A GraphView (UIView) is instantiated with a much wider area (bigFrame) as its initWithFrame. The GraphView is then added to the graphScrollView with addSubView, and graphScrollView’s ContentSize is set to bigFrame.size. GraphView draws expected data correctly, and is scrollable as expected, getting to left and right edges.

The problem is that the graph spills out of the screen at the bottom, and doesn’t seem to start directly at the bottom of the navigation bar. I’ve searched here, and other pages, for awhile on frames/bounds/'view programming guide for iOS/etc., and can modify size and placement of the graph, but the code would be a real mess, and I’d like it to be dynamic/parameterizable, since it needs to work when rotated. So is there a standard sequence of what to init each piece with in the hierarchy, origin/size-wise? I’ve been logging each piece’s screen/window/view/navbar frame and bounds, but it’s not clear where things first go astray. Thanks for any guidance.

In AppDelegate:

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; CGRect screenBounds=[[UIScreen mainScreen] bounds]; NSLog(@"%s screenBounds (x,y,w,h)=%f,%f,%f,%f",__func__,screenBounds.origin.x,screenBounds.origin.y,screenBounds.size.width,screenBounds.size.height); CGRect screenAppFrame=[[UIScreen mainScreen] applicationFrame]; NSLog(@"%s screenAppFrame (x,y,w,h)=%f,%f,%f,%f",__func__,screenAppFrame.origin.x,screenAppFrame.origin.y,screenAppFrame.size.width,screenAppFrame.size.height); // Override point for customization after application launch. MenuViewController *menuViewController=[[MenuViewController alloc] init]; // Create an instance of a UINavigationController, and make menuViewController the root. Set menuViewController's NavigationItem's Title. UINavigationController *navController=[[UINavigationController alloc] initWithRootViewController:menuViewController]; //self.window.backgroundColor = [UIColor whiteColor]; // Place navigation controller's view in the window hierarchy. [[self window] setRootViewController:navController]; [self.window makeKeyAndVisible];
A table/menu pick while in ManuViewController displays a GraphViewController:

if ([indexPath row] == 4) { // Show a summary of recent everything. GraphViewController *graphViewController=[[GraphViewController alloc] init]; // How to set new controller's title? [[self navigationController] pushViewController:graphViewController animated:YES]; }
GraphViewController establishes a graphScrollView:

codeloadView {
NSLog(@"%s",func);
// Get size that drawing will occur in. Use ‘bounds’ vs. ‘applicationFrame’?
// Hmmm, even though searches suggest appFrame, this covers the nav bar, so back to ‘bounds’.
CGRect screenBounds=[[UIScreen mainScreen] bounds];
NSLog(@"%s screenBounds (x,y,w,h)=%f,%f,%f,%f",func,screenBounds.origin.x,screenBounds.origin.y,screenBounds.size.width,screenBounds.size.height);
CGRect screenAppFrame=[[UIScreen mainScreen] applicationFrame];
NSLog(@"%s screenAppFrame (x,y,w,h)=%f,%f,%f,%f",func,screenAppFrame.origin.x,screenAppFrame.origin.y,screenAppFrame.size.width,screenAppFrame.size.height);
screenAppFrame.size.height-=self.navigationController.navigationBar.frame.size.height; // Reduce height by navBar height. Crude, but works.
screenAppFrame.size.height-=20; // Reduce height by 20px band below navBar, but not sure why. Crude, but works.
NSLog(@"%s screenAppFrameAdjusted (x,y,w,h)=%f,%f,%f,%f",func,screenAppFrame.origin.x,screenAppFrame.origin.y,screenAppFrame.size.width,screenAppFrame.size.height);
// NSLog(@“self.view.bounds (x,y,w,h)=%f,%f,%f,%f”,self.view.bounds.origin.x,self.view.bounds.origin.y,self.view.bounds.size.width,self.view.bounds.size.height); // Loops forever!
NSLog(@"%s selfNavContViewBounds (x,y,w,h) %f,%f %f,%f",func,self.navigationController.view.bounds.origin.x,self.navigationController.view.bounds.origin.y,self.navigationController.view.bounds.size.width,self.navigationController.view.bounds.size.height);
NSLog(@"%s selfNavContBarFrame (x,y,w,h) %f,%f %f,%f",func,self.navigationController.navigationBar.frame.origin.x,self.navigationController.navigationBar.frame.origin.y,self.navigationController.navigationBar.frame.size.width,self.navigationController.navigationBar.frame.size.height);
UIScrollView *graphScrollView=[[UIScrollView alloc] initWithFrame:screenAppFrame];
// UIScrollView graphScrollView=[[UIScrollView alloc] initWithFrame:self.view.bounds]; // This loops forever! Hmmm, self.view seems like a killer!
// Display the scrollView.
[self setView:graphScrollView];
// Compute the total drawn area that the scrollView is a window into. Base on number of meals, but just use a larger frame for now.
CGRect bigFrame=screenAppFrame;
bigFrame.size.width
=2.0;
// Give the total drawing area to the actual drawing object.
GraphView *graphView=[[GraphView alloc] initWithFrame];
// Make the scrollView display content from the actual drawing object.
[graphScrollView addSubview:graphView];
// Inform scrollView of total drawn information.
[graphScrollView setContentSize:bigFrame.size];[/code]
GraphView’s drawRect then draws:

- (void)drawRect:(CGRect)rect { NSLog(@"%s",__func__); NSLog(@"%s Called with rect (x,y,w,h)=%f,%f,%f,%f)",__func__,rect.origin.x,rect.origin.y,rect.size.width,rect.size.height); CGRect bounds=[self bounds]; NSLog(@"%s selfBounds (x,y,w,h)=%f,%f,%f,%f",__func__,bounds.origin.x,bounds.origin.y,bounds.size.width,bounds.size.height); CGRect frame=[self frame]; NSLog(@"%s selfFrame (x,y,w,h)=%f,%f,%f,%f",__func__,frame.origin.x,frame.origin.y,frame.size.width,frame.size.height); for (MealItem *meal in allMeals) { mealDate=[meal dateCreated]; x=([mealDate timeIntervalSinceReferenceDate]-[earliestDate timeIntervalSinceReferenceDate])/dateRange*bounds.size.width+bounds.origin.x; // Plot Carb point for meal carb=[meal totalCarb]; yCarb=bounds.origin.y+bounds.size.height-carb/maxCarb*bounds.size.height; //NSLog(@"x,yCarb=%f,%f",x,yCarb); CGContextBeginPath(contextRef); CGContextAddArc(contextRef, x, yCarb, dotSize/2, 0, 2*M_1_PI, YES); CGContextClosePath(contextRef); CGContextSetRGBStrokeColor(contextRef, 1, 0, 0, 1); CGContextSetRGBFillColor(contextRef, 1, 0, 0, 1); CGContextDrawPath(contextRef, kCGPathFillStroke);
Logging:

2014-03-15 14:30:29.484 Pump[306:c07] -[PumpAppDelegate application:didFinishLaunchingWithOptions:] 2014-03-15 14:30:29.485 Pump[306:c07] -[PumpAppDelegate application:didFinishLaunchingWithOptions:] screenBounds (x,y,w,h)=0.000000,0.000000,320.000000,480.000000 2014-03-15 14:30:29.486 Pump[306:c07] -[PumpAppDelegate application:didFinishLaunchingWithOptions:] screenAppFrame (x,y,w,h)=0.000000,20.000000,320.000000,460.000000 2014-03-15 14:30:29.486 Pump[306:c07] -[MenuViewController init] 2014-03-15 14:30:29.490 Pump[306:c07] -[MenuViewController init] MenuViewContView (init) frame org, size: 0.000000,20.000000 320.000000,460.000000 2014-03-15 14:30:29.490 Pump[306:c07] -[MenuViewController init] MenuViewContView (init) bounds org, size: 0.000000,0.000000 320.000000,460.000000 2014-03-15 14:30:29.501 Pump[306:c07] -[PumpAppDelegate application:didFinishLaunchingWithOptions:] selfWindow frame org, size: 0.000000,0.000000 320.000000,480.000000 2014-03-15 14:30:29.501 Pump[306:c07] -[PumpAppDelegate application:didFinishLaunchingWithOptions:] selfWindow bounds org, size: 0.000000,0.000000 320.000000,480.000000 2014-03-15 14:30:29.520 Pump[306:c07] -[PumpAppDelegate application:didFinishLaunchingWithOptions:] navigationBar frame org, size: 0.000000,20.000000 320.000000,44.000000 2014-03-15 14:30:29.520 Pump[306:c07] -[PumpAppDelegate application:didFinishLaunchingWithOptions:] navigationBar bounds org, size: 0.000000,0.000000 320.000000,44.000000 2014-03-15 14:30:29.520 Pump[306:c07] -[PumpAppDelegate application:didFinishLaunchingWithOptions:] navcontrollerView frame org, size: 0.000000,0.000000 320.000000,480.000000 2014-03-15 14:30:29.521 Pump[306:c07] -[PumpAppDelegate application:didFinishLaunchingWithOptions:] navcontrollerView bounds org, size: 0.000000,0.000000 320.000000,480.000000 2014-03-15 14:30:29.521 Pump[306:c07] -[PumpAppDelegate application:didFinishLaunchingWithOptions:] menuViewContView frame org, size: 0.000000,0.000000 320.000000,416.000000 2014-03-15 14:30:29.521 Pump[306:c07] -[PumpAppDelegate application:didFinishLaunchingWithOptions:] menuViewContView bounds org, size: 0.000000,0.000000 320.000000,416.000000 2014-03-15 14:30:31.652 Pump[306:c07] -[MenuViewController tableView:didSelectRowAtIndexPath:] 2014-03-15 14:30:31.655 Pump[306:c07] -[GraphViewController init] 2014-03-15 14:30:31.656 Pump[306:c07] -[GraphViewController loadView] 2014-03-15 14:30:31.656 Pump[306:c07] -[GraphViewController loadView] screenBounds (x,y,w,h)=0.000000,0.000000,320.000000,480.000000 2014-03-15 14:30:31.656 Pump[306:c07] -[GraphViewController loadView] screenAppFrame (x,y,w,h)=0.000000,20.000000,320.000000,460.000000 2014-03-15 14:30:31.657 Pump[306:c07] -[GraphViewController loadView] screenAppFrameAdjusted (x,y,w,h)=0.000000,20.000000,320.000000,440.000000 2014-03-15 14:30:31.657 Pump[306:c07] -[GraphViewController loadView] selfNavContViewBounds (x,y,w,h) 0.000000,0.000000 0.000000,0.000000 2014-03-15 14:30:31.657 Pump[306:c07] -[GraphViewController loadView] selfNavContBarFrame (x,y,w,h) 0.000000,0.000000 0.000000,0.000000 2014-03-15 14:30:31.657 Pump[306:c07] -[GraphView initWithFrame:] 2014-03-15 14:30:31.658 Pump[306:c07] -[GraphView initWithFrame:] InitWithFrame=(x,y,w,h)=0.000000,20.000000,640.000000,440.000000 2014-03-15 14:30:31.658 Pump[306:c07] -[GraphViewController viewDidLoad] 2014-03-15 14:30:31.658 Pump[306:c07] -[GraphViewController init] GraphViewContView (init) frame org, size: 0.000000,20.000000 320.000000,440.000000 2014-03-15 14:30:31.659 Pump[306:c07] -[GraphViewController init] GraphViewContView (init) bounds org, size: 0.000000,0.000000 320.000000,440.000000 2014-03-15 14:30:31.659 Pump[306:c07] -[MenuViewController tableView:didSelectRowAtIndexPath:] navcontrollerView frame org, size: 0.000000,0.000000 320.000000,480.000000 2014-03-15 14:30:31.660 Pump[306:c07] -[MenuViewController tableView:didSelectRowAtIndexPath:] navcontrollerView bounds org, size: 0.000000,0.000000 320.000000,480.000000 2014-03-15 14:30:31.660 Pump[306:c07] -[GraphView drawRect:] 2014-03-15 14:30:31.661 Pump[306:c07] -[GraphView drawRect:] Called with rect (x,y,w,h)=0.000000,0.000000,640.000000,440.000000) 2014-03-15 14:30:31.661 Pump[306:c07] -[GraphView drawRect:] selfBounds (x,y,w,h)=0.000000,0.000000,640.000000,440.000000 2014-03-15 14:30:31.661 Pump[306:c07] -[GraphView drawRect:] selfFrame (x,y,w,h)=0.000000,20.000000,640.000000,440.000000
Not sure how to post a picture. But there’s a 20p black space from the bottom of the nav bar to the top of my graph where I have a max-valued data point, and the lower part of the graph spills below the bottom of the actual screen.