Скрытые проблемы изменения ориентации UIView / Layout - PullRequest
3 голосов
/ 13 января 2011

Проблема: У меня есть два View Controller загружены в корневой View Controller. Оба макета подчиненного представления реагируют на изменения ориентации. Я переключаюсь между двумя представлениями, используя [UIViewformationFromView: ...]. Оба подпункта работают нормально сами по себе, но если ...

  1. Просмотры поменялись местами
  2. Изменение ориентации
  3. Просмотры снова меняются местами

Представление, которое ранее было скрыто, имеет серьезные проблемы с макетом. Чем больше я повторяю эти шаги, тем хуже становится проблема.

Детали реализации

У меня есть три вида контроллеров.

  1. MyAppViewController
  2. A_ViewController
  3. B_ViewController

A & B ViewControllers имеют каждое фоновое изображение, а также UIWebView и AQGridView соответственно. Чтобы дать вам пример того, как я все это настраиваю, вот метод loadView для 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];

}

Для краткости AQGridView в B_ViewController настроен почти так же.

Теперь оба этих представления работают нормально. Тем не менее, я использую оба из них в 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];

}

Я пробираюсь через это, и я подозреваю, что многое из того, что я сделал, реализовано неправильно, поэтому, пожалуйста, не стесняйтесь указывать на все, что должно быть сделано иначе, мне нужен ввод

Но моя главная задача - понять, что вызывает проблемы с макетом. Вот два изображения, которые иллюстрируют природу проблем макета ...

UPDATE : Я просто заметил, что когда ориентация горизонтальная, переход переворачивается вертикально, когда я ожидаю, что он будет горизонтальным. Я не знаю, что это за ключ к тому, что может пойти не так.

Normal Layout

Переключиться на другой вид ... изменить ориентацию .... переключиться обратно ....

Problem Layout

1 Ответ

1 голос
/ 15 апреля 2011

Я только что наткнулся на это, и у меня такое чувство, что вы с тех пор поняли это.Но на всякий случай, или если кто-то ищет тот же ответ, я использовал такой подход в этой ситуации.

В заголовочных файлах каждого контроллера представления (те, между которыми вы переключаетесь, а не корневой MyAppViewController)), добавьте число с плавающей запятой:

float boundWidth;

В viewDidLoad инициализируйте его как 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;
}
...