4

I'm trying to create an iPhone application that is always in landscape mode, using the Utility application template. Here's what I did:

  • Create a new iPhone application project, using the Utility Application template
  • In Interface Builder, rotate all the views 90 degrees.
  • In Interface Builder, add a label to the middle of the MainView. Stretch it all the way across the view, set the alignment to centered, and set the autosizing springs so that it can stretch horizontally.
  • In Info.plist, add the key "UIInterfaceOrientation" with value "UIInterfaceOrientationLandscapeRight"
  • In the controller classes, change the shouldAutorotateToInterfaceOrientation methods to "return (interfaceOrientation == UIInterfaceOrientationLandscapeRight) || (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);"
  • Run the app.

When I launch my app, it comes up in landscape orientation, but the main view only covers the top half of the display, and it is stretched horizontally. I get the same results in both the simulator and on an actual device. I've seen it with versions 2.2 and 2.2.1 of the SDK.

I have been able to work around the problem by adding the following step to the above:

  • Add "self.view.autoresizesSubviews = NO;" to RootViewController's viewDidLoad method after "[super viewDidLoad];".

If I do this, then it works as expected. But this feels like a hack. Why should this be necessary?

I don't think it is a transformation issue. All elements are drawn in the proper orientation and with the proper scaling. The problem seems to be that the bounds rectangles of the main view gets funky. It looks like the height of the main view is being cut by a little more than half, and the width is being increased by about 50%.

If I do the exact same set of steps using the View-based Application template instead of Utility, then everything works as expected. So I'm pretty sure the problem is specific to how a Utility application manages its views.

Anybody understand what's going on here?

4

3 回答 3

3

我要说的是设置这个键不会旋转你的界面;您仍然需要以横向模式布置内容并使用 CFaffineTransform 进行适当的旋转 - 请参阅 iPhone OS 编程指南中的“以横向模式启动”。为您查找参考资料时,我发现了这条评论:“要在 v2.1 之前的 iPhone OS 版本中以横向模式启动基于视图控制器的应用程序,您需要对应用程序的变换应用 90 度旋转根视图除了前面的所有步骤。在 iPhone OS 2.1 之前,视图控制器不会根据 UIInterfaceOrientation 键的值自动旋转它们的视图。但是,在 iPhone OS 2.1 及更高版本中,此步骤不是必需的。

因此,如果您运行的是 2.1 之前的版本,则需要将此代码添加到视图控制器中的 viewDidLoad 方法中。(否则,您可以发布一些代码吗?)

-(void)viewDidLoad 
// After loading the view, transform the view so that the co-ordinates are right for landscape
// As described in iPhone Application Programming Guide
// Weird, I'm sure this used to be needed, but it doesn't now. The one in CardScrollViewController is needed though.
{
    [super viewDidLoad];

    CGAffineTransform transform = self.view.transform;
    CGPoint center = CGPointMake(kScreenHeight / 2.0, kScreenWidth / 2.0);

    // Set the center point of the view to the center point of the window's content area.
    self.view.center = center;

    // Rotate the view 90 degrees around its new center point.
    transform = CGAffineTransformRotate(transform, (M_PI / 2.0));
    self.view.transform = transform;    
}
于 2009-02-08T17:23:51.917 回答
2

Jane 将 UIInterfaceOrientation 的设置描述为 UIInterfaceOrientationLandscapeRight(或 UIInterfaceOrientationLandscapeLeft),以及文档中推荐的旋转设置,但我在根视图控制器中使用了稍微不同的代码块(到同一端):

- (void)loadView 
{
    UIView *primaryView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
    primaryView.backgroundColor = [UIColor clearColor];

    // Start in landscape orientation, and stay that way
    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (orientation == UIInterfaceOrientationLandscapeRight) 
    {
        CGAffineTransform transform = primaryView.transform;

        // Use the status bar frame to determine the center point of the window's content area.
        CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
        CGRect bounds = CGRectMake(0, 0, statusBarFrame.size.height, statusBarFrame.origin.x);
        CGPoint center = CGPointMake(60.0, bounds.size.height / 2.0);

        // Set the center point of the view to the center point of the window's content area.
        primaryView.center = center;

        // Rotate the view 90 degrees around its new center point.
        transform = CGAffineTransformRotate(transform, (M_PI / 2.0));
        primaryView.transform = transform;
    }   

    self.view = primaryView;
    [primaryView release];  
}

除此之外,我在根视图控制器中实现了以下委托方法:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
    return ( (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}

最后,我遇到了模拟器无法正确自动旋转的奇怪故障,因此我需要在我的 UIApplicationDelegate 中实现以下委托方法:

- (void)application:(UIApplication *)application willChangeStatusBarOrientation:(UIInterfaceOrientation)newStatusBarOrientation duration:(NSTimeInterval)duration;
{
    // This prevents the view from autorotating to portrait in the simulator
    if ((newStatusBarOrientation == UIInterfaceOrientationPortrait) || (newStatusBarOrientation == UIInterfaceOrientationPortraitUpsideDown))
        [application setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
}

毕竟,我的应用程序能够以横向(右)启动,并在 2.0 固件和模拟器中保持该方向。

于 2009-02-08T20:02:05.013 回答
0

尝试在笔尖中将视图的方向属性设置为横向。该属性可以在 Simulated Metrices 下 UIView 的 Info View 的第 4 个选项卡[Attributes Inspector] 中找到。

于 2011-11-11T03:52:41.013 回答