2

I'm a relative newcomer to cocoa & programming for the ipad.

I've built an app that has a split view controller. In the detail view is a toolbar with a button on it. When the button is pressed, the split view controller is removed from the superview, and another view is put in its place. A toolbar button on this new view removes the view and puts the split view back. Works great... except when the ipad is rotated while the second view is visible. When the user returns to the split view, it's displayed as it was before the rotation.

The split view and all the sub views are set to autoresize=yes, and return yes when they receive the autorotatetointerfaceorientation message.

I'm guessing I need to tell the split view and its sub views to resize themselves when I add it as a subview to the window.

Thanks Chris

Robin
  • 10,011
  • 5
  • 49
  • 75
Chris
  • 1,013
  • 1
  • 15
  • 35
  • While I am not sure how to solve your problem, I have had some problems similar to yours. The problem is that when a view is not in the view hierarchy of the main window, it is not told to rotate when the device rotates. The problem is worsened by the fact that the UISplitViewController is very rigid in what you are allowed to do with it. I am pretty sure it is not designed to be removed from the view hierarchy and re-added. Sadly, when I wanted to do more with the UISplitViewController than Apple allows you to do, I was forced to essentially build my own version of it from scratch. Not fun. – Simon Goldeen Mar 01 '11 at 04:10
  • hmmm. Is there a way to leave the split view controller in the hierarchy but not be visible? Or, barring that, perhaps I could get the orientation before removing the split view, compare to the orientation when I'm going to put it back, and tell it to rotate itself prior to adding back as a subview? – Chris Mar 01 '11 at 04:16

2 Answers2

0

Ok, I have an idea for what might work: Don't remove the UISplitViewController's view from the view hierarchy. Instead, either put a view on top of it, set the alpha property of its view to 0 or set the hidden property of its view to YES.

Simon Goldeen
  • 9,080
  • 3
  • 36
  • 45
  • Won't work, because orientation events only get sent to the first child view of UIWindow. He'll lose orientation events to the new view he's pushed on. – occulus Mar 01 '11 at 16:13
  • @occulus - is it possible to simulate the rotation by looking at the rotational state of the app before the split view is swapped out, and again when it's time to bring the split view back in? I could inform the split view of the state before bringing it back in, or I could bring it back in and them immediately fake an orientation change (by passing an event?) to get it to display properly. Thoughts? – Chris Mar 02 '11 at 03:10
0

Please see my question concerning this matter here:

Best way to switch between UISplitViewController and other view controllers?

If you use UISplitViewController as Apple intend you to, it's quite limited.

I ended up using a strategy exactly as you mention -- i.e. remove the UISplitViewController's view from UIWindow, and replace with another, and then later switch back. I found out that the orientation change WAS handled, even if I rotated while view B was presented (B being the non-split view), then switch back to A (the split view). However, I had to do a bit of fiddling with the frame size of the uisplitview to make it work. Will update with more info later when I find it.

There's also the option of writing your own split view controller, or using someone else's reimplementation, such as this one:

http://mattgemmell.com/2010/07/31/mgsplitviewcontroller-for-ipad

UPDATE

The fiddling I did with the frame size of UISplitView can be seen in the following method in my AppDelegate. These methods are for presenting the split view controller by replacing another top level view controller under UIWindow:

- (void)removeAllWindowSubviews {
    for (UIView *childView in window.subviews) {
        [childView removeFromSuperview];
    }
}

- (void)presentSplitView:(UISplitViewController *)vc {
    [self removeAllWindowSubviews];

    UIView *viewForSplitVC = vc.view;

    // fix for deficiency in adding a split view controller's view in landscape mode
    // and it still having a frame for portrait mode.
    // 2010-10-15 added -20.0f to fix problem with toolbar in LHS VC being 20 pix too low. 
    viewForSplitVC.frame = CGRectMake(viewForSplitVC.frame.origin.x, viewForSplitVC.frame.origin.y, 
                              navigationController.view.bounds.size.width, navigationController.view.bounds.size.height - 20.0f);    

    [window addSubview:viewForSplitVC];
}

// for removing the split view and restoring the other main VC
- (void)restoreMenu {
    if (isIPad()) {
        [self removeAllWindowSubviews];

        [window addSubview:navigationController.view];      
    }
}

As I said, it's a hack, but the correcting of the frame gave me the ability to present the split VC without its frame being sometimes incorrect. And as I noted earlier, by doing this stuff, we're going outside what Apple want us to do, hence the hackery involved.

Community
  • 1
  • 1
occulus
  • 16,959
  • 6
  • 53
  • 76
  • also, what fiddling did you do with the frame size to get things to fit right? I have looked at Matt Gemmell's split view implementation. I was hoping to avoid having to go that route. Thanks again. – Chris Mar 02 '11 at 03:11
  • thank you very much. I had to add viewForSplitVC.transform=CGAffineTransformIdentity to get it to work right, but otherwise this was just what I needed. Thank you. – Chris Mar 02 '11 at 15:24