I am creating something similar to a SplitFrameViewController, but with enough differences that I am making a custom implementation. My problem arises when I am trying to size the “Master” view to be 25% of the available screen and the “Detail” view to be the remaining 75%.
No matter what I try though, the size is incorrect. The MasterView is much too wide and the Detail overlaps a bit. I think I might be doing something incorrect in my nib files, but I’m not quite sure. The resulting sizes on the iPad emulator looks like about 35% for the master view and about 80% for the detail view.
Also, if anyone has any criticism/comments/suggestions on my project structure, feel free to comment on that as well, as this is my first attempt.
AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.containerViewController = [[ContainerViewController alloc] init];
self.window.rootViewController = self.containerViewController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
ContainerViewController
I have checked the widths of the resulting rectangles in viewWillAppear, and they are correct.
- (id)init
{
self = [super init];
if (self) {
self.masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil];
self.detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
[self addChildViewController:self.masterViewController];
[self addChildViewController:self.detailViewController];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view addSubview:self.masterViewController.view];
[self.masterViewController didMoveToParentViewController:self];
[self.view addSubview:self.detailViewController.view];
[self.detailViewController didMoveToParentViewController:self];
}
- (void)viewDidUnload
{
self.masterViewController = nil;
self.detailViewController = nil;
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
CGRect containerBounds = self.view.bounds;
CGRect masterBounds, detailBounds;
CGRectDivide(containerBounds, &masterBounds, &detailBounds, CGRectGetWidth(containerBounds) * 0.25, CGRectMinXEdge);
self.masterViewController.view.frame = masterBounds;
self.detailViewController.view.frame = detailBounds;
}
Edit
I added the following lines to the end of viewWillAppear and got the commented results.
NSLog(@"container bounds: %@", NSStringFromCGRect(containerBounds));
NSLog(@"master bounds: %@", NSStringFromCGRect(masterBounds));
NSLog(@"detail bounds: %@", NSStringFromCGRect(detailBounds));
// container bounds: {{0, 0}, {768, 1004}}
// master bounds: {{0, 0}, {192, 1004}}
// detail bounds: {{0, 0}, {576, 1004}}
Oh my gosh I figured it out. So I am running my application only in Landscape orientation. But I was getting the frame measurements in Portrait mode. Apparently, even if it only launches, runs, and supports landscape mode, it first creates the view in portrait mode and then switches to landscape mode. ViewWillAppear was running before the switch (even though everything I have read says it is supposed to go after). I moved the code in my
ViewWillAppearblock to(void)viewWillLayoutSubviewsand it worked fine.Another reason that there might have been an issue is that technically my RootViewController’s view property shouldn’t exist, although it was returning values from within the class, just not outside of it. Honestly just odd behavior in general. Anyway, if anyone else has this problem, that’s the answer.