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

Posted

技术标签:

【中文标题】旋转放置和移动视图 (UIView)【英文标题】:Placing and Moving Views on Rotation (UIView) 【发布时间】:2011-05-24 01:50:44 【问题描述】:

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

    使用两个超级视图(纵向和横向)。旋转时:在它们之间切换。 使用一个超级视图。旋转时:更改每个子视图的框架、边界和中心属性。

如果您有两个具有足够不同布局和元素的视图,那么第一种方法可能就足够了。如果您的两个视图在不同方向上的大小基本相同,则第二种方法可能是仅使用一个视图的更好方法。

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

【问题讨论】:

【参考方案1】:

要在 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);
    

【讨论】:

就是这样,谢谢。我试图设置转换属性,但表现得很奇怪。【参考方案2】:

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

- (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【参考方案3】:

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

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

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

【讨论】:

【参考方案4】:

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

在简单的情况下,为子视图设置正确的autoresizingMask 就足够了。阅读它。真的很好用。

【讨论】:

以上是关于旋转放置和移动视图 (UIView)的主要内容,如果未能解决你的问题,请参考以下文章

旋转后重新初始化 UIView 视图和子视图

如何移动 UIView 并使用 Swift 以编程方式放置新的 UIView?

旋转的 UIView 变得无响应

在视图控制器上放置无限的uiview对象数组[关闭]

Swift + Autolayout:旋转 UILabel,保持在 UIView 旁边

在 UIView 上旋转/移动对象