Поддержка ориентации раскадровок для xCode 4.2? - PullRequest
13 голосов
/ 18 октября 2011

Я обновился до 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», и реализовал там контроллеры альбомной ориентации. На самом деле, это в точности как обычная (портретная) раскадровка, но все экраны в альбомном режиме.

Так что я извлеку 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. Реализация обновления LandscapeView

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

Удачи всем.

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

Ответы [ 3 ]

6 голосов
/ 27 января 2012

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

#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);
}
3 голосов
/ 12 января 2012

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

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

3 голосов
/ 18 октября 2011

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

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

Ниже приведена дополнительная информация об автоматическом изменении размера масок: Автоматическая обработка изменений макета с использованием автоматического изменения размераПравила .

...