Подтвердить что ты не робот

Поддержка ориентации раскадровки для xCode 4.2?

Я обновил до xCode 4.2 и стал новым инструментом раскадровки. Однако не удалось найти способ поддерживать портрет и пейзаж.

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

if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) 
    {
        self.view = self.landscapeView;
    }
    else
    {
        self.view = self.portraitView;
    }

Но я искал способ сделать это автоматически. Я имею в виду, теперь это xCode 4.2, я ожидал большего от него. Спасибо всем.

==================================
ВРЕМЕННОЕ РЕШЕНИЕ:

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

Я создал еще один файл .storyboard под названием "MainStoryboard_iPhone_Landscape" и реализовал там контроллеры ландшафтного дизайна. Фактически, это точно как обычная (портретная).storyboard, но все экраны находятся в ландшафтном режиме.

Итак, я извлечу ViewController из пейзажной раскадровки, и когда произойдет поворот, просто измените self.view с новым представлением viewController.

1. Генерировать уведомления при изменении ориентации:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

2.Посмотрите на уведомления:

[[NSNotificationCenter defaultCenter] addObserverForName:UIDeviceOrientationDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {    
    // We must add a delay here, otherwise we'll swap in the new view  
    // too quickly and we'll get an animation glitch  
    [self performSelector:@selector(updateLandscapeView) withObject:nil afterDelay:0];
}];

3.Implement updateLandscapeView

- (void)updateLandscapeView {  
 //>     isShowingLandscapeView is declared in AppDelegate, so you won't need to declare it in each ViewController
 UIDeviceOrientation deviceOrientation       = [UIDevice currentDevice].orientation;
 if (UIDeviceOrientationIsLandscape(deviceOrientation) && !appDelegate().isShowingLandscapeView)
 {
     UIStoryboard *storyboard                = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone_Landscape" bundle:[NSBundle mainBundle]];
     MDBLogin *loginVC_landscape             =  [storyboard instantiateViewControllerWithIdentifier:@"MDBLogin"];
     appDelegate().isShowingLandscapeView    = YES;  
     [UIView transitionWithView:loginVC_landscape.view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationCurveEaseIn animations:^{
         //>     Setup self.view to be the landscape view
         self.view = loginVC_landscape.view;
     } completion:NULL];
 }
 else if (UIDeviceOrientationIsPortrait(deviceOrientation) && appDelegate().isShowingLandscapeView)
 {
     UIStoryboard *storyboard                = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:[NSBundle mainBundle]];
     MDBLogin *loginVC                       = [storyboard instantiateViewControllerWithIdentifier:@"MDBLogin"];
     appDelegate().isShowingLandscapeView    = NO;
     [UIView transitionWithView:loginVC.view duration:0 options:UIViewAnimationOptionTransitionCrossDissolve|UIViewAnimationCurveEaseIn animations:^{
         //>     Setup self.view to be now the previous portrait view
         self.view = loginVC.view;
     } completion:NULL];
 }}

Удачи всем.

P.S: Я согласен с ответом Ad Taylor, потому что после долгого ожидания и поиска решения я закончил реализацию чего-то, вдохновленного его ответом. Спасибо Тейлору.

4b9b3361

Ответ 1

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

#pragma mark Rotation view control

- (void)orientationChanged:(NSNotification *)notification
{
    // We must add a delay here, otherwise we'll swap in the new view
    // too quickly and we'll get an animation glitch
    [self performSelector:@selector(updateLandscapeView) withObject:nil afterDelay:0];
}

- (void)updateLandscapeView
{
    UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
    if (UIDeviceOrientationIsLandscape(deviceOrientation) && !self.isShowingLandscapeView)
    {
        [self performSegueWithIdentifier: @"toLandscape" sender: self];
        self.isShowingLandscapeView = YES;
    }
    else if (deviceOrientation == UIDeviceOrientationPortrait && self.isShowingLandscapeView)
    {
        [self dismissModalViewControllerAnimated:YES];
        self.isShowingLandscapeView = NO;
    }    
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

Ответ 2

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

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

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

Ответ 3

В XCode v4.2.1 при использовании StoryBoards вы можете изменить ориентацию контроллера View, а не самого представления, поэтому, если вы вставили другое представление, вы не сможете изменить его ориентацию, даже если вы мог бы правильно просмотреть представление.

Таким образом, предыдущий способ иметь два представления не будет работать при использовании StoryBoards (при использовании NIB, где View Orientation изменяет для отдельных представлений).