旋转放置和移动视图 (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 并使用 Swift 以编程方式放置新的 UIView?