iOS开发中使用代码控制横竖屏的切换


http://www.jianshu.com/p/650ba0ff626b


很多时候,项目中都有这样的需求:APP中以竖屏为主,个别界面会要求横屏显示,或者要根据用户的手机朝向自动切换横竖屏;下面就来详细讲解,在项目中怎么使用代码来控制APP的界面转换.
首先,要想APP支持多个方向,需要在工程进行设置支持的朝向:
General-->Deployment Info-->Device Orientation中进行设置
这样,就可以在项目中使用代码来控制页面的朝向了,在这之前,需要知道控制视图是否能够自动旋转,以及支持的朝向,是通过哪些方法来控制的?
其实,主要使用的是下面三个方法:

/ New Autorotation support.  
//是否自动旋转,返回YES可以自动旋转  
- (BOOL)shouldAutorotate NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;  
//返回支持的方向  
- (UIInterfaceOrientationMask)supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;  
// Returns interface orientation masks.  
//这个是返回优先方向  
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation NS_AVAILABLE_IOS(6_0) __TVOS_PROHIBITED;


一般情况下,实现前两个方法即可!这些都是UIViewController的实例方法,直接在需要设置的控制器内重写上面的方法即可;
有时候,你会发现,只有在APP启动时出现的第一个界面内重写上面的两个方法,会有效果;而在其他的界面重写,并没有效果.这是因为,程序启动后的第一个界面是程序的跟视图控制器,而这些设置,必须是影响了跟视图中的相应设置,才会有效果;
假如,你在跟视图中进行了如下设置:

- (BOOL)shouldAutorotate{  
    return NO;  
}
那么,在整个项目中,无论你如何设置,都不会有自动旋转屏幕的效果.
综上可知,如果要改变某个视图屏幕方向,需要告诉跟视图,在跟视图中修改为相应的设置即可;
所以,问题来了,怎么告诉跟视图呢?这要视情况而定:

1.当前viewController就是跟视图控制器

这种情况最简单,直接在控制器中重写上面的方法,设置是否支持自动旋转,以及支持的方向即可:

- (BOOL)shouldAutorotate{
    return YES;
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0
- (NSUInteger)supportedInterfaceOrientations
#else
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
#endif
{
    return UIInterfaceOrientationMaskAll;
}

像上面我设置为支持自动旋转,支持所有的朝向;但是这种情况很少见...


2.项目的跟视图控制器是导航(UINavigationController)

这种情况比较常见,也很简单;一般使用的导航的时候,都不会去直接使用系统的UINavigationController,而会定义一个他的子类,做一些公共的设置:

#import <UIKit/UIKit.h>

@interface BaseNaviViewController : UINavigationController

@end

然后在导航的viewController里面重写上面的三个方法,这里也有两种方式来控制:

2.1设置最后一个push的viewController

这种方式,主要是用在,当push到某个视图控制器时,要求他能够支持自动旋转,或者强制转为横屏;这里主要用到了导航的viewControllers属性,这是一个数组,数组的最后一个元素,就是最后push进去的viewController,所以,实现代码如下:


-(BOOL)shouldAutorotate  
{  
    return [[self.viewControllers lastObject] shouldAutorotate];  

}  

#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0  
- (NSUInteger)supportedInterfaceOrientations  
#else  
- (UIInterfaceOrientationMask)supportedInterfaceOrientations  
#endif  
{  
     return [[self.viewControllers lastObject] supportedInterfaceOrientations];  
}  

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {  

    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];  
}

到这里还没有结束,这里只是获取到了最后一个push的viewController,然后用它去调用了相应的方法,具体的方法实现,还是需要在哪个viewController里进行设置的,也就是在需要特殊设置的viewController里重写上面的方法:


-(BOOL)shouldAutorotate
{
    return YES;
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0
- (NSUInteger)supportedInterfaceOrientations
#else
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
#endif
{
    return UIInterfaceOrientationMaskPortraitUpsideDown;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {

    return UIInterfaceOrientationPortraitUpsideDown;
}

其实这样也就是告诉跟视图控制器,这个界面我要特殊设置一下;


2.2设置指定的控制器

第一种方法是,只要push进去一个视图控制器,都可以进行相应的设置,而这种方法是只针对特定的控制器进行设置,例如这里,我需要把SecondViewController单独设置为支持横屏,只需要将第一种方法中的导航里的相应代码做如下修改:

-(BOOL)shouldAutorotate
{
    if ([[self.viewControllers lastObject]isKindOfClass:[SecondViewController class]]) {
        return YES;
    }

    return NO;
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0
- (NSUInteger)supportedInterfaceOrientations
#else
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
#endif
{
    if ([[self.viewControllers lastObject]isKindOfClass:[SecondViewController class]]) {
                return UIInterfaceOrientationMaskLandscapeLeft;
            }

    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {

    if ([[self.viewControllers lastObject]isKindOfClass:[SecondViewController class]]) {
        return UIInterfaceOrientationLandscapeLeft;
    }

    return UIInterfaceOrientationPortrait;
}

这样的好处是,可以控制指定的视图控制器,也不用在指定的视图控制器内再重写上面的方法;
坏处就是,如果需要控制的视图控制器比较多的话,加的判断会多很多;没有方式一灵活;

3.跟视图控制器是UITabbarController

这种情况比较常见,项目的跟视图控制器是一个UITabBarController,这种情况的实现相对来说要复杂一些,但是,明白了原理,总是有方法来实现的.归根结底,也就是告诉跟视图,我这个界面需要支持旋转了;
由于,在UITabBarController里直接获取到UIViewController比较困难,所以这里我采用通知的形式,来获取相应的设置状态;
首先,设置一个全局的BOOL值,用于接收通知发送的参数:

#import <UIKit/UIKit.h>

@interface BaseTabBar : UITabBarController
{
    BOOL shouldAutorotate;  
}
@end

然后注册一个通知:

//注册旋转屏幕的通知
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(autorotateInterface:) name:@"InterfaceOrientationNotification" object:nil];

实现通知方法:

-(void)autorotateInterface:(NSNotification *)notifition
{
    shouldAutorotate = [notifition.object boolValue];
}

然后在重写的方法里加入判断:

/** 
 * 
 *  @return 是否支持旋转 
 */  
-(BOOL)shouldAutorotate  
{  
    NSLog(@"======%d",shouldAutorotate);  
    if (!shouldAutorotate) {  
        return NO;  
    }else{  
        return YES;  
    }  
}  

/** 
 *  适配旋转的类型 
 * 
 *  @return 类型 
 */  
-(UIInterfaceOrientationMask)supportedInterfaceOrientations  
{  
    if (!shouldAutorotate) {  
        return UIInterfaceOrientationMaskPortrait;  
    }  
    return UIInterfaceOrientationMaskAllButUpsideDown;  
}

这里我直接将支持的方向写死了,只是判断了一下是否支持自动旋转屏幕,如果需要将支持的方向传过来,可以修改通知携带的参数;
最后在需要自动转屏的控制器内发送通知:

[[NSNotificationCenter defaultCenter] postNotificationName:@"InterfaceOrientationNotification" object:@"YES"];

到此,对于控制屏幕的旋转及方向,基本就介绍完了,如果有不足或者不对的地方,还请指正;如果你有更好的方式实现同样的效果,还请不吝赐教...

//强制旋转屏幕  
- (void)orientationToPortrait:(UIInterfaceOrientation)orientation {  
    SEL selector = NSSelectorFromString(@"setOrientation:");  
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];  
    [invocation setSelector:selector];  
    [invocation setTarget:[UIDevice currentDevice]];  
    int val = orientation;  
    [invocation setArgument:&val atIndex:2];//前两个参数已被target和selector占用  
    [invocation invoke];  

}

使用的时候,只需要把你需要旋转的方向传过去即可!
有一点需要注意:从A进入B的时候,把B强制转换成横屏,返回的时候,需要在A出现的时候再转换为原来的方向,不然会有问题;个人建议可以在B的viewWillAppear调用这个方法,转换屏幕(例如转换为横屏),然后在A的viewWillAppear中转换回来;


Demo下载地址: https://github.com/fenglingdeyi/InterfaceRotationTest


关于横竖屏切换更多的资料:http://blog.csdn.net/a351945755/article/details/39159263




方案是为解决特定问题或达成特定目标而制定的一系列计划或步骤。它的作用是提供一种系统性的方法,以有效地应对挑战、优化流程或实现目标。以下是方案的主要作用: 问题解决: 方案的核心目标是解决问题。通过系统性的规划和执行,方案能够分析问题的根本原因,提供可行的解决方案,并引导实施过程,确保问题得到合理解决。 目标达成: 方案通常与明确的目标相关联,它提供了一种达成这些目标的计划。无论是企业战略、项目管理还是个人发展,方案的制定都有助于明确目标并提供达成目标的路径。 资源优化: 方案在设计时考虑了可用资源,以最大化其效用。通过明智的资源分配,方案可以在有限的资源条件下实现最大的效益,提高效率并减少浪费。 风险管理: 方案通常会对潜在的风险进行评估,并制定相应的风险管理策略。这有助于减轻潜在问题的影响,提高方案的可行性和可持续性。 决策支持: 方案提供了决策者所需的信息和数据,以便做出明智的决策。这种数据驱动的方法有助于减少不确定性,提高决策的准确性。 团队协作: 复杂的问题通常需要多个人的协同努力。方案提供了一个共同的框架,帮助团队成员理解各自的职责和任务,促进协作并确保整个团队朝着共同的目标努力。 监控与评估: 方案通常包括监控和评估的机制,以确保实施的有效性。通过定期的评估,可以及时调整方案,以适应变化的环境或新的挑战。 总体而言,方案的作用在于提供一种有序、有计划的方法,以解决问题、实现目标,并在实施过程最大化资源利用和风险管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值