在旋转上放置和移动视图(UIView)

时间:2011-05-24 01:50:45

标签: iphone objective-c ios ipad uiview

当应用程序旋转时,准确放置和移动视图的“正确”方法是什么?也就是说,当UI从纵向旋转到横向时,如何对视图的位置,大小和重排进行细粒度控制(反之亦然)?我认为我的两个选择是:

  1. 使用两个超级视图(纵向和横向)。旋转:在它们之间切换。
  2. 使用一个超级视图。轮换时:更改每个子视图的框架,边界和中心属性。
  3. 如果你有两个具有足够明显的布局和元素的视图,那么第一种方式可能就足够了。如果你的两个视图对于不同的方向基本上是相同的大小,第二种方式可能是仅使用一个视图来实现它的更好方法。

    我怀疑前者可以用IB完成,而后者应该以编程方式完成。

    portrait to landscape

4 个答案:

答案 0 :(得分:9)

要在iPhone旋转时对子视图的位置和大小进行细粒度控制,请在UIViewController方法willAnimateRotationToInterfaceOrientation:duration:中更改子视图的框架。在动画块中调用此方法,因此对您在其中创建的子视图帧的所有更改都将进行动画处理。

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
        // Portrait frames
        self.subviewA.frame = CGRectMake(x, y, width, height);
        self.subviewB.frame = CGRectMake(x, y, width, height);
        self.subviewC.frame = CGRectMake(x, y, width, height);
    } else {
        // Landscape frames
        self.subviewA.frame = CGRectMake(x, y, width, height);
        self.subviewB.frame = CGRectMake(x, y, width, height);
        self.subviewC.frame = CGRectMake(x, y, width, height);
    }
}

答案 1 :(得分:0)

这是一个想法。我担心动画会很有趣,但请试试看。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toOrientation 
                                duration:(NSTimeInterval)duration {

    if (toOrientation == UIInterfaceOrientationLandscapeLeft ||
        toOrientation == UIInterfaceOrientationLandscapeRight) {
        [UIView beginAnimations:nil context:NULL]; {
            [UIView setAnimationDuration:1.0];
        }
            [UIView setAnimationDelegate:self];
        [viewA setFrame:CGRectMake(?,?,?,?)];
        [viewB setFrame:CGRectMake(?,?,?,?)];
        [viewC setFrame:CGRectMake(?,?,?,?)];
        } [UIView commitAnimations];    
    } else if  (toOrientation == UIInterfaceOrientationPortrait ||
            toOrientation == UIInterfaceOrientationPortraitUpsideDown) {
        [UIView beginAnimations:nil context:NULL]; {
            [UIView setAnimationDuration:1.0];
        }
        [UIView setAnimationDelegate:self];
        [viewA setFrame:CGRectMake(?,?,?,?)];
        [viewB setFrame:CGRectMake(?,?,?,?)];
        [viewC setFrame:CGRectMake(?,?,?,?)];
        } [UIView commitAnimations];    
    }

答案 2 :(得分:0)

我有一个适合我的想法,我在视图中使用一个小视图,当设备方向发生变化时,它会自动旋转。使用一个通知程序,然后在方法中更改方向。

#define DegreesToRadians(x) (M_PI * x / 180.0)

.......

[[NSNotificationCenter defaultCenter] addObserver:showIndicator
                                         selector:@selector(setProperOreintation)
                                             name:UIDeviceOrientationDidChangeNotification
                                           object:nil];

.......

-(void)setProperOrientation {

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];


if (orientation == UIDeviceOrientationPortraitUpsideDown)
    self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, DegreesToRadians(180)); 

else if (orientation == UIDeviceOrientationLandscapeLeft)
    self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, DegreesToRadians(90));  

else if (orientation == UIDeviceOrientationLandscapeRight)
    self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, DegreesToRadians(-90));

    [UIView commitAnimations]; }

此处代替旋转你可以使用翻译或缩放

答案 3 :(得分:0)

有很多解决方案。其中之一是您之前阅读的控件动画。另一种选择是准备2 UIView一个用于纵向模式,另一个用于横向模式。并且在切换方向上 - 加载适当的UIView。这就是我在我的应用程序中使用的方式。因为有时景观和肖像之间的差异很大。

在简单的情况下,足以为子视图设置正确的autoresizingMask。阅读它。它的效果非常好。