13

我升级到 xCode 4.2,它是新的 Storyboards 功能。但是,找不到同时支持纵向和横向的方法。

当然,我是以编程方式完成的,有 2 个视图,一个用于纵向,一个用于横向,就像过去一样,并且:

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

但我一直在寻找一种以某种方式自动执行此操作的方法。我的意思是,现在是 xCode 4.2,我期待更多。谢谢大家。

====================================
临时解决方案:

我将在这里提出一个临时解决方案。我说这是暂时的,因为我仍在等待苹果公司对此做一些真正聪明的事情。

我创建了另一个 .storyboard 文件,名为“MainStoryboard_iPhone_Landscape”,并在那里实现了横向视图控制器。实际上,它与 normal(portrait) .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.实现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];
 }}

祝大家好运。

PS:我会接受 Ad Taylor 的回答,因为经过长时间的等待和寻找解决方案,我完成了从他的回答中获得灵感的一些东西。谢谢泰勒。

4

3 回答 3

6

这是一个老问题,但我在当天早些时候阅读了这个问题,然后不得不花费大量时间来制定更好的解决方案。我从破解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);
}
于 2012-01-27T18:04:08.013 回答
3

在 XCode v4.2.1 中,当使用 StoryBoards 时,您只能更改视图控制器的方向,而不能更改视图本身,因此如果您在那里插入了另一个视图,您将无法更改它的方向,即使您可以看到正确查看。

因此,在使用 StoryBoards 时(当使用 NIB 时,视图方向可针对单独的视图进行更改),以前的具有两个视图的方法似乎不起作用。

于 2012-01-12T14:45:33.220 回答
3

您通常不应该为不同的方向考虑单独的视图,除非它们有很大的不同(可以说,它们不应该如此)。相反,当父视图的框架发生变化时,您应该依靠自动调整掩码来根据基本约束布置尽可能多的视图内容。这将允许子视图适当地响应其父视图框架的变化,通常是由于界面方向变化的结果。

为了更直接地回答您的问题,不,Xcode 没有办法假设或被告知您想将哪些视图用于特定的界面方向,因为这从来不是UIKit视图架构的意图。

以下是有关自动调整掩码大小的更多信息:使用自动调整大小规则自动处理布局更改

于 2011-10-18T07:04:50.317 回答