UISplitViewController Detail view without resizing when rotated

I hope I can describe this situation correctly. It's easy to see on screen when this is happening, but difficult to explain in words, but I'll do my best.

I have a UISplitViewController with a fixed main view (UITableView) and one of two Detail views, depending on which cell is affected in the Master. Each of the Detail views is also a UITableView. I used the Todd Bates transform from the Apple MultipleDetailViews example to use storyboards as the basis for my code ( Adventures in UISplitViewController ).

I use storyboards so it’s because the explaining part is getting tricky. The wizard and the first displayed detail view navigation controllers are connected to the storyboard as a relationship to the UISplitViewController. The second detailed navigation controller is just in the storyboard with no connections.

Here's the problem. Part No. 1 is active in landscape mode, and part No. 2 is active by clicking on a line in the Wizard. The iPad has been rotated to portrait mode, which causes part # 2 to be properly resized for portrait mode. Part No. 1 is set as active by clicking on a line in the Wizard. Part # 1 is the same size as when it was last displayed in landscape mode, it doesn't fill the screen as it should.

My question is, can I tell the controller of a part that is not currently showing to resize when the orientation changes? Or maybe a better question is how to resize the displayed part that was just displayed to fill a portion of the UISplitView part?

Hopefully I've described this in enough detail so that someone can help.

The UISplitViewControllerDelegate methods are implemented in the Manager class, which should forward these calls to the detail view controllers. Here's the implementation for this method:

#pragma mark - UISplitViewControllerDelegate

/* forward the message to the current detail view
 * all detail views must implement UISplitViewControllerDelegate
 */
-(void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc
{
    self.masterBarButtonItem = barButtonItem;
    self.masterPopoverController = pc;

    barButtonItem.title = NSLocalizedString(@"Games", @"Games");

    [self.currentDetailController.navigationItem setLeftBarButtonItem:self.masterBarButtonItem animated:YES];
}

/* forward the message to the current detail view
 * all detail views must implement UISplitViewControllerDelegate
 */
-(void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
    self.masterBarButtonItem = nil;
    self.masterPopoverController = nil;

    [self.currentDetailController.navigationItem setLeftBarButtonItem:nil animated:YES];
}

      

And I've implemented the following in each of the detail view controllers:

#pragma mark - Split view

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
    barButtonItem.title = NSLocalizedString(@"Games", @"Games");
    [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
    self.masterPopoverController = popoverController;
}

- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
    // Called when the view is shown again in the split view, invalidating the button and popover controller.
    [self.navigationItem setLeftBarButtonItem:nil animated:YES];
    self.masterPopoverController = nil;
}

      

The problem is that none of the verbose controllers receive these messages. I don't see how they work anyway ...

I don't see how redirecting didRotateFromInterfaceOrientation: will cause the part controller to not show on resize. From Apple documentation:

When the orientation of an iOS device changes, the system sends a UIDeviceOrientationDidChangeNotification notification to let any interested parties know that a change has occurred. By default, the UIKit framework intercepts this notification and uses it to automatically update the orientation of the interface. This means that with a few exceptions, you don't need to handle this notification at all. Instead, all you have to do is implement appropriate methods in the view controller classes to respond to orientation changes.

The window object does most of the work associated with changing the current orientation. However, it works in conjunction with the root view controller to determine if an orientation change should occur, and if so, what additional methods should be called to respond to the change. If this controller is a container, it can rely on the child to decide if there should be an orientation.

When a rotation occurs, the view controller's methods are called at different stages of the rotation to give the view controller the ability to perform additional tasks. You can use these techniques to hide or view views, change location or resize, or notify other parts of your application to change orientation. Since you are calling your own methods during the rotation operation, you should avoid performing any tedious operations. You should also avoid replacing the entire view hierarchy with a new set of views. There are better ways to provide unique views for different orientations, such as presenting a new view controller (as described in the Creating an Alternate Landscape Interface section).

+3


source to share


2 answers


I solved my problem. In the code that swaps the Details views, I set the rendered view to the same size as the rendered view. I still have additional tests, but this solution looks like a winner.



+1


source


Similar to the splitViewController methods, you should forward the following call:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    // Forward to detail view controller here:

}

      



to a detail view controller that is NOT visible (i.e. NOT self.currentDetailController, but another one).

+1


source







All Articles