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