2011-05-24 151 views
16

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

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

如果你有足够鲜明的布局和元素两种观点,那么第一种方式可能是不够好。如果你的两个视图基本上是针对不同方向的大小相同的东西,那么第二种方法可能是仅使用一个视图进行处理的更好方法。

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

portrait to landscape

回答

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); 
    } 
} 
+0

就是这样,谢谢。我试图设置变形属性,但表现出一种奇怪的方式。 – 2012-05-18 10:46:34

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

我认为你需要'setFrame'而不是'setBounds' – Lukman 2011-05-24 03:02:39

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

,而不是旋转u可以使用翻译或规模以下

0

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

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