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

17
什么是在应用程序旋转时准确放置和移动视图的“正确”方式?也就是说,当UI从纵向方向旋转到横向方向(或反之亦然)时,我如何精细地控制视图的位置、大小和重新布局?我认为我的两个选择是:
  1. 使用两个父视图(纵向和横向)。旋转时:在它们之间切换。
  2. 使用一个父视图。旋转时:改变每个子视图的frame、bounds和center属性。
如果您有两个具有足够独特布局和元素的视图,则第一种方法可能已经足够好了。如果您的两个视图本质上是为不同方向大小而调整的相同内容,则采用第二种方法可能更好,只需使用一个视图即可。
我怀疑前者可以用IB完成,后者应该通过编程方式完成。

portrait to landscape

4个回答

11

为了在 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);
    }
}

就这样,谢谢。我试图设置变换属性,但它的行为很奇怪。 - Nuno Costa

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];    
    }

我认为你需要使用 setFrame 而不是 setBounds - Lukman

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]; }

在这里,您可以使用平移或缩放代替旋转。


0

有很多解决方案。其中之一是控件动画,就像你之前读到的那样。另一个选项是准备两个UIView,一个用于纵向模式,另一个用于横向模式。在切换方向时,加载适当的UIView。这是我在我的应用程序中使用的方式。因为有时横向和纵向之间的差异非常大。

在简单的情况下,为子视图设置正确的autoresizingMask就足够了。阅读相关资料。它的效果非常好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接