project_files/HedgewarsMobile/MGSplitViewController.m
changeset 6658 2cccf6b2b89d
equal deleted inserted replaced
6657:e1125559359f 6658:2cccf6b2b89d
       
     1 //
       
     2 //  MGSplitViewController.m
       
     3 //  MGSplitView
       
     4 //
       
     5 //  Created by Matt Gemmell on 26/07/2010.
       
     6 //  Copyright 2010 Instinctive Code.
       
     7 //
       
     8 
       
     9 #import "MGSplitViewController.h"
       
    10 #import "MGSplitDividerView.h"
       
    11 #import "MGSplitCornersView.h"
       
    12 
       
    13 #define MG_DEFAULT_SPLIT_POSITION		320.0	// default width of master view in UISplitViewController.
       
    14 #define MG_DEFAULT_SPLIT_WIDTH			1.0		// default width of split-gutter in UISplitViewController.
       
    15 #define MG_DEFAULT_CORNER_RADIUS		5.0		// default corner-radius of overlapping split-inner corners on the master and detail views.
       
    16 #define MG_DEFAULT_CORNER_COLOR			[UIColor blackColor]	// default color of intruding inner corners (and divider background).
       
    17 
       
    18 #define MG_PANESPLITTER_CORNER_RADIUS	0.0		// corner-radius of split-inner corners for MGSplitViewDividerStylePaneSplitter style.
       
    19 #define MG_PANESPLITTER_SPLIT_WIDTH		25.0	// width of split-gutter for MGSplitViewDividerStylePaneSplitter style.
       
    20 
       
    21 #define MG_MIN_VIEW_WIDTH				200.0	// minimum width a view is allowed to become as a result of changing the splitPosition.
       
    22 
       
    23 #define MG_ANIMATION_CHANGE_SPLIT_ORIENTATION	@"ChangeSplitOrientation"	// Animation ID for internal use.
       
    24 #define MG_ANIMATION_CHANGE_SUBVIEWS_ORDER		@"ChangeSubviewsOrder"	// Animation ID for internal use.
       
    25 
       
    26 
       
    27 @interface MGSplitViewController (MGPrivateMethods)
       
    28 
       
    29 - (void)setup;
       
    30 - (CGSize)splitViewSizeForOrientation:(UIInterfaceOrientation)theOrientation;
       
    31 - (void)layoutSubviews;
       
    32 - (void)layoutSubviewsWithAnimation:(BOOL)animate;
       
    33 - (void)layoutSubviewsForInterfaceOrientation:(UIInterfaceOrientation)theOrientation withAnimation:(BOOL)animate;
       
    34 - (BOOL)shouldShowMasterForInterfaceOrientation:(UIInterfaceOrientation)theOrientation;
       
    35 - (BOOL)shouldShowMaster;
       
    36 - (NSString *)nameOfInterfaceOrientation:(UIInterfaceOrientation)theOrientation;
       
    37 - (void)reconfigureForMasterInPopover:(BOOL)inPopover;
       
    38 
       
    39 @end
       
    40 
       
    41 
       
    42 @implementation MGSplitViewController
       
    43 
       
    44 
       
    45 #pragma mark -
       
    46 #pragma mark Orientation helpers
       
    47 
       
    48 
       
    49 - (NSString *)nameOfInterfaceOrientation:(UIInterfaceOrientation)theOrientation
       
    50 {
       
    51 	NSString *orientationName = nil;
       
    52 	switch (theOrientation) {
       
    53 		case UIInterfaceOrientationPortrait:
       
    54 			orientationName = @"Portrait"; // Home button at bottom
       
    55 			break;
       
    56 		case UIInterfaceOrientationPortraitUpsideDown:
       
    57 			orientationName = @"Portrait (Upside Down)"; // Home button at top
       
    58 			break;
       
    59 		case UIInterfaceOrientationLandscapeLeft:
       
    60 			orientationName = @"Landscape (Left)"; // Home button on left
       
    61 			break;
       
    62 		case UIInterfaceOrientationLandscapeRight:
       
    63 			orientationName = @"Landscape (Right)"; // Home button on right
       
    64 			break;
       
    65 		default:
       
    66 			break;
       
    67 	}
       
    68 	
       
    69 	return orientationName;
       
    70 }
       
    71 
       
    72 
       
    73 - (BOOL)isLandscape
       
    74 {
       
    75 	return UIInterfaceOrientationIsLandscape(self.interfaceOrientation);
       
    76 }
       
    77 
       
    78 
       
    79 - (BOOL)shouldShowMasterForInterfaceOrientation:(UIInterfaceOrientation)theOrientation
       
    80 {
       
    81 	// Returns YES if master view should be shown directly embedded in the splitview, instead of hidden in a popover.
       
    82 	return ((UIInterfaceOrientationIsLandscape(theOrientation)) ? _showsMasterInLandscape : _showsMasterInPortrait);
       
    83 }
       
    84 
       
    85 
       
    86 - (BOOL)shouldShowMaster
       
    87 {
       
    88 	return [self shouldShowMasterForInterfaceOrientation:self.interfaceOrientation];
       
    89 }
       
    90 
       
    91 
       
    92 - (BOOL)isShowingMaster
       
    93 {
       
    94 	return [self shouldShowMaster] && self.masterViewController && self.masterViewController.view && ([self.masterViewController.view superview] == self.view);
       
    95 }
       
    96 
       
    97 
       
    98 #pragma mark -
       
    99 #pragma mark Setup and Teardown
       
   100 
       
   101 
       
   102 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
       
   103 {
       
   104 	if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
       
   105 		[self setup];
       
   106 	}
       
   107 	
       
   108 	return self;
       
   109 }
       
   110 
       
   111 
       
   112 - (id)initWithCoder:(NSCoder *)aDecoder
       
   113 {
       
   114 	if ((self = [super initWithCoder:aDecoder])) {
       
   115 		[self setup];
       
   116 	}
       
   117 	
       
   118 	return self;
       
   119 }
       
   120 
       
   121 
       
   122 - (void)setup
       
   123 {
       
   124 	// Configure default behaviour.
       
   125 	_viewControllers = [[NSMutableArray alloc] initWithObjects:[NSNull null], [NSNull null], nil];
       
   126 	_splitWidth = MG_DEFAULT_SPLIT_WIDTH;
       
   127 	_showsMasterInPortrait = NO;
       
   128 	_showsMasterInLandscape = YES;
       
   129 	_reconfigurePopup = NO;
       
   130 	_vertical = YES;
       
   131 	_masterBeforeDetail = YES;
       
   132 	_splitPosition = MG_DEFAULT_SPLIT_POSITION;
       
   133 	CGRect divRect = self.view.bounds;
       
   134 	if ([self isVertical]) {
       
   135 		divRect.origin.y = _splitPosition;
       
   136 		divRect.size.height = _splitWidth;
       
   137 	} else {
       
   138 		divRect.origin.x = _splitPosition;
       
   139 		divRect.size.width = _splitWidth;
       
   140 	}
       
   141 	_dividerView = [[MGSplitDividerView alloc] initWithFrame:divRect];
       
   142 	_dividerView.splitViewController = self;
       
   143 	_dividerView.backgroundColor = MG_DEFAULT_CORNER_COLOR;
       
   144 	_dividerStyle = MGSplitViewDividerStyleThin;
       
   145 }
       
   146 
       
   147 
       
   148 - (void)dealloc
       
   149 {
       
   150 	_delegate = nil;
       
   151 	[self.view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
       
   152 	[_viewControllers release];
       
   153 	[_barButtonItem release];
       
   154 	[_hiddenPopoverController release];
       
   155 	[_dividerView release];
       
   156 	[_cornerViews release];
       
   157 	
       
   158 	[super dealloc];
       
   159 }
       
   160 
       
   161 
       
   162 #pragma mark -
       
   163 #pragma mark View management
       
   164 
       
   165 
       
   166 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
       
   167 {
       
   168     return YES;
       
   169 }
       
   170 
       
   171 
       
   172 - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
       
   173 {
       
   174 	[self.masterViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
       
   175 	[self.detailViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
       
   176 }
       
   177 
       
   178 
       
   179 - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
       
   180 {
       
   181 	[self.masterViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
       
   182 	[self.detailViewController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
       
   183 }
       
   184 
       
   185 
       
   186 - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 
       
   187 										 duration:(NSTimeInterval)duration
       
   188 {
       
   189 	[self.masterViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
       
   190 	[self.detailViewController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
       
   191 	
       
   192 	// Hide popover.
       
   193 	if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
       
   194 		[_hiddenPopoverController dismissPopoverAnimated:NO];
       
   195 	}
       
   196 	
       
   197 	// Re-tile views.
       
   198 	_reconfigurePopup = YES;
       
   199 	[self layoutSubviewsForInterfaceOrientation:toInterfaceOrientation withAnimation:YES];
       
   200 }
       
   201 
       
   202 
       
   203 - (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
       
   204 {
       
   205 	[self.masterViewController willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
       
   206 	[self.detailViewController willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
       
   207 }
       
   208 
       
   209 
       
   210 - (void)didAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
       
   211 {
       
   212 	[self.masterViewController didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
       
   213 	[self.detailViewController didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
       
   214 }
       
   215 
       
   216 
       
   217 - (void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation duration:(NSTimeInterval)duration
       
   218 {
       
   219 	[self.masterViewController willAnimateSecondHalfOfRotationFromInterfaceOrientation:fromInterfaceOrientation duration:duration];
       
   220 	[self.detailViewController willAnimateSecondHalfOfRotationFromInterfaceOrientation:fromInterfaceOrientation duration:duration];
       
   221 }
       
   222 
       
   223 
       
   224 - (CGSize)splitViewSizeForOrientation:(UIInterfaceOrientation)theOrientation
       
   225 {
       
   226 	UIScreen *screen = [UIScreen mainScreen];
       
   227 	CGRect fullScreenRect = screen.bounds; // always implicitly in Portrait orientation.
       
   228 	CGRect appFrame = screen.applicationFrame;
       
   229 	
       
   230 	// Find status bar height by checking which dimension of the applicationFrame is narrower than screen bounds.
       
   231 	// Little bit ugly looking, but it'll still work even if they change the status bar height in future.
       
   232 	float statusBarHeight = MAX((fullScreenRect.size.width - appFrame.size.width), (fullScreenRect.size.height - appFrame.size.height));
       
   233 	
       
   234 	// Initially assume portrait orientation.
       
   235 	float width = fullScreenRect.size.width;
       
   236 	float height = fullScreenRect.size.height;
       
   237 	
       
   238 	// Correct for orientation.
       
   239 	if (UIInterfaceOrientationIsLandscape(theOrientation)) {
       
   240 		width = height;
       
   241 		height = fullScreenRect.size.width;
       
   242 	}
       
   243 	
       
   244 	// Account for status bar, which always subtracts from the height (since it's always at the top of the screen).
       
   245 	height -= statusBarHeight;
       
   246 	
       
   247 	return CGSizeMake(width, height);
       
   248 }
       
   249 
       
   250 
       
   251 - (void)layoutSubviewsForInterfaceOrientation:(UIInterfaceOrientation)theOrientation withAnimation:(BOOL)animate
       
   252 {
       
   253 	if (_reconfigurePopup) {
       
   254 		[self reconfigureForMasterInPopover:![self shouldShowMasterForInterfaceOrientation:theOrientation]];
       
   255 	}
       
   256 	
       
   257 	// Layout the master, detail and divider views appropriately, adding/removing subviews as needed.
       
   258 	// First obtain relevant geometry.
       
   259 	CGSize fullSize = [self splitViewSizeForOrientation:theOrientation];
       
   260 	float width = fullSize.width;
       
   261 	float height = fullSize.height;
       
   262 	
       
   263 	if (NO) { // Just for debugging.
       
   264 		NSLog(@"Target orientation is %@, dimensions will be %.0f x %.0f", 
       
   265 			  [self nameOfInterfaceOrientation:theOrientation], width, height);
       
   266 	}
       
   267 	
       
   268 	// Layout the master, divider and detail views.
       
   269 	CGRect newFrame = CGRectMake(0, 0, width, height);
       
   270 	UIViewController *controller;
       
   271 	UIView *theView;
       
   272 	BOOL shouldShowMaster = [self shouldShowMasterForInterfaceOrientation:theOrientation];
       
   273 	BOOL masterFirst = [self isMasterBeforeDetail];
       
   274 	if ([self isVertical]) {
       
   275 		// Master on left, detail on right (or vice versa).
       
   276 		CGRect masterRect, dividerRect, detailRect;
       
   277 		if (masterFirst) {
       
   278 			if (!shouldShowMaster) {
       
   279 				// Move off-screen.
       
   280 				newFrame.origin.x -= (_splitPosition + _splitWidth);
       
   281 			}
       
   282 			
       
   283 			newFrame.size.width = _splitPosition;
       
   284 			masterRect = newFrame;
       
   285 			
       
   286 			newFrame.origin.x += newFrame.size.width;
       
   287 			newFrame.size.width = _splitWidth;
       
   288 			dividerRect = newFrame;
       
   289 			
       
   290 			newFrame.origin.x += newFrame.size.width;
       
   291 			newFrame.size.width = width - newFrame.origin.x;
       
   292 			detailRect = newFrame;
       
   293 			
       
   294 		} else {
       
   295 			if (!shouldShowMaster) {
       
   296 				// Move off-screen.
       
   297 				newFrame.size.width += (_splitPosition + _splitWidth);
       
   298 			}
       
   299 			
       
   300 			newFrame.size.width -= (_splitPosition + _splitWidth);
       
   301 			detailRect = newFrame;
       
   302 			
       
   303 			newFrame.origin.x += newFrame.size.width;
       
   304 			newFrame.size.width = _splitWidth;
       
   305 			dividerRect = newFrame;
       
   306 			
       
   307 			newFrame.origin.x += newFrame.size.width;
       
   308 			newFrame.size.width = _splitPosition;
       
   309 			masterRect = newFrame;
       
   310 		}
       
   311 		
       
   312 		// Position master.
       
   313 		controller = self.masterViewController;
       
   314 		if (controller && [controller isKindOfClass:[UIViewController class]])  {
       
   315 			theView = controller.view;
       
   316 			if (theView) {
       
   317 				theView.frame = masterRect;
       
   318 				if (!theView.superview) {
       
   319 					[controller viewWillAppear:NO];
       
   320 					[self.view addSubview:theView];
       
   321 					[controller viewDidAppear:NO];
       
   322 				}
       
   323 			}
       
   324 		}
       
   325 		
       
   326 		// Position divider.
       
   327 		theView = _dividerView;
       
   328 		theView.frame = dividerRect;
       
   329 		if (!theView.superview) {
       
   330 			[self.view addSubview:theView];
       
   331 		}
       
   332 		
       
   333 		// Position detail.
       
   334 		controller = self.detailViewController;
       
   335 		if (controller && [controller isKindOfClass:[UIViewController class]])  {
       
   336 			theView = controller.view;
       
   337 			if (theView) {
       
   338 				theView.frame = detailRect;
       
   339 				if (!theView.superview) {
       
   340 					[self.view insertSubview:theView aboveSubview:self.masterViewController.view];
       
   341 				} else {
       
   342 					[self.view bringSubviewToFront:theView];
       
   343 				}
       
   344 			}
       
   345 		}
       
   346 		
       
   347 	} else {
       
   348 		// Master above, detail below (or vice versa).
       
   349 		CGRect masterRect, dividerRect, detailRect;
       
   350 		if (masterFirst) {
       
   351 			if (!shouldShowMaster) {
       
   352 				// Move off-screen.
       
   353 				newFrame.origin.y -= (_splitPosition + _splitWidth);
       
   354 			}
       
   355 			
       
   356 			newFrame.size.height = _splitPosition;
       
   357 			masterRect = newFrame;
       
   358 			
       
   359 			newFrame.origin.y += newFrame.size.height;
       
   360 			newFrame.size.height = _splitWidth;
       
   361 			dividerRect = newFrame;
       
   362 			
       
   363 			newFrame.origin.y += newFrame.size.height;
       
   364 			newFrame.size.height = height - newFrame.origin.y;
       
   365 			detailRect = newFrame;
       
   366 			
       
   367 		} else {
       
   368 			if (!shouldShowMaster) {
       
   369 				// Move off-screen.
       
   370 				newFrame.size.height += (_splitPosition + _splitWidth);
       
   371 			}
       
   372 			
       
   373 			newFrame.size.height -= (_splitPosition + _splitWidth);
       
   374 			detailRect = newFrame;
       
   375 			
       
   376 			newFrame.origin.y += newFrame.size.height;
       
   377 			newFrame.size.height = _splitWidth;
       
   378 			dividerRect = newFrame;
       
   379 			
       
   380 			newFrame.origin.y += newFrame.size.height;
       
   381 			newFrame.size.height = _splitPosition;
       
   382 			masterRect = newFrame;
       
   383 		}
       
   384 		
       
   385 		// Position master.
       
   386 		controller = self.masterViewController;
       
   387 		if (controller && [controller isKindOfClass:[UIViewController class]])  {
       
   388 			theView = controller.view;
       
   389 			if (theView) {
       
   390 				theView.frame = masterRect;
       
   391 				if (!theView.superview) {
       
   392 					[controller viewWillAppear:NO];
       
   393 					[self.view addSubview:theView];
       
   394 					[controller viewDidAppear:NO];
       
   395 				}
       
   396 			}
       
   397 		}
       
   398 		
       
   399 		// Position divider.
       
   400 		theView = _dividerView;
       
   401 		theView.frame = dividerRect;
       
   402 		if (!theView.superview) {
       
   403 			[self.view addSubview:theView];
       
   404 		}
       
   405 		
       
   406 		// Position detail.
       
   407 		controller = self.detailViewController;
       
   408 		if (controller && [controller isKindOfClass:[UIViewController class]])  {
       
   409 			theView = controller.view;
       
   410 			if (theView) {
       
   411 				theView.frame = detailRect;
       
   412 				if (!theView.superview) {
       
   413 					[self.view insertSubview:theView aboveSubview:self.masterViewController.view];
       
   414 				} else {
       
   415 					[self.view bringSubviewToFront:theView];
       
   416 				}
       
   417 			}
       
   418 		}
       
   419 	}
       
   420 	
       
   421 	// Create corner views if necessary.
       
   422 	MGSplitCornersView *leadingCorners; // top/left of screen in vertical/horizontal split.
       
   423 	MGSplitCornersView *trailingCorners; // bottom/right of screen in vertical/horizontal split.
       
   424 	if (!_cornerViews) {
       
   425 		CGRect cornerRect = CGRectMake(0, 0, 10, 10); // arbitrary, will be resized below.
       
   426 		leadingCorners = [[MGSplitCornersView alloc] initWithFrame:cornerRect];
       
   427 		leadingCorners.splitViewController = self;
       
   428 		leadingCorners.cornerBackgroundColor = MG_DEFAULT_CORNER_COLOR;
       
   429 		leadingCorners.cornerRadius = MG_DEFAULT_CORNER_RADIUS;
       
   430 		trailingCorners = [[MGSplitCornersView alloc] initWithFrame:cornerRect];
       
   431 		trailingCorners.splitViewController = self;
       
   432 		trailingCorners.cornerBackgroundColor = MG_DEFAULT_CORNER_COLOR;
       
   433 		trailingCorners.cornerRadius = MG_DEFAULT_CORNER_RADIUS;
       
   434 		_cornerViews = [[NSArray alloc] initWithObjects:leadingCorners, trailingCorners, nil];
       
   435 		[leadingCorners release];
       
   436 		[trailingCorners release];
       
   437 		
       
   438 	} else if ([_cornerViews count] == 2) {
       
   439 		leadingCorners = [_cornerViews objectAtIndex:0];
       
   440 		trailingCorners = [_cornerViews objectAtIndex:1];
       
   441 	}
       
   442 	
       
   443 	// Configure and layout the corner-views.
       
   444 	leadingCorners.cornersPosition = (_vertical) ? MGCornersPositionLeadingVertical : MGCornersPositionLeadingHorizontal;
       
   445 	trailingCorners.cornersPosition = (_vertical) ? MGCornersPositionTrailingVertical : MGCornersPositionTrailingHorizontal;
       
   446 	leadingCorners.autoresizingMask = (_vertical) ? UIViewAutoresizingFlexibleBottomMargin : UIViewAutoresizingFlexibleRightMargin;
       
   447 	trailingCorners.autoresizingMask = (_vertical) ? UIViewAutoresizingFlexibleTopMargin : UIViewAutoresizingFlexibleLeftMargin;
       
   448 	
       
   449 	float x, y, cornersWidth, cornersHeight;
       
   450 	CGRect leadingRect, trailingRect;
       
   451 	float radius = leadingCorners.cornerRadius;
       
   452 	if (_vertical) { // left/right split
       
   453 		cornersWidth = (radius * 2.0) + _splitWidth;
       
   454 		cornersHeight = radius;
       
   455 		x = ((shouldShowMaster) ? ((masterFirst) ? _splitPosition : width - (_splitPosition + _splitWidth)) : (0 - _splitWidth)) - radius;
       
   456 		y = 0;
       
   457 		leadingRect = CGRectMake(x, y, cornersWidth, cornersHeight); // top corners
       
   458 		trailingRect = CGRectMake(x, (height - cornersHeight), cornersWidth, cornersHeight); // bottom corners
       
   459 		
       
   460 	} else { // top/bottom split
       
   461 		x = 0;
       
   462 		y = ((shouldShowMaster) ? ((masterFirst) ? _splitPosition : height - (_splitPosition + _splitWidth)) : (0 - _splitWidth)) - radius;
       
   463 		cornersWidth = radius;
       
   464 		cornersHeight = (radius * 2.0) + _splitWidth;
       
   465 		leadingRect = CGRectMake(x, y, cornersWidth, cornersHeight); // left corners
       
   466 		trailingRect = CGRectMake((width - cornersWidth), y, cornersWidth, cornersHeight); // right corners
       
   467 	}
       
   468 	
       
   469 	leadingCorners.frame = leadingRect;
       
   470 	trailingCorners.frame = trailingRect;
       
   471 	
       
   472 	// Ensure corners are visible and frontmost.
       
   473 	if (!leadingCorners.superview) {
       
   474 		[self.view insertSubview:leadingCorners aboveSubview:self.detailViewController.view];
       
   475 		[self.view insertSubview:trailingCorners aboveSubview:self.detailViewController.view];
       
   476 	} else {
       
   477 		[self.view bringSubviewToFront:leadingCorners];
       
   478 		[self.view bringSubviewToFront:trailingCorners];
       
   479 	}
       
   480 }
       
   481 
       
   482 
       
   483 - (void)layoutSubviewsWithAnimation:(BOOL)animate
       
   484 {
       
   485 	[self layoutSubviewsForInterfaceOrientation:self.interfaceOrientation withAnimation:animate];
       
   486 }
       
   487 
       
   488 
       
   489 - (void)layoutSubviews
       
   490 {
       
   491 	[self layoutSubviewsForInterfaceOrientation:self.interfaceOrientation withAnimation:YES];
       
   492 }
       
   493 
       
   494 
       
   495 - (void)viewWillAppear:(BOOL)animated
       
   496 {
       
   497 	[super viewWillAppear:animated];
       
   498 	
       
   499 	if ([self isShowingMaster]) {
       
   500 		[self.masterViewController viewWillAppear:animated];
       
   501 	}
       
   502 	[self.detailViewController viewWillAppear:animated];
       
   503 	
       
   504 	_reconfigurePopup = YES;
       
   505 	[self layoutSubviews];
       
   506 }
       
   507 
       
   508 
       
   509 - (void)viewDidAppear:(BOOL)animated
       
   510 {
       
   511 	[super viewDidAppear:animated];
       
   512 	
       
   513 	if ([self isShowingMaster]) {
       
   514 		[self.masterViewController viewDidAppear:animated];
       
   515 	}
       
   516 	[self.detailViewController viewDidAppear:animated];
       
   517 }
       
   518 
       
   519 
       
   520 - (void)viewWillDisappear:(BOOL)animated
       
   521 {
       
   522 	[super viewWillDisappear:animated];
       
   523 	
       
   524 	if ([self isShowingMaster]) {
       
   525 		[self.masterViewController viewWillDisappear:animated];
       
   526 	}
       
   527 	[self.detailViewController viewWillDisappear:animated];
       
   528 }
       
   529 
       
   530 
       
   531 - (void)viewDidDisappear:(BOOL)animated
       
   532 {
       
   533 	[super viewDidDisappear:animated];
       
   534 	
       
   535 	if ([self isShowingMaster]) {
       
   536 		[self.masterViewController viewDidDisappear:animated];
       
   537 	}
       
   538 	[self.detailViewController viewDidDisappear:animated];
       
   539 }
       
   540 
       
   541 
       
   542 #pragma mark -
       
   543 #pragma mark Popover handling
       
   544 
       
   545 
       
   546 - (void)reconfigureForMasterInPopover:(BOOL)inPopover
       
   547 {
       
   548 	_reconfigurePopup = NO;
       
   549 	
       
   550 	if ((inPopover && _hiddenPopoverController) || (!inPopover && !_hiddenPopoverController) || !self.masterViewController) {
       
   551 		// Nothing to do.
       
   552 		return;
       
   553 	}
       
   554 	
       
   555 	if (inPopover && !_hiddenPopoverController && !_barButtonItem) {
       
   556 		// Create and configure popover for our masterViewController.
       
   557 		[_hiddenPopoverController release];
       
   558 		_hiddenPopoverController = nil;
       
   559 		[self.masterViewController viewWillDisappear:NO];
       
   560 		_hiddenPopoverController = [[UIPopoverController alloc] initWithContentViewController:self.masterViewController];
       
   561 		[self.masterViewController viewDidDisappear:NO];
       
   562 		
       
   563 		// Create and configure _barButtonItem.
       
   564 		_barButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Master", nil) 
       
   565 														  style:UIBarButtonItemStyleBordered 
       
   566 														 target:self 
       
   567 														 action:@selector(showMasterPopover:)];
       
   568 		
       
   569 		// Inform delegate of this state of affairs.
       
   570 		if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:willHideViewController:withBarButtonItem:forPopoverController:)]) {
       
   571 			[(NSObject <MGSplitViewControllerDelegate> *)_delegate splitViewController:self 
       
   572 																willHideViewController:self.masterViewController 
       
   573 																	 withBarButtonItem:_barButtonItem 
       
   574 																  forPopoverController:_hiddenPopoverController];
       
   575 		}
       
   576 		
       
   577 	} else if (!inPopover && _hiddenPopoverController && _barButtonItem) {
       
   578 		// I know this looks strange, but it fixes a bizarre issue with UIPopoverController leaving masterViewController's views in disarray.
       
   579 		[_hiddenPopoverController presentPopoverFromRect:CGRectZero inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO];
       
   580 		
       
   581 		// Remove master from popover and destroy popover, if it exists.
       
   582 		[_hiddenPopoverController dismissPopoverAnimated:NO];
       
   583 		[_hiddenPopoverController release];
       
   584 		_hiddenPopoverController = nil;
       
   585 		
       
   586 		// Inform delegate that the _barButtonItem will become invalid.
       
   587 		if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:willShowViewController:invalidatingBarButtonItem:)]) {
       
   588 			[(NSObject <MGSplitViewControllerDelegate> *)_delegate splitViewController:self 
       
   589 																willShowViewController:self.masterViewController 
       
   590 															 invalidatingBarButtonItem:_barButtonItem];
       
   591 		}
       
   592 		
       
   593 		// Destroy _barButtonItem.
       
   594 		[_barButtonItem release];
       
   595 		_barButtonItem = nil;
       
   596 		
       
   597 		// Move master view.
       
   598 		UIView *masterView = self.masterViewController.view;
       
   599 		if (masterView && masterView.superview != self.view) {
       
   600 			[masterView removeFromSuperview];
       
   601 		}
       
   602 	}
       
   603 }
       
   604 
       
   605 
       
   606 - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
       
   607 {
       
   608 	[self reconfigureForMasterInPopover:NO];
       
   609 }
       
   610 
       
   611 
       
   612 - (void)notePopoverDismissed
       
   613 {
       
   614 	[self popoverControllerDidDismissPopover:_hiddenPopoverController];
       
   615 }
       
   616 
       
   617 
       
   618 #pragma mark -
       
   619 #pragma mark Animations
       
   620 
       
   621 
       
   622 - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
       
   623 {
       
   624 	if (([animationID isEqualToString:MG_ANIMATION_CHANGE_SPLIT_ORIENTATION] || 
       
   625 		 [animationID isEqualToString:MG_ANIMATION_CHANGE_SUBVIEWS_ORDER])
       
   626 		&& _cornerViews) {
       
   627 		for (UIView *corner in _cornerViews) {
       
   628 			corner.hidden = NO;
       
   629 		}
       
   630 		_dividerView.hidden = NO;
       
   631 	}
       
   632 }
       
   633 
       
   634 
       
   635 #pragma mark -
       
   636 #pragma mark IB Actions
       
   637 
       
   638 
       
   639 - (IBAction)toggleSplitOrientation:(id)sender
       
   640 {
       
   641 	BOOL showingMaster = [self isShowingMaster];
       
   642 	if (showingMaster) {
       
   643 		if (_cornerViews) {
       
   644 			for (UIView *corner in _cornerViews) {
       
   645 				corner.hidden = YES;
       
   646 			}
       
   647 			_dividerView.hidden = YES;
       
   648 		}
       
   649 		[UIView beginAnimations:MG_ANIMATION_CHANGE_SPLIT_ORIENTATION context:nil];
       
   650 		[UIView setAnimationDelegate:self];
       
   651 		[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
       
   652 	}
       
   653 	self.vertical = (!self.vertical);
       
   654 	if (showingMaster) {
       
   655 		[UIView commitAnimations];
       
   656 	}
       
   657 }
       
   658 
       
   659 
       
   660 - (IBAction)toggleMasterBeforeDetail:(id)sender
       
   661 {
       
   662 	BOOL showingMaster = [self isShowingMaster];
       
   663 	if (showingMaster) {
       
   664 		if (_cornerViews) {
       
   665 			for (UIView *corner in _cornerViews) {
       
   666 				corner.hidden = YES;
       
   667 			}
       
   668 			_dividerView.hidden = YES;
       
   669 		}
       
   670 		[UIView beginAnimations:MG_ANIMATION_CHANGE_SUBVIEWS_ORDER context:nil];
       
   671 		[UIView setAnimationDelegate:self];
       
   672 		[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
       
   673 	}
       
   674 	self.masterBeforeDetail = (!self.masterBeforeDetail);
       
   675 	if (showingMaster) {
       
   676 		[UIView commitAnimations];
       
   677 	}
       
   678 }
       
   679 
       
   680 
       
   681 - (IBAction)toggleMasterView:(id)sender
       
   682 {
       
   683 	if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
       
   684 		[_hiddenPopoverController dismissPopoverAnimated:NO];
       
   685 	}
       
   686 	
       
   687 	if (![self isShowingMaster]) {
       
   688 		// We're about to show the master view. Ensure it's in place off-screen to be animated in.
       
   689 		_reconfigurePopup = YES;
       
   690 		[self reconfigureForMasterInPopover:NO];
       
   691 		[self layoutSubviews];
       
   692 	}
       
   693 	
       
   694 	// This action functions on the current primary orientation; it is independent of the other primary orientation.
       
   695 	[UIView beginAnimations:@"toggleMaster" context:nil];
       
   696 	if (self.isLandscape) {
       
   697 		self.showsMasterInLandscape = !_showsMasterInLandscape;
       
   698 	} else {
       
   699 		self.showsMasterInPortrait = !_showsMasterInPortrait;
       
   700 	}
       
   701 	[UIView commitAnimations];
       
   702 }
       
   703 
       
   704 
       
   705 - (IBAction)showMasterPopover:(id)sender
       
   706 {
       
   707 	if (_hiddenPopoverController && !(_hiddenPopoverController.popoverVisible)) {
       
   708 		// Inform delegate.
       
   709 		if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:popoverController:willPresentViewController:)]) {
       
   710 			[(NSObject <MGSplitViewControllerDelegate> *)_delegate splitViewController:self 
       
   711 																	 popoverController:_hiddenPopoverController 
       
   712 															 willPresentViewController:self.masterViewController];
       
   713 		}
       
   714 		
       
   715 		// Show popover.
       
   716 		[_hiddenPopoverController presentPopoverFromBarButtonItem:_barButtonItem permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
       
   717 	}
       
   718 }
       
   719 
       
   720 
       
   721 #pragma mark -
       
   722 #pragma mark Accessors and properties
       
   723 
       
   724 
       
   725 - (id)delegate
       
   726 {
       
   727 	return _delegate;
       
   728 }
       
   729 
       
   730 
       
   731 - (void)setDelegate:(id <MGSplitViewControllerDelegate>)newDelegate
       
   732 {
       
   733 	if (newDelegate != _delegate && 
       
   734 		(!newDelegate || [(NSObject *)newDelegate conformsToProtocol:@protocol(MGSplitViewControllerDelegate)])) {
       
   735 		_delegate = newDelegate;
       
   736 	}
       
   737 }
       
   738 
       
   739 
       
   740 - (BOOL)showsMasterInPortrait
       
   741 {
       
   742 	return _showsMasterInPortrait;
       
   743 }
       
   744 
       
   745 
       
   746 - (void)setShowsMasterInPortrait:(BOOL)flag
       
   747 {
       
   748 	if (flag != _showsMasterInPortrait) {
       
   749 		_showsMasterInPortrait = flag;
       
   750 		
       
   751 		if (![self isLandscape]) { // i.e. if this will cause a visual change.
       
   752 			if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
       
   753 				[_hiddenPopoverController dismissPopoverAnimated:NO];
       
   754 			}
       
   755 			
       
   756 			// Rearrange views.
       
   757 			_reconfigurePopup = YES;
       
   758 			[self layoutSubviews];
       
   759 		}
       
   760 	}
       
   761 }
       
   762 
       
   763 
       
   764 - (BOOL)showsMasterInLandscape
       
   765 {
       
   766 	return _showsMasterInLandscape;
       
   767 }
       
   768 
       
   769 
       
   770 - (void)setShowsMasterInLandscape:(BOOL)flag
       
   771 {
       
   772 	if (flag != _showsMasterInLandscape) {
       
   773 		_showsMasterInLandscape = flag;
       
   774 		
       
   775 		if ([self isLandscape]) { // i.e. if this will cause a visual change.
       
   776 			if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
       
   777 				[_hiddenPopoverController dismissPopoverAnimated:NO];
       
   778 			}
       
   779 			
       
   780 			// Rearrange views.
       
   781 			_reconfigurePopup = YES;
       
   782 			[self layoutSubviews];
       
   783 		}
       
   784 	}
       
   785 }
       
   786 
       
   787 
       
   788 - (BOOL)isVertical
       
   789 {
       
   790 	return _vertical;
       
   791 }
       
   792 
       
   793 
       
   794 - (void)setVertical:(BOOL)flag
       
   795 {
       
   796 	if (flag != _vertical) {
       
   797 		if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
       
   798 			[_hiddenPopoverController dismissPopoverAnimated:NO];
       
   799 		}
       
   800 		
       
   801 		_vertical = flag;
       
   802 		
       
   803 		// Inform delegate.
       
   804 		if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:willChangeSplitOrientationToVertical:)]) {
       
   805 			[_delegate splitViewController:self willChangeSplitOrientationToVertical:_vertical];
       
   806 		}
       
   807 		
       
   808 		[self layoutSubviews];
       
   809 	}
       
   810 }
       
   811 
       
   812 
       
   813 - (BOOL)isMasterBeforeDetail
       
   814 {
       
   815 	return _masterBeforeDetail;
       
   816 }
       
   817 
       
   818 
       
   819 - (void)setMasterBeforeDetail:(BOOL)flag
       
   820 {
       
   821 	if (flag != _masterBeforeDetail) {
       
   822 		if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
       
   823 			[_hiddenPopoverController dismissPopoverAnimated:NO];
       
   824 		}
       
   825 		
       
   826 		_masterBeforeDetail = flag;
       
   827 		
       
   828 		if ([self isShowingMaster]) {
       
   829 			[self layoutSubviews];
       
   830 		}
       
   831 	}
       
   832 }
       
   833 
       
   834 
       
   835 - (float)splitPosition
       
   836 {
       
   837 	return _splitPosition;
       
   838 }
       
   839 
       
   840 
       
   841 - (void)setSplitPosition:(float)posn
       
   842 {
       
   843 	// Check to see if delegate wishes to constrain the position.
       
   844 	float newPosn = posn;
       
   845 	BOOL constrained = NO;
       
   846 	CGSize fullSize = [self splitViewSizeForOrientation:self.interfaceOrientation];
       
   847 	if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:constrainSplitPosition:splitViewSize:)]) {
       
   848 		newPosn = [_delegate splitViewController:self constrainSplitPosition:newPosn splitViewSize:fullSize];
       
   849 		constrained = YES; // implicitly trust delegate's response.
       
   850 		
       
   851 	} else {
       
   852 		// Apply default constraints if delegate doesn't wish to participate.
       
   853 		float minPos = MG_MIN_VIEW_WIDTH;
       
   854 		float maxPos = ((_vertical) ? fullSize.width : fullSize.height) - (MG_MIN_VIEW_WIDTH + _splitWidth);
       
   855 		constrained = (newPosn != _splitPosition && newPosn >= minPos && newPosn <= maxPos);
       
   856 	}
       
   857 	
       
   858 	if (constrained) {
       
   859 		if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
       
   860 			[_hiddenPopoverController dismissPopoverAnimated:NO];
       
   861 		}
       
   862 		
       
   863 		_splitPosition = newPosn;
       
   864 		
       
   865 		// Inform delegate.
       
   866 		if (_delegate && [_delegate respondsToSelector:@selector(splitViewController:willMoveSplitToPosition:)]) {
       
   867 			[_delegate splitViewController:self willMoveSplitToPosition:_splitPosition];
       
   868 		}
       
   869 		
       
   870 		if ([self isShowingMaster]) {
       
   871 			[self layoutSubviews];
       
   872 		}
       
   873 	}
       
   874 }
       
   875 
       
   876 
       
   877 - (void)setSplitPosition:(float)posn animated:(BOOL)animate
       
   878 {
       
   879 	BOOL shouldAnimate = (animate && [self isShowingMaster]);
       
   880 	if (shouldAnimate) {
       
   881 		[UIView beginAnimations:@"SplitPosition" context:nil];
       
   882 	}
       
   883 	[self setSplitPosition:posn];
       
   884 	if (shouldAnimate) {
       
   885 		[UIView commitAnimations];
       
   886 	}
       
   887 }
       
   888 
       
   889 
       
   890 - (float)splitWidth
       
   891 {
       
   892 	return _splitWidth;
       
   893 }
       
   894 
       
   895 
       
   896 - (void)setSplitWidth:(float)width
       
   897 {
       
   898 	if (width != _splitWidth && width >= 0) {
       
   899 		_splitWidth = width;
       
   900 		if ([self isShowingMaster]) {
       
   901 			[self layoutSubviews];
       
   902 		}
       
   903 	}
       
   904 }
       
   905 
       
   906 
       
   907 - (NSArray *)viewControllers
       
   908 {
       
   909 	return [[_viewControllers copy] autorelease];
       
   910 }
       
   911 
       
   912 
       
   913 - (void)setViewControllers:(NSArray *)controllers
       
   914 {
       
   915 	if (controllers != _viewControllers) {
       
   916 		for (UIViewController *controller in _viewControllers) {
       
   917 			if ([controller isKindOfClass:[UIViewController class]]) {
       
   918 				[controller.view removeFromSuperview];
       
   919 			}
       
   920 		}
       
   921 		[_viewControllers release];
       
   922 		_viewControllers = [[NSMutableArray alloc] initWithCapacity:2];
       
   923 		if (controllers && [controllers count] >= 2) {
       
   924 			self.masterViewController = [controllers objectAtIndex:0];
       
   925 			self.detailViewController = [controllers objectAtIndex:1];
       
   926 		} else {
       
   927 			NSLog(@"Error: %@ requires 2 view-controllers. (%@)", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
       
   928 		}
       
   929 		
       
   930 		[self layoutSubviews];
       
   931 	}
       
   932 }
       
   933 
       
   934 
       
   935 - (UIViewController *)masterViewController
       
   936 {
       
   937 	if (_viewControllers && [_viewControllers count] > 0) {
       
   938 		NSObject *controller = [_viewControllers objectAtIndex:0];
       
   939 		if ([controller isKindOfClass:[UIViewController class]]) {
       
   940 			return [[controller retain] autorelease];
       
   941 		}
       
   942 	}
       
   943 	
       
   944 	return nil;
       
   945 }
       
   946 
       
   947 
       
   948 - (void)setMasterViewController:(UIViewController *)master
       
   949 {
       
   950 	if (!_viewControllers) {
       
   951 		_viewControllers = [[NSMutableArray alloc] initWithCapacity:2];
       
   952 	}
       
   953 	
       
   954 	NSObject *newMaster = master;
       
   955 	if (!newMaster) {
       
   956 		newMaster = [NSNull null];
       
   957 	}
       
   958 	
       
   959 	BOOL changed = YES;
       
   960 	if ([_viewControllers count] > 0) {
       
   961 		if ([_viewControllers objectAtIndex:0] == newMaster) {
       
   962 			changed = NO;
       
   963 		} else {
       
   964 			[_viewControllers replaceObjectAtIndex:0 withObject:newMaster];
       
   965 		}
       
   966 		
       
   967 	} else {
       
   968 		[_viewControllers addObject:newMaster];
       
   969 	}
       
   970 	
       
   971 	if (changed) {
       
   972 		[self layoutSubviews];
       
   973 	}
       
   974 }
       
   975 
       
   976 
       
   977 - (UIViewController *)detailViewController
       
   978 {
       
   979 	if (_viewControllers && [_viewControllers count] > 1) {
       
   980 		NSObject *controller = [_viewControllers objectAtIndex:1];
       
   981 		if ([controller isKindOfClass:[UIViewController class]]) {
       
   982 			return [[controller retain] autorelease];
       
   983 		}
       
   984 	}
       
   985 	
       
   986 	return nil;
       
   987 }
       
   988 
       
   989 
       
   990 - (void)setDetailViewController:(UIViewController *)detail
       
   991 {
       
   992 	if (!_viewControllers) {
       
   993 		_viewControllers = [[NSMutableArray alloc] initWithCapacity:2];
       
   994 		[_viewControllers addObject:[NSNull null]];
       
   995 	}
       
   996 	
       
   997 	BOOL changed = YES;
       
   998 	if ([_viewControllers count] > 1) {
       
   999 		if ([_viewControllers objectAtIndex:1] == detail) {
       
  1000 			changed = NO;
       
  1001 		} else {
       
  1002 			[_viewControllers replaceObjectAtIndex:1 withObject:detail];
       
  1003 		}
       
  1004 		
       
  1005 	} else {
       
  1006 		[_viewControllers addObject:detail];
       
  1007 	}
       
  1008 	
       
  1009 	if (changed) {
       
  1010 		[self layoutSubviews];
       
  1011 	}
       
  1012 }
       
  1013 
       
  1014 
       
  1015 - (MGSplitDividerView *)dividerView
       
  1016 {
       
  1017 	return [[_dividerView retain] autorelease];
       
  1018 }
       
  1019 
       
  1020 
       
  1021 - (void)setDividerView:(MGSplitDividerView *)divider
       
  1022 {
       
  1023 	if (divider != _dividerView) {
       
  1024 		[_dividerView removeFromSuperview];
       
  1025 		[_dividerView release];
       
  1026 		_dividerView = [divider retain];
       
  1027 		_dividerView.splitViewController = self;
       
  1028 		_dividerView.backgroundColor = MG_DEFAULT_CORNER_COLOR;
       
  1029 		if ([self isShowingMaster]) {
       
  1030 			[self layoutSubviews];
       
  1031 		}
       
  1032 	}
       
  1033 }
       
  1034 
       
  1035 
       
  1036 - (BOOL)allowsDraggingDivider
       
  1037 {
       
  1038 	if (_dividerView) {
       
  1039 		return _dividerView.allowsDragging;
       
  1040 	}
       
  1041 	
       
  1042 	return NO;
       
  1043 }
       
  1044 
       
  1045 
       
  1046 - (void)setAllowsDraggingDivider:(BOOL)flag
       
  1047 {
       
  1048 	if (self.allowsDraggingDivider != flag && _dividerView) {
       
  1049 		_dividerView.allowsDragging = flag;
       
  1050 	}
       
  1051 }
       
  1052 
       
  1053 
       
  1054 - (MGSplitViewDividerStyle)dividerStyle
       
  1055 {
       
  1056 	return _dividerStyle;
       
  1057 }
       
  1058 
       
  1059 
       
  1060 - (void)setDividerStyle:(MGSplitViewDividerStyle)newStyle
       
  1061 {
       
  1062 	if (_hiddenPopoverController && _hiddenPopoverController.popoverVisible) {
       
  1063 		[_hiddenPopoverController dismissPopoverAnimated:NO];
       
  1064 	}
       
  1065 	
       
  1066 	// We don't check to see if newStyle equals _dividerStyle, because it's a meta-setting.
       
  1067 	// Aspects could have been changed since it was set.
       
  1068 	_dividerStyle = newStyle;
       
  1069 	
       
  1070 	// Reconfigure general appearance and behaviour.
       
  1071 	float cornerRadius;
       
  1072 	if (_dividerStyle == MGSplitViewDividerStyleThin) {
       
  1073 		cornerRadius = MG_DEFAULT_CORNER_RADIUS;
       
  1074 		_splitWidth = MG_DEFAULT_SPLIT_WIDTH;
       
  1075 		self.allowsDraggingDivider = NO;
       
  1076 		
       
  1077 	} else if (_dividerStyle == MGSplitViewDividerStylePaneSplitter) {
       
  1078 		cornerRadius = MG_PANESPLITTER_CORNER_RADIUS;
       
  1079 		_splitWidth = MG_PANESPLITTER_SPLIT_WIDTH;
       
  1080 		self.allowsDraggingDivider = YES;
       
  1081 	}
       
  1082 	
       
  1083 	// Update divider and corners.
       
  1084 	[_dividerView setNeedsDisplay];
       
  1085 	if (_cornerViews) {
       
  1086 		for (MGSplitCornersView *corner in _cornerViews) {
       
  1087 			corner.cornerRadius = cornerRadius;
       
  1088 		}
       
  1089 	}
       
  1090 	
       
  1091 	// Layout all views.
       
  1092 	[self layoutSubviews];
       
  1093 }
       
  1094 
       
  1095 
       
  1096 - (void)setDividerStyle:(MGSplitViewDividerStyle)newStyle animated:(BOOL)animate
       
  1097 {
       
  1098 	BOOL shouldAnimate = (animate && [self isShowingMaster]);
       
  1099 	if (shouldAnimate) {
       
  1100 		[UIView beginAnimations:@"DividerStyle" context:nil];
       
  1101 	}
       
  1102 	[self setDividerStyle:newStyle];
       
  1103 	if (shouldAnimate) {
       
  1104 		[UIView commitAnimations];
       
  1105 	}
       
  1106 }
       
  1107 
       
  1108 
       
  1109 - (NSArray *)cornerViews
       
  1110 {
       
  1111 	if (_cornerViews) {
       
  1112 		return [[_cornerViews retain] autorelease];
       
  1113 	}
       
  1114 	
       
  1115 	return nil;
       
  1116 }
       
  1117 
       
  1118 
       
  1119 @synthesize showsMasterInPortrait;
       
  1120 @synthesize showsMasterInLandscape;
       
  1121 @synthesize vertical;
       
  1122 @synthesize delegate;
       
  1123 @synthesize viewControllers;
       
  1124 @synthesize masterViewController;
       
  1125 @synthesize detailViewController;
       
  1126 @synthesize dividerView;
       
  1127 @synthesize splitPosition;
       
  1128 @synthesize splitWidth;
       
  1129 @synthesize allowsDraggingDivider;
       
  1130 @synthesize dividerStyle;
       
  1131 
       
  1132 
       
  1133 @end