Как сделать так, чтобы дочерний контроллер вида понимал свою рамку, когда она представлена в ландшафте?


Я представляю дочерний контроллер вида из родительского контроллера вида со следующим кодом:

self.childVC = [[ChildVC alloc] init];
[self addChildViewController:self.childVC];
self.childVC.view.frame = self.view.bounds;
self.childVC.alpha = 0.1;
[self.view addSubview:self.childVC.view];
[UIView
    animateWithDuration:0.3
    delay:0.0
    options:UIViewAnimationOptionCurveEaseInOut
    animations:^(void) {
        self.view.alpha = 1.0;
    }
    completion:^(BOOL finished) {
        [self.childVC didMoveToParentViewController:self];
    }
];

Родительский контроллер вида поддерживает все ориентации. Когда ребенок представлен в то время как родитель находится в портретной ориентации, кадр ребенка, как и ожидалось:

viewDidLoad:   <UIView: 0xeb9f70; frame = (0 0; 320 568); autoresize = W+H;
viewDidAppear: <UIView: 0xeb9f70; frame = (0 0; 320 568); autoresize = W+H;

Однако, когда ребенок представлен в то время как родитель находится в ландшафтной ориентации, фрейм ребенка выглядит странно:

viewDidLoad:   <UIView: 0xeb9f70; frame = (0 0; 320 568); autoresize = W+H;
viewDidAppear: <UIView: 0xeb9f70; frame = (0 0; 568 320); autoresize = W+H;

В viewDidLoad ребенок думает, что его фрейм является в портретах. Затем он исправляет себя в viewDidAppear. Это спорадическое изменение кадра делает анимацию ребенка беспокойной. Как я могу сделать кадр одновременно правильным и последовательным, когда ребенок запускается в альбомной ориентации?

2 2

2 ответа:

viewDidLoad представляет представление в исходном состоянии, когда все элементы загружены. Планировка еще не началась. Если контроллер вида определен в раскадровке или наконечнике, он будет иметь значения, как они были считаны из декодера. Вы не должны запускать анимацию там, а в viewWillAppear, который должен быть вызван после того, как вид был макетом (viewDidLayout).

У вас есть реализация supportedInterfaceOrientationsи preferredInterfaceOrientationForPresentation.

Я нашел это из руководства по программированию ViewController

В iOS 5 и более ранних версиях контроллер вида иногда может участвовать в процессе вращения, даже если он не является самым верхним полноэкранным контроллером вида. Обычно это происходит, когда контроллер представления контейнера запрашивает у своих дочерних элементов поддерживаемые ориентации интерфейса. На практике способность детей подавлять родителей редко бывает полезной. Имея это в виду, вы должны рассмотреть возможность эмуляции поведения iOS 6 как можно больше в приложении, которое также должно поддерживать iOS 5:

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

И из этого Вы можете видеть, что произошло, когда произошло вращение.

Надеюсь, что это поможет Вам разобраться в этом в вашей ситуации.