iPhone / iPad的方向处理

这更是一个普遍的问题,让人们为我提供指导,基本上是学习iPad / iPhone的开发,终于遇到了多方位的支持问题。

我已经查阅了相当数量的doco,而我的书“Beginning iPhone 3 Development”有一个不错的篇章。

但是我的问题是,如果我要以编程方式改变我的控制(甚至对每个方向使用不同的观点),人们究竟如何维护他们的代码基础呢? 我可以想象在意大利面代码/成千上万的“if”检查到处都有这么多的问题,这将迫使我坚持对UI的安排作一个小的改变。

有没有人有经验处理这个问题? 什么是控制它的好方法?

非常感谢Mark

我用我的视图控制器中的两个简单的方法做到这一点:

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { [self adjustViewsForOrientation:toInterfaceOrientation]; } - (void) adjustViewsForOrientation:(UIInterfaceOrientation)orientation { if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) { titleImageView.center = CGPointMake(235.0f, 42.0f); subtitleImageView.center = CGPointMake(355.0f, 70.0f); ... } else if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) { titleImageView.center = CGPointMake(160.0f, 52.0f); subtitleImageView.center = CGPointMake(275.0f, 80.0f); ... } } 

为了保持这个清洁你可以很容易地划分视图调整/重新加载/等。 从单个if-else条件中调用方法。

这真的取决于你在铺设什么。

如果您查看Apple Settings应用程序,则可以看到他们使用表格视图来显示布局,并为大多数行定制了单元格。 有了这个,你可以通过填充单元格的宽度来让一个简单的界面非常便宜地旋转。 这甚至适用于邮件,每行都有编辑文本单元的地方。 表格可以很容易地全部透明,只有button或标签可见,所以它们看起来不像表格。

你可以从每个UIView的autoresizingMask中获得大量的milage。 如果您有一个或多个项目可以具有灵活的高度,那么您通常可以获得在任一方向都看起来很好的界面布局。 根据它的外观,有时你可以把所有东西都放在最上面。

在极less数情况下,如果所有界面元素都放在一个正方形中,则可以将它们旋转到位。

有两次您必须明确处理方向更改。 一个是当一个视图从旁边移动到另一个旋转时。 另一个是当你为每个方向有不同的图像,例如,如果你总是想成为全宽。

有时候有办法解决这两个问题。 您可以使用可拉伸的图像或将自己限制为每行一个视图。 或者您可以locking某些视图的方向。

如果您必须更改视图的布局,则有一个显式的layoutSubviews方法。 你应该尝试在这一个方法中处理你所有的条件布局。 只有当视图边界发生变化时才会调用它,例如在旋转或者为键盘腾出空间时。 为需要响应旋转的每个视图层次结构创build一个自定义视图,并从这里对子视图进行布局。

iPhone SDK是build立在MVC架构的基础之上的,所以理论上如果你把所有的逻辑(模型)与你的用户界面(视图)分离开来,那么你只需要担心一个地方的用户界面:你的视图控制器。 对于那些,你可以有一个单独的视图控制器为每个方向,其中每一个然后将被加载一个if / else来select加载哪个视图控制器。

对于iPhone / iPad的支持,您可以加载另一个可以处理更大显示的视图控制器。

请参阅以下链接: http : //mustafashaik.wordpress.com/2010/11/17/handling-orientations-in-ipad/

我不能保证这个代码,而且诚实地说,上面的代码将会很好地支持RotateToInterfaceOrientation。 这里是另一个采取从FBDialog.m来自iPhone / iPad的。 (虽然,我认为这是一个web视图)

这是要点

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:@"UIDeviceOrientationDidChangeNotification" object:nil]; - (void)deviceOrientationDidChange:(void*)object { UIDeviceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if ([self shouldRotateToOrientation:orientation]) { CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration; [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:duration]; [self sizeToFitOrientation:YES]; [UIView commitAnimations]; } } -(CGAffineTransform)transformForOrientation { UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if (orientation == UIInterfaceOrientationLandscapeLeft) { return CGAffineTransformMakeRotation(M_PI*1.5); } else if (orientation == UIInterfaceOrientationLandscapeRight) { return CGAffineTransformMakeRotation(M_PI/2); } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) { return CGAffineTransformMakeRotation(-M_PI); } else { return CGAffineTransformIdentity; } } - (void)sizeToFitOrientation:(BOOL)transform { if (transform) { self.transform = CGAffineTransformIdentity; } CGRect frame = [UIScreen mainScreen].applicationFrame; CGPoint center = CGPointMake( frame.origin.x + ceil(frame.size.width/2), frame.origin.y + ceil(frame.size.height/2)); CGFloat scale_factor = 1.0f; if (FBIsDeviceIPad()) { // On the iPad the dialog's dimensions should only be 60% of the screen's scale_factor = 0.6f; } CGFloat width = floor(scale_factor * frame.size.width) - kPadding * 2; CGFloat height = floor(scale_factor * frame.size.height) - kPadding * 2; _orientation = [UIApplication sharedApplication].statusBarOrientation; if (UIInterfaceOrientationIsLandscape(_orientation)) { self.frame = CGRectMake(kPadding, kPadding, height, width); } else { self.frame = CGRectMake(kPadding, kPadding, width, height); } self.center = center; if (transform) { self.transform = [self transformForOrientation]; } } 

在你的问题中,你写道:

我可以想象在意大利面代码/成千上万的“if”检查到处都有这么多的问题,这将迫使我坚持对UI的安排作一个小的改变。

避免这种情况的一种方法是创build一个视图层次结构,从一开始就分割处理iPhone / iPad特定的更改。 您只需设置每个设备最初加载的视图。 然后,像通常那样创build一个viewcontroller,但是您也创build了您所创build的viewcontroller的子类。 每个设备的一个子类。 这就是您可以放置​​设备特定代码的位置,如方向处理。 喜欢这个:

 MyViewController.h // Code that is used on both devices MyViewController_iPhone.h // iPhone specific code, like orientation handling MyViewController_iPad.h // iPad specific code, like orientation handling 

如果你对这种方法感兴趣,我build议你阅读这篇文章 。 它以一个非常好的方式解释它。

文章提到的一件事是:

– 开始引用 –

这种模式的美妙之处在于我们不必乱抛垃圾,看起来像这样:

 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { // The device is an iPad running iPhone 3.2 or later. // set up the iPad-specific view } else { // The device is an iPhone or iPod touch. // set up the iPhone/iPod Touch view } 

—引用结束

我希望有帮助。 祝你好运!