简体   繁体   中英

Hidden UIView Orientation Change / Layout problems

The Problem: I have two View Controllers loaded into a root View Controller. Both sub view layouts respond to orientation changes. I switch between the two views using [UIView transformationFromView:...]. Both sub views work fine on their own, but if...

  1. Views are swapped
  2. Orientation Changes
  3. Views are swapped again

the View that was previously hidden has serious layout problems. The more I repeat these steps the worse the problem gets.

Implementation Details

I have three viewsControllers.

  1. MyAppViewController
  2. A_ViewController
  3. B_ViewController

A & B ViewControllers have a background image each, and a UIWebView and an AQGridView respectively. To give you an example of how i'm setting it all up, here's the loadView method for A_ViewController...

- (void)loadView {

    [super loadView];

    // background image
    // Should fill the screen and resize on orientation changes
    UIImageView *bg = [[UIImageView alloc] initWithFrame:self.view.bounds];
    bg.contentMode = UIViewContentModeCenter;
    bg.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    bg.image = [UIImage imageNamed:@"fuzzyhalo.png"];
    [self.view addSubview:bg];

    // frame for webView
    // Should have a margin of 34 on all sides and resize on orientation changes
    CGRect webFrame = self.view.bounds;
    webFrame.origin.x = 34;
    webFrame.origin.y = 34;
    webFrame.size.width = webFrame.size.width - 68;
    webFrame.size.height = webFrame.size.height - 68;

    projectView = [[UIWebView alloc] initWithFrame:webFrame];
    projectView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

    [self.view addSubview:projectView];

}

For the sake of brevity, the AQGridView in B_ViewController is set up pretty much the same way.

Now both these views work fine on their own. However, I use both of them in the AppViewController like this...

- (void)loadView {

        [super loadView];

        self.view.autoresizesSubviews = YES;
        [self setWantsFullScreenLayout:YES];

        webView = [[WebProjectViewController alloc] init];
        [self.view addSubview:webView.view];

        mainMenu = [[GridViewController alloc] init];
        [self.view addSubview:mainMenu.view];

        activeView = mainMenu;

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(switchViews:) name:SWAPVIEWS object:nil];


    }

and I switch betweem the two views using my own switchView method like this

- (void) switchViews:(NSNotification*)aNotification;
{
    NSString *type = [aNotification object];

    if ([type isEqualToString:MAINMENU]){
        [UIView transitionFromView:activeView.view toView:mainMenu.view duration:0.75 options:UIViewAnimationOptionTransitionFlipFromRight completion:nil];
        activeView = mainMenu;
    }

    if ([type isEqualToString:WEBVIEW]) {
        [UIView transitionFromView:activeView.view toView:webView.view duration:0.75 options:UIViewAnimationOptionTransitionFlipFromLeft completion:nil];
        activeView = webView;
    }

    // These don't seem to do anything
    //[mainMenu.view setNeedsLayout];
    //[webView.view setNeedsLayout];

}

I'm fumbling my way through this, and I suspect a lot of what i've done is implemented incorrectly so please feel free to point out anything that should be done differently, I need the input.

But my primary concern is to understand what's causing the layout problems. Here's two images which illustrate the nature of the layout issues...

UPDATE : I just noticed that when the orientation is landscape, the transition flips vertically, when I would expect it to be horizontal. I don't know wether that's a clue as to what might be going wrong.

正常布局

Switch to the other view... change orientation.... switch back....

问题布局

I just stumbled across this and have a feeling you have since figured this out. But just in case, or if someone else is searching for the same answer, this is the approach I have taken in the situation.

In each view controller's header files (the ones you switch between, not the root MyAppViewController), add a float:

float boundWidth;

In viewDidLoad, initialize it to 0

boundWidth = 0;

Then create a check such as the following:

- (void)viewDidAppear:(BOOL)animated {
// check to see what orientation the device is in;
   if ((boundWidth != 0) && (boundWidth != self.view.bounds.size.width)) {
      // the orientation has changed, so insert code to deal with this;
}

Keep track of the width by setting it when you leave the view:

- (void)viewDidDisappear:(BOOL)animated {
   boundWidth = self.view.bounds.size.width;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM