隐藏的 UIView 方向更改/布局问题

发布于 2024-10-11 21:25:18 字数 3274 浏览 2 评论 0原文

问题: 我有两个视图控制器加载到根视图控制器中。两个子视图布局都会响应方向变化。我使用 [UIView conversionFromView:...] 在两个视图之间切换。两个子视图本身都可以正常工作,但是如果...

  1. 视图被交换
  2. 方向更改
  3. 视图再次被交换,

之前隐藏的视图会出现严重的布局问题。我重复这些步骤的次数越多,问题就越严重。

实现细节

我有三个viewController。

  1. MyAppViewController
  2. A_ViewController
  3. B_ViewController

A & B ViewController 每个都有一个背景图像,分别有一个 UIWebView 和一个 AQGridView。为了给你一个我如何设置的例子,这里是 A_ViewController 的 loadView 方法...

- (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];

}

为了简洁起见,B_ViewController 中的 AQGridView 的设置方式几乎相同。

现在,这两种观点都可以很好地发挥作用。但是,我在 AppViewController 中使用它们,就像这样...

- (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];


    }

并且我使用我自己的 switchView 方法在两个视图之间切换,就像这样

- (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];

}

我正在摸索着解决这个问题,我怀疑我所做的很多事情是实施不正确,所以请随时指出任何应该采取不同做法的地方,我需要输入。

但我最关心的是了解导致布局问题的原因。这里有两张图片说明了布局问题的本质...

更新: 我刚刚注意到,当方向为横向时,过渡会垂直翻转,而我希望它是水平的。我不知道这是否是可能出现问题的线索。

正常布局

切换到另一个视图...更改方向...切换回来....

问题布局

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.

Normal Layout

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

Problem Layout

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清醇 2024-10-18 21:25:18

我只是偶然发现了这一点,并有一种感觉,你已经明白了这一点。但为了以防万一,或者如果其他人正在寻找相同的答案,这就是我在这种情况下采取的方法。

在每个视图控制器的头文件(您在其之间切换的头文件,而不是根 MyAppViewController)中,添加一个浮动:

float boundWidth;

在 vi​​ewDidLoad 中,将其初始化为 0

boundWidth = 0;

然后创建如下检查:

- (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;
}

通过在离开时设置它来跟踪宽度观点:

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

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文