如何在iOS中旋转期间移动一个UIView?

时间:2012-06-11 22:10:02

标签: objective-c ios xcode rotation

我很难弄清楚如何处理我的iPad应用程序的一个屏幕的不同设备方向。这是我的情况:

〜除了一个标签外,所有这个屏幕都使用弹簧和支柱完美旋转。这个标签的问题是我希望它以非正统的方式(对角线)移动,因此弹簧和支柱(或调整大小的面具将不起作用)。

〜我正在考虑这样做的方式是这样的:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)newInterfaceOrientation duration:(NSTimeInterval)duration
{
    if(UIInterfaceOrientationIsLandscape(newInterfaceOrientation))
    {
        self.myScreenLabel.frame = CGRectMake(600,0,400,100);
    }
    else {
        self.myScreenLabel.frame = CGRectMake(...//something); }
}

我还会在viewDidLoad中使用类似的逻辑进行检查。 If in portrait mode, put label at... else put label at...

我认为这会奏效;但是,我有点想知道是否有更好的设计方法来做到这一点。上面的方法,到处都有硬编码的数字;因此,有更好的方法吗?此外,这种方法没有利用我的标签在肖像模式的故事板中完美定位的事实,这只是我需要改变的景观。

有关更好设计的任何建议吗?

2 个答案:

答案 0 :(得分:3)

第一个问题,如果您可以在旋转发生之前触发该方法,那么我已经使用您的方法实现了方向更改的行为而没有不良结果。或者,您可以使用NSNotifications在方向更改上添加触发器:

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

然后添加如下方法:

 - (void) didRotate:(NSNotification *)notification {   
    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
    if (orientation == UIDeviceOrientationLandscapeLeft) {
        //your code here
    }
 }

关于你的第二个问题,定位这样的框架是可怕的,但我认为你意识到这一点。相反,将元素定位为与其他内容相关,就像一个支柱(也就是说,总是将小部件相对于它之间的距离进行定位)。因此,在视图中使用窗口的框架,视图的框架或其他一些UIView子类来定位对象,而不是绝对数字。

答案 1 :(得分:0)

有几点想法:

  1. 如果iOS 5+,您可能想要使用viewWillLayoutSubviews,考虑到iOS 6发行说明中的​​注释,重新模态视图和屏幕重定向方法可能更为重要。这也有一个优点,即您的代码位于一个位置。由于我仍然支持前5(虽然我不会再长时间),我实际上有动态检查iOS版本并从其他方法调用我的viewWillLayoutSubviews如果预先5.0,否则我让viewWillLayoutSubviews只是做繁重的工作。

  2. 如果您的横向方向完全不同,您可能想要追求Creating an Alternate Landscape Interface。我从来没有这样做过,但似乎这是你的胡同。关于在不同方向使用不同的NIB,SO上也有帖子。但不确定这在故事板环境中是否有意义。

  3. 对于我们偶尔需要根据屏幕尺寸移动或调整大小的这些控件,我认为我们大多数人都使用viewWillLayoutSubviews来完成。这就是该方法的全部目的(尽管我通常将它用于高度根据数据内容和屏幕宽度而变化的标签)。我从未停下来认为可能有另一种方式。如果您在更改方向时只有一个控件可以移动,也许您可​​以创建两个额外的隐藏控件,一个用于您希望在纵向中可见控件的位置,另一个用于在景观中您想要的位置的另一个隐藏控件(在IB中,您可以切换视图方向以便于控件的布局)。然后在viewWillLayoutSubviews中将实际可见控件的框架设置为这两个隐藏控件之一的框架(当然,取决于方向)。这使您无法在代码中硬编码帧坐标,并充分利用IB的优势。这整个建议可能太可爱了一半,但如果你不想通过我的第二点努力,这是另一种方法。