【问题标题】:Storyboards orientation support for xCode 4.2?xCode 4.2 的情节提要方向支持?
【发布时间】:2011-12-09 20:26:20
【问题描述】:

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

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

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

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

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

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

我创建了另一个 .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];
 }}

祝大家好运。

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

【问题讨论】:

  • self.view = newView; iOS 6+ 上的应用程序会崩溃吗

标签: iphone landscape storyboard xcode4.2 device-orientation


【解决方案1】:

您通常不应该为不同的方向考虑单独的视图,除非它们有很大的不同(可以说,它们不应该如此)。相反,您应该依靠autoresizing masks 在超级视图的框架发生变化时根据基本限制布置尽可能多的视图内容。这将允许子视图适当地响应其父视图框架的变化,通常是界面方向变化的结果。

要更直接地回答您的问题,不,Xcode 无法假设或被告知您要针对特定​​界面方向使用哪些视图,因为这绝不是 UIKit 的视图架构的意图。

以下是有关自动调整蒙版大小的更多信息:Handling Layout Changes Automatically Using Autoresizing Rules

【讨论】:

  • 感谢您的回答。但在 4.2 之前,我们可以选择将 2 个视图添加到一个 ViewController,并分别配置它们,纵向和横向。我现在看到我们可以在 ViewController 中添加第二个视图,但我们看不到它。点击它进行配置,你看不到它。在某些情况下(我有很多)自动调整大小确实没有帮助。那我们该怎么办?
  • 啊,我明白你的意思了。这似乎是情节提要的错误(或者可能是所需的行为)。我注意到了同样的事情,这可能会很痛苦。我建议向 Apple 提交错误。
【解决方案2】:

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

因此,在使用 StoryBoard 时(使用 NIB 时,具有两个视图的先前方式似乎无法工作,其中视图方向可针对单独的视图进行更改)。

【讨论】:

  • 嗯,当您需要纵向和横向,但自动旋转还不够时,您将如何处理这个问题?我仍然没有选择。我希望主菜单视图控制器,例如,在横向模式下排列的菜单与在纵向模式下的排列方式不同。请问有什么办法吗?
【解决方案3】:

这是一个老问题,但我在当天早些时候阅读了这个问题,然后不得不花费大量时间来制定更好的解决方案。我通过破解Apple Alternate View example 想出了这个解决方案。基本上它为横向视图提供模式视图。

#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);
}

【讨论】:

  • 我接受了你的回答,因为这启发了我解决我的问题。但是,我只是转换到另一个视图,而不是呈现/关闭 modalViewController。谢谢泰勒。
猜你喜欢
  • 2011-12-07
  • 1970-01-01
  • 2012-02-19
  • 1970-01-01
  • 2012-05-13
  • 2012-02-21
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多