iOS显示器旋转的消除方案www.weide1946.com,差异根视

2019-09-11 12:59 来源:未知

方今在做跟录制有关的办事,录制嘛,分明不是小窗口播放,在手提式有线电话机上播放摄像肯定正是最大显示器利用率啦,那就能够用到全屏播放--相当于旋转显示器。上面作者就来介绍下自家自身的技术方案:先说一个别笔者在网络查到的素材,这里给我们校对叁个主题素材即便要设置app的横屏依旧竖屏在Xcode里面有大多装置的

一、几个基本的点子


苹果系统支持横屏顺序

系统匡助横屏顺序application window设置私下认可读取plist里面安装的可行性一致Xcode Geneal设置里面勾选

1.1显示屏旋转方向

- (BOOL)shouldAutorotate//是否支持旋转屏幕{
    return YES;
}
- (NSUInteger)supportedInterfaceOrientations//支持哪些方向{
    return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation//默认显示的方向{
    return UIInterfaceOrientationPortrait;
}

主意调用有限制
合法原来的小说:

www.weide1946.com 1

image.png

1.也正是唯有在window 的 rootcontroller 可能 window最上层prensented controller里面使用方面多个函数,顾客旋转的时候手艺获得调用。
2.独有shouldAutorotate 重临YES时别的五个函数才具博取调用,重回为NO的时候默以为UIInterfaceOrientationMaskPortrait方向。

据此要调控某些分界面旋转只可以在windows 的调整器里面,覆盖以上上个方法,并在supportedInterfaceOrientations 获取你须要旋转的调整器的大势。具体的选拔代码上边有研讨根调控器分别为UITabBarControllerUINavigationController的情况。

暗中同意读取plist里面安装的主旋律(优先级最高)等同于Xcode Geneal设置里面勾选

接下来是UINavigationcontroller等第最低的是viewcontroller

1.2 代码切换荧屏方向

//代码切换屏幕方向
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
            [[UIDevice currentDevice] setValue:value forKey:@"orientation"];

application window设置的品级次之

领会了那一个顺序做横屏就变得很轻巧了application帮助全体

1.3 显示旋转横屏时熄灭的状态栏

info.plist文件大校 View controller-based status bar appearance 设置为NOapplication:didFinishLaunchingWithOptions:中增加底下代码

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];

如此之后你就能意识未有的场地条又乖乖的归来了。

然后是UINavigationcontroller

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return UIInterfaceOrientationMaskAll;//支持所有方向}

1.4 荧屏旋转的多少个代理方法

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration NS_DEPRECATED_IOS(2_0,8_0, "Implement viewWillTransitionToSize:withTransitionCoordinator: instead") __TVOS_PROHIBITED;
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation NS_DEPRECATED_IOS(2_0,8_0) __TVOS_PROHIBITED;

方便调控器对显示屏旋转做出相应的响应:

www.weide1946.com 2

image.png

品级最低的是viewcontroller

UINavigationcontroller支持竖屏

1.5 监听设备的团团转

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onDeviceOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil];

-(void)onDeviceOrientationChange  
{  

    UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;  
    if (UIDeviceOrientationIsLandscape(orientation)) {  
            [self.view setNeedsLayout];  
            [self.view layoutIfNeeded];  
    }else if (orientation==UIDeviceOrientationPortrait){  
           [self.collectionView reloadData];  
            [self.view setNeedsLayout];  
            [self.view layoutIfNeeded];  

    }  
}  

注:其实这么些优先级跟你的window的rootViewcontroller有涉及,就算rootViewcontroller是UITabbarViewontroller,那么tabbar就就像是前边所说的UINavigationcontroller

- shouldAutorotate//是否支持旋转屏幕{ return YES;}- (NSUInteger)supportedInterfaceOrientations//支持哪些方向{ return UIInterfaceOrientationMaskPortrait;}- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation//默认显示的方向{ return UIInterfaceOrientationPortrait;}

二、系统支持横屏顺序


(1) 暗中同意读取plist里面安装的来头(优先级最高)等同于Xcode Geneal设置里面勾选

www.weide1946.com 3

861981-58be5bbebac5ecd1.jpeg

万一在plist只怕General设置了纯粹方向,在工程里面包车型大巴其余代码都会失灵。所以想要旋转荧屏,必得让你的工程支撑所旋转的自由化。
(不过此地还恐怕有一种办法是把当下调整器的View大概view.layer做transform旋转,不过作者觉着那并非当真的旋转显示器,一点能够印证的便是:状态条并不随着旋转)
(2)application window设置的品级次之
(3)然后是UINavigationcontroller
www.weide1946.com,(4)等第最低的是viewcontroller

demo:https://github.com/jesse881025/OrientationChange.git

viewcontroller扶助横屏(pushmodel出来)

三、设置有个别调整器旋转


实际供给描述如下:
要求app 推入到TGLivePlayController时,(1)用户点击视频全屏/退出全屏书时,自定义播放view可以做出响应的全屏/16:9显示 (2)用户退出TGLivePlayController时,app自动切换到竖屏状态。

- shouldAutorotate//是否支持旋转屏幕{ return YES;}- (NSUInteger)supportedInterfaceOrientations//支持哪些方向{ return UIInterfaceOrientationMaskLandscape;}- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation//默认显示的方向{ return UIInterfaceOrientationLandscapeLeft;}

3.1 根调整器为UINavigationController

-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    return UIInterfaceOrientationPortrait;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    UIViewController *vc = self.visibleViewController;
    if([vc isKindOfClass:[TGLiveVideoController class]]){
        return [vc supportedInterfaceOrientations];
    }else{
        return UIInterfaceOrientationMaskPortrait;
    }
}

-(BOOL)shouldAutorotate{
    UIViewController *vc = self.visibleViewController;
    return [vc shouldAutorotate];

   //也可以这样写只在指定的vc里面响应,只是这样在退出指定的控制器时不能在willdisappear里面还原竖屏。
    if([vc isKindOfClass:[TGLiveVideoController class]]){
        return [vc supportedInterfaceOrientations];
    }
    return NO;
}

证Bellamy些,只要在plist只怕General设置了帮忙的矛头表示其分界面援救的自动旋转的取向

3.2 根视图调节器为TabBarController

创建NavigationController和TabBarVontroller的category
此地注意不可能在tabbarcontroller的类里写旋转方式 不然以下方法会无效

为此想要旋转荧屏,必需让您的工程支撑所旋转的趋势。(但是这里还恐怕有一种形式是把当前调节器的View或许view.layer做transform旋转,可是笔者感到那并非当真的旋转显示器,一点得以表明的正是:状态条并不趁着旋转)其实那几个优先级跟你的window的rootViewcontroller有涉及,倘若rootViewcontroller是UITabbarViewontroller,那么tabbar就临近前边所说的UINavigationcontroller,在iOS6之后许多办法爆发了变动,在此之前的二个显示器旋转的艺术就失效了,退换位上边的不二等秘书技。其实荧屏旋转在手提式有线电话机里面有设置,上拉菜单就能够有关闭荧屏旋转的方法,不过我们都了解多数行使在关闭显示屏旋转的时候也得以扩充显示屏旋转---通过某八个开关的平地风波来触发,那正是胁迫旋转(前提依旧是您的工程安装扶助你所要旋转的趋向)

UITabBarController autoRotate.h
#import <UIKit/UIKit.h>  

@interface UITabBarController (autoRotate)  
-(BOOL)shouldAutorotate;  
-(NSUInteger)supportedInterfaceOrientations;  
@end  

www.weide1946.com 4

UITabBarController autoRotate.m
#import "UITabBarController autoRotate.h"  

@implementation UITabBarController (autoRotate)  
-(BOOL)shouldAutorotate{
    return [self.selectedViewController shouldAutorotate];
}

-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
    return [self.selectedViewController supportedInterfaceOrientations];
}

-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
@end  

貌似的不须要旋转的前后相继只须求勾选第一个就能够了。由于软件须要小编勾选的是第三个和首个,在Coding以前自身要告诉我们四个细节:在iOS8之后,显示屏旋转到横向的时候,状态条就能够暗中认可遮掩,笔者觉着苹果是私下认可让您收获最大的展现区域,但是对于自己这么些分寸性冷淡的人来讲,横屏也要显得状态条,以为望着非常浅白色的电瓶组比较舒服,具体的操作方法便是:

UINavigationController autoRotate.h
@interface UINavigationController (autoRotate)  
-(BOOL)shouldAutorotate;  
-(NSUInteger)supportedInterfaceOrientations;  
@end  

在info.plist文件中校 View controller-based status bar appearance 设置为NOapplication:didFinishLaunchingWithOptions:中增添下边代码

UINavigationController autoRotate.m
-(BOOL)shouldAutorotate{
    return [self.selectedViewController shouldAutorotate];
}

-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
    return [self.selectedViewController supportedInterfaceOrientations];
}

-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];

3.3 调控器代码

如此那般之后您就能发觉未有的场地条有宝宝的回来了。接下来便是Coding了:翻阅各大网址和论坛笔者总计了少数种方法,但是完全一样的转动显示器的代码,以供参照他事他说加以考察:援助ARC版本:(那一个办法可以利用,而且能够由此苹果的稽审,已经有人利用并核查通过了)

TGLiveVideoController.m
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self LVSetUpNavItem];
    [self LVSetUpSubviews];
}

-(void)LVSetUpNavItem{
    self.navigationItem.leftBarButtonItem = nil;//移除原有的统一定制的返回键
    UIButton *LeftItem = [UIButton new];
    LeftItem.frame = CGRectMake(0, 0, 24, 24);
    [LeftItem.imageView setContentMode:UIViewContentModeCenter];
    [LeftItem setImage:[UIImage imageNamed:@"back"] forState:UIControlStateNormal];
    [LeftItem setBackgroundImage:[UIImage imageNamed:@"nav_fanhui"] forState:UIControlStateNormal];
    [LeftItem addTarget:self action:@selector(LVbackBtnClick) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *customLeftItem = [[UIBarButtonItem alloc] initWithCustomView:LeftItem];
    self.navigationItem.leftBarButtonItem = customLeftItem;
}
#pragma mark - 替换统一生成的返回键事件
-(void)LVbackBtnClick{
    //先旋转后退回
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    [self.navigationController popViewControllerAnimated:YES];
}

-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    CGFloat videoWidth = kScreenWidth;
    CGFloat videoHeight = _isFullScreen ? self.view.bounds.size.height : kScreenWidth / 16.0f * 9.0f;
    [self.player setPreviewFrame:CGRectMake(0, 0, videoWidth, videoHeight)];

    CGFloat btnW = 60.0f;
    CGFloat btnH = 40.0f;
    CGFloat btnX = CGRectGetMaxX(self.player.previewView.frame) - btnW;
    CGFloat btnY = CGRectGetMaxY(self.player.previewView.frame) - btnH;
    self.btnFullScreen.frame = CGRectMake(btnX, btnY, btnW, btnH);
}

-(BOOL)shouldAutorotate{
    return YES;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

#pragma mark - 旋转代理事件
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                                duration:(NSTimeInterval)duration{
    _isFullScreen = NO;
    //横屏情况
    if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
       toInterfaceOrientation == UIInterfaceOrientationLandscapeRight){
        _isFullScreen = YES;
    }
    self.btnFullScreen.selected = _isFullScreen;
}

#pragma mark - 全屏点击
-(void)btnFullScreenClick:(UIButton *)sender{
    BOOL state = !self.isFullScreen;
    if(state){
        NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    }else{
        NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    }

}

Rotation Issues in ios 6

参谋文献:

iOS内定页面显示器旋转,手动旋转(某app达成效果与利益全经过)
不等根视图下决定部分显示器旋转

if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) { SEL selector = NSSelectorFromString(@"setOrientation:"); NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]]; [invocation setSelector:selector]; [invocation setTarget:[UIDevice currentDevice]]; int val = UIInterfaceOrientationLandscapeRight;//这里可以改变旋转的方向 [invocation setArgument:&val atIndex:2]; [invocation invoke]; }

或者

//但是注意这个方法必须在general里面设置支持锁旋转的方向,否则就是强行旋转,会导致程序崩溃,而且不会有崩溃日志,很难发现崩溃在哪里,所以使用这个方法的时候一定要注意设置支持的方向。[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIDeviceOrientationPortrait] forKey:@"orientation"];

不支持ARC版本

if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) { [[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:UIInterfaceOrientationLandscapeRight]; }

还只怕有一点便是怎么判断当前显示器的矛头:能够依靠电源的求实可行性来剖断,苹果提供了这一办法

NSInteger i = [[UIApplication sharedApplication] statusBarOrientation];if (i == UIInterfaceOrientationLandscapeRight){ //在这里可以写相应的代码}

某个人想必想要监听显示屏的全自动旋转:

1.注册UIApplicationDidChangeStatusBarOrientationNotification通知(举例:在一个viewcontroller类的viewdidload中注册该通知),示例代码如下: [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarOrientationChange:)name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];- statusBarOrientationChange:(NSNotification *)notification{ UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; if (orientation == UIInterfaceOrientationLandscapeRight) // home键靠右{ // } if (orientation ==UIInterfaceOrientationLandscapeLeft) // home键靠左 { // } if (orientation == UIInterfaceOrientationPortrait){ // } if (orientation == UIInterfaceOrientationPortraitUpsideDown){ // }}注意这种方式监听的是StatusBar也就是状态栏的方向,所以这个是跟你的布局有关的,你的布局转了,才会接到这个通知,而不是设备旋转的通知。当我们关注的东西和布局相关而不是纯粹设备旋转,我们使用上面的代码作为实现方案比较适合。

2.注册UIDeviceOrientationDidChangeNotification通知(举例:我们同样在一个viewcontroller类的viewdidload中注册该通知),示例代码如下: [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientChange:)name:UIDeviceOrientationDidChangeNotification object:nil];- orientChange:(NSNotification *)noti{ NSDictionary* ntfDict = [noti userInfo]; UIDeviceOrientation orient = [UIDevice currentDevice].orientation; /* UIDeviceOrientationUnknown, UIDeviceOrientationPortrait, // Device oriented vertically, home button on the bottom UIDeviceOrientationPortraitUpsideDown, // Device oriented vertically, home button on the top UIDeviceOrientationLandscapeLeft, // Device oriented horizontally, home button on the right UIDeviceOrientationLandscapeRight, // Device oriented horizontally, home button on the left UIDeviceOrientationFaceUp, // Device oriented flat, face up UIDeviceOrientationFaceDown // Device oriented flat, face down */ switch  { case UIDeviceOrientationPortrait: break; case UIDeviceOrientationLandscapeLeft: break; case UIDeviceOrientationPortraitUpsideDown: break; case UIDeviceOrientationLandscapeRight: break; default: break; }}注意到这种方式里面的方向还包括朝上或者朝下,很容易看出这个完全是根据设备自身的物理方向得来的,当我们关注的只是物理朝向时,我们通常需要注册该通知来解决问题(另外还有一个加速计的api,可以实现类似的功能,该api较底层,在上面两个方法能够解决问题的情况下建议不要用,使用不当性能损耗非常大)。

补充:利用runtime方法:

UIInterfaceOrientation ifo=[[UIApplication sharedApplication] statusBarOrientation]; (id,SEL,UIInterfaceOrientation,BOOL))objc_msgSend)([UIDevice currentDevice],NSSelectorFromString([NSString stringWithFormat:@"set%@:animated:",tmpStr]),ifo,NO);

补给:参考链接

版权声明:本文由韦德娱乐1946_韦德娱乐1946网页版|韦德国际1946官网发布于网络编程,转载请注明出处:iOS显示器旋转的消除方案www.weide1946.com,差异根视