第一种:通过人为的办法改变view.transform的属性。
具体办法:
view.transform一般是View的旋转,拉伸移动等属性,类似view.layer.transform,区别在于 View.transform是二维的,也就是使用仿射的办法通常就是带有前缀CGAffineTransform的类(可以到api文档里面搜索这个前 缀的所有类),而view.layer.transform可以在3D模式下面的变化,通常使用的都是前缀为CATransform3D的类。
这里要记住一点,当你改变过一个view.transform属性或者view.layer.transform的时候需要恢复默认状态的话,记得先把他 们重置可以使用view.transform = CGAffineTransformIdentity,或者view.layer.transform = CATransform3DIdentity,假设你一直不断的改变一个view.transform的属性,而每次改变之前没有重置的话,你会发现后来 的改变和你想要的发生变化了,不是你真正想要的结果。
好了,上面介绍了旋转的属性,接下来就是关键了。官方提供了一个办法就是查看当前电池条的状态UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;通过这个办法,你可以知道当前屏幕的电池条的显示方向,而且你还可以 强制设置他的显示方向,通过设置这个属性就OK了,可以选择是否动画改变电池条方向。有了这两个那我们就可以任意的改变我们想要的显示方式了。
1.获取当前电池条的方向UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation
2.获取当前屏幕的大小CGRect frame = [UIScreen mainScreen].applicationFrame;
3.设置我们的View的中心点
CGPoint center = CGPointMake(frame.origin.x + ceil(frame.size.width/2),frame.origin.y + ceil(frame.size.height/2));
4.根据当前电池条的方向,获取需要旋转的角度的大小。通常
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;
}
5.可以动画的改变我们view的显示方式了
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeRight animated:YES];
CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;(获取当前电池条动画改变的时间)
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:duration];
//在这里设置view.transform需要匹配的旋转角度的大小就可以了。
[UIView commitAnimations];
第二种:通过setorientation:的办法强制性的旋转到一个特定的方向。
注意:Apple在3.0以后都不支持这个办法了,这个办法已经成为了私有的了,但是要跳过App Stroe的审核,需要一点巧妙的办法。
不要直接调用[[UIDevice currentDevice] setorientation: UIInterfaceOrientationLandscapeRight]这样的办法来强制性的横屏,这样导致你的程序是很难通过App Store审核的。但是你可以选择使用performSelector的办法来调用它。具体就几行代码如下:
//强制横屏
if ([[UIDevice currentDevice] respondsToSelector:@selector(setorientation:)]) {
[[UIDevice currentDevice] performSelector:@selector(setorientation:)
withObject:(id)UIInterfaceOrientationLandscapeRight];
}
总结:如果第一种办法可以满足你需要的话,最好使用第一种办法,因为那个上 App Store肯定没问问题,但是第二种的话是需要冒风险的,但是如果你的结构太复杂了,导致使用第一种办法人为很难控制的话,可以尝试简单的使用第二种办 法。我在有米提供的sample里面就看到他使用了第二种简单的办法来显示横屏竖式的广告条。
ipad横竖屏切换解决方案
由于ipad的横竖屏不同,所以好的应用,横竖屏的页面布局也不一样。那么就需要横竖屏的整体解决方案。先看一个横竖屏布局不一样的界面。
上面两张图是来自同一个界面的横竖版的截屏。可以看出,横竖版显示的内容相同,但是界面布局不同。要实现上述布局,主要是运用UIView中 layoutSubviews方法。当UIView设置为自动适配屏幕时,当用户旋转设备的时候,会调用layoutSubviews方法,我们只需重写 这个方法,然后判断用户屏幕的方向。在调整每个空间的位置即可。
下面是实现上述界面的最简单的原型:
事例的截图如下:
- 其中右面的文字和绿色部分是用一个子视图封装的。
- 整个布局是我在主视图中添加了一个ContentView视图,在ContentView视图中添加了一个ArticleView视图。
- 其中ArticleView和ContentView的xib文件都打开了
- 在ContentView中重写layoutSubviews方法,然后根据stausbar的方向判断当前视图的横竖屏。具体代码:
-(void)layoutSubviews{
[super layoutSubviews];
UIDeviceOrientation interfaceOrientation=[[UIApplication sharedApplication] statusBarOrientation];
if (interfaceOrientation == UIDeviceOrientationPortrait || interfaceOrientation == UIDeviceOrientationPortraitUpsideDown) {
//翻转为竖屏时
[self setVerticalFrame];
}else if (interfaceOrientation==UIDeviceOrientationLandscapeLeft || interfaceOrientation == UIDeviceOrientationLandscapeRight) {
//翻转为横屏时
[self setHorizontalFrame];
}
}-(void)setVerticalFrame
{
NSLog(@"竖屏");
[titleLable setFrame:CGRectMake(283,239,83)];
[leftView setFrame:CGRectMake(38,102,384,272)];
[rightView setFrame:CGRectMake(450,282,198)];
}-(void)setHorizontalFrame
{
NSLog(@"横屏");
[titleLable setFrame:CGRectMake(183,83)];
[leftView setFrame:CGRectMake(168,122,272)];
[rightView setFrame:CGRectMake(650,198)];
}在具体的横竖屏方法中,从新设置各个组件的坐标即可。
- 接下来在ContentView中添加ArticleView视图。
-(id)initWithCoder:(NSCoder *)aDecoder
{
if ((self = [super initWithCoder:aDecoder])) {NSArray *arrayContentView =[[NSBundle mainBundle] loadNibNamed:@"ArticleView" owner:self options:nil];
rightView=[arrayContentView objectAtIndex:0];
[self addSubview:rightView];
}
return self;
}
由于我用的是xib,所以初始化方法为initWithCoder,在这个中添加新的视图。
同样在ArticleView中设置横竖屏相应空间的坐标即可。
-(void)layoutSubviews{
[super layoutSubviews];
UIDeviceOrientation interfaceOrientation=[[UIApplication sharedApplication] statusBarOrientation];
CGRect rect=self.frame;
rect.size.width=282;
rect.size.height=198;
[self setFrame:rect];
if (interfaceOrientation == UIDeviceOrientationPortrait || interfaceOrientation == UIDeviceOrientationPortraitUpsideDown) {
//翻转为竖屏时
[self setVerticalFrame];
}else if (interfaceOrientation==UIDeviceOrientationLandscapeLeft || interfaceOrientation == UIDeviceOrientationLandscapeRight) {
//翻转为横屏时
[self setHorizontalFrame];
}
}-(void)setVerticalFrame
{
NSLog(@"竖屏");
[contentView setFrame:CGRectMake(12,6,250,125)];
[textLable setFrame:CGRectMake(50,139,182,39)];
}-(void)setHorizontalFrame
{
NSLog(@"横屏");
[contentView setFrame:CGRectMake(12,106,158)];
[textLable setFrame:CGRectMake(135,11,147,39)];
}
- </pre> 需求:程序默认开启是横屏,在压到某个页面的时候是竖屏<p></p><p>< /p><p>1.默认横屏需要在XX-info.plist 的 Supported interface orientations 的第一项为 Landscape (left home button)</p><p>2.在切换的竖屏的时候< /p><p></p><pre name="code" class="cpp">-(void)viewWillAppear:(BOOL)animated
- {
- //[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
- UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
- if (orientation != UIInterfaceOrientationPortrait ||
- orientation != UIInterfaceOrientationPortraitUpsideDown)
- {
- [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
- //(获取当前电池条动画改变的时间
- CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationDuration:duration];
- //在这里设置view.transform需要匹配的旋转角度的大小就可以了。
- self.view.transform = [self getTransformMakeRotationByOrientation:orientation];
- [UIView commitAnimations];
- }
- }
计算方向
- - (CGAffineTransform)getTransformMakeRotationByOrientation:(UIInterfaceOrientation)orientation
- {
- if (orientation == UIInterfaceOrientationLandscapeLeft)
- {
- return CGAffineTransformMakeRotation(M_PI/2);
- }
- else if (orientation == UIInterfaceOrientationLandscapeRight)
- {
- return CGAffineTransformMakeRotation(M_PI/2);
- }
- else if (orientation == UIInterfaceOrientationPortraitUpsideDown)
- {
- return CGAffineTransformMakeRotation(-M_PI);
- }
- else
- {
- }
- return CGAffineTransformIdentity;
- }
3.返回的到竖屏
- - (void)viewWilldisappear:(BOOL)animated
- {
- UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
- if (orientation != UIInterfaceOrientationLandscapeLeft ||
- orientation != UIInterfaceOrientationLandscapeRight)
- {
- [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];
- //(获取当前电池条动画改变的时间
- CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
- [UIView beginAnimations:nil context:nil];
- [UIView setAnimationDuration:duration];
- self.view.transform = CGAffineTransformIdentity;
- [UIView commitAnimations];
- }
- }
iPad上的应用一般都会横竖屏支持,所以同一个界面页面的横竖布局也是不一样的。要实现横竖布局的不一样一般用到了UIView的layoutSubView方法。当UIView设置为自动适配屏幕时,当用户设备旋转的时候,就会调用layoutSubView这个方法,只要重写这个方法,然后判断屏幕的方向,调整控件的位址就可以了。现在大家可能会有些疑问,为什么不在UIViewController的这个方法:
-(void)layoutSubviews{
}
-(void)setVerticalFrame
{
}
-(void)setHorizontalFrame
{
}