是否可以在设备方向改变时更改控制器内单个视图的方向?

时间:2013-12-22 22:20:33

标签: ios objective-c cocoa-touch uiview uiinterfaceorientation

我正在尝试在UIView内转换一个UIViewController,而无需转动整个控制器。这可能吗?我试着说明一下:

_____^_____       ____________________
|         |      |      ____^____     |
|  __^__  |      |     |         |    |
|  |   |  |      |  A  |    B    |    > 
|  | B |  |  --> |     |_________|    |
|  |___|  |      |                    |
|         |      |____________________|
|    A    |
|_________|

显示视图的方向,每个视图的箭头指向UP。 UIViewController(A)始终保持纵向,因此如果将设备转换为横向,则向上倾斜。 UIView将转向遵守设备的方向,以便向上。 在YouTube应用中可以看到此类似的内容,如果您单击纵向视频,它会显示在视图顶部,如果您转动设备,则只有视频视图在横向播放。他们解决了不同的问题吗?单个UIView是否有自己的shouldAutorotateToInterfaceOrientationshouldAutorotatesupportedInterfaceOrientations和/或preferredInterfaceOrientationForPresentation规则,而不是其控制器?

1 个答案:

答案 0 :(得分:1)

您需要自己对视图应用变换。您应该在viewDidLayoutSubviews中应用此转换,以确保在视图布局时正确应用转换,并注册UIDeviceOrientationDidChangeNotification通知并在设备方向更改时重新应用转换。

-(void)_applyTransform
{
    CGAffineTransform t = CGAffineTransformIdentity;
    if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft)
    {
        t = CGAffineTransformMakeRotation(M_PI/2.0);
    }
    else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight)
    {
        t = CGAffineTransformMakeRotation(-M_PI/2.0);
    }
    else if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
    {
        t = CGAffineTransformMakeRotation(M_PI);
    }

    [_view setTransform:t];
}

- (void)_deviceOrientationDidChange:(NSNotification*)n
{
    [self _applyTransform];
}

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    [self _applyTransform];
}

由粉丝回答! :)只是为了记录,这里是使用Leo的一个很棒的例子的一整套典型的工作代码。

假设你有一个 UIView 类,所以通常匹配你正在加载的XIB。在示例中,视图有四个按钮。我们将在iPhone旋转时旋转按钮。 (要清楚我们只是旋转,我们想要的是什么,在视图中 - 我们不是在这个例子中旋转整个视图。你可以旋转东西,移动物品,隐藏东西,或任何你想要的东西,或者你如果相关,可以旋转整个视图。处理更大的调整大小的问题是不同的,这个例子显示“只是”旋转该死的按钮到位。)

(顺便说一句,通常我建议在这里使用可能的类别,但这是一个很好的例子来展示它是如何工作的,作为简单的粘贴代码。)

请注意,它会动画旋转的按钮。

@implementation SomeUIView

-(id)initWithCoder:(NSCoder*)coder
    {
    self = [super initWithCoder:coder];
    if (!self) return nil;

    // your other setup code

    [[NSNotificationCenter defaultCenter]
        addObserver:self selector:@selector(spun)
        name:UIDeviceOrientationDidChangeNotification object:nil];

    NSLog(@"added ok...");
    return self;
    }

-(void)dealloc
    {
    NSLog(@"removed ok...");

    // your other dealloc code

    [[NSNotificationCenter defaultCenter]
        removeObserver:self
        name:UIDeviceOrientationDidChangeNotification object:nil];
    }

然后旋转按钮(或任何你想要的东西)......

-(void)spinOneThing:(UIView *)vv
    {
    CGAffineTransform t = CGAffineTransformIdentity;

    if ([[UIDevice currentDevice] orientation] ==
             UIDeviceOrientationLandscapeLeft)
        t = CGAffineTransformMakeRotation(M_PI/2.0);
    if ([[UIDevice currentDevice] orientation] ==
             UIDeviceOrientationLandscapeRight)
        t = CGAffineTransformMakeRotation(-M_PI/2.0);
    if ([[UIDevice currentDevice] orientation] ==
             UIDeviceOrientationPortraitUpsideDown)
        t = CGAffineTransformMakeRotation(M_PI);

    [UIView animateWithDuration:0.1 animations:^{ [vv setTransform:t]; }];
    }

-(void)spun  // the device was spun by the user
    {
    NSLog(@"spun...");
    [self spinOneThing:self.buttonA];
    [self spinOneThing:self.buttonB];
    [self spinOneThing:self.buttonC];
    [self spinOneThing:self.buttonD];
    }