IOS 6强制设备朝向景观

Joh*_*ith 57 iphone objective-c orientation ios6

我给了一个应用程序说10个视图控制器.我使用导航控制器来加载/卸载它们.

除一个以外的所有人都处于纵向模式 假设第7个VC处于景观状态.我需要它在加载时以横向呈现.

请建议在IOS 6中强制定位从纵向到横向的方法(在IOS 5中工作也很好).

以下是我 IOS 6 之前做的事情:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    UIViewController *c = [[[UIViewController alloc]init] autorelease];
    [self presentModalViewController:c animated:NO];
    [self dismissModalViewControllerAnimated:NO];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
Run Code Online (Sandbox Code Playgroud)

呈现和解雇模态VC迫使应用程序检查其方向,因此shouldAutorotateToInterfaceOrientation被调用.

我在IOS 6中尝试过的内容:

- (BOOL)shouldAutorotate{
    return YES;
}
-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    return UIInterfaceOrientationLandscapeLeft;
}
Run Code Online (Sandbox Code Playgroud)

在加载时,控制器保持纵向.旋转设备后,方向改变就好了.但是我需要让控制器在加载时自动旋转到横向,因此用户必须旋转设备才能正确查看数据.

另一个问题:该装置旋转回纵向后,方向变为纵向,虽然我在指定supportedInterfaceOrientations唯一的UIInterfaceOrientationMaskLandscape.为什么会这样?

此外,上述3种方法越来越被调用.

一些(有用的)数据:

  1. 在我的plist文件中,我指定了3个方向 - 所有方向都是颠倒的.
  2. 该项目是在Xcode 4.3 IOS 5中启动的.包括xib在内的所有类都是在Xcode 4.5 IOS 6之前创建的,现在我使用的是最后一个版本.
  3. 在plist文件中,状态栏设置为可见.
  4. 在xib文件中(我希望在横向中),状态栏为"无",方向设置为横向.

任何帮助表示赞赏.谢谢.

Joh*_*ith 43

伙计们,我会发布我的解决方案.

是)我有的:

  1. 基于视图的应用程序,具有多个视图控制器.(这是基于导航的,但由于方向问题,我不得不将其视为基于视图).
  2. 所有视图控制器都是纵向的,除了一个 - landscapeLeft.

任务:

  1. 无论用户如何握住设备,我的一个视图控制器都必须自动旋转到横向.所有其他控制器必须是纵向的,并且在离开横向控制器后,应用程序必须强制旋转为纵向,无论用户如何握住设备.
  2. 这必须像IOS 6.x一样在IOS 5.x上运行

走!

(更新删除了@IvanVučica建议的宏)

在所有PORTRAIT视图控制器中覆盖自动旋转方法,如下所示:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
    return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
-(BOOL)shouldAutorotate {
    return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}
Run Code Online (Sandbox Code Playgroud)

您可以看到2种方法:一种用于IOS 5,另一种用于IOS 6.

您的LANDSCAPE视图控制器也是如此,但有一些添加和更改:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
    [image_signature setImage:[self resizeImage:image_signature.image]];
    return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
-(BOOL)shouldAutorotate {
    return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
    [image_signature setImage:[self resizeImage:image_signature.image]];
    return UIInterfaceOrientationMaskLandscapeLeft;
}
Run Code Online (Sandbox Code Playgroud)

注意:要在IOS 5强制自动旋转,你应该添加:

- (void)viewDidLoad{
    [super viewDidLoad];
    if ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0)
        [[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO];    
}
Run Code Online (Sandbox Code Playgroud)

类似地,在您离开LANDSCAPE控制器后,无论您加载什么控制器,都应该再次强制IOS 5自动旋转,但现在您将使用UIDeviceOrientationPortrait,当您转到PORTRAIT控制器时:

- (void)viewDidLoad{
        [super viewDidLoad];
        if ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0)
            [[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];    
    }
Run Code Online (Sandbox Code Playgroud)

现在最后一件事(而且有点奇怪) - 您必须改变从控制器切换到另一个控制器的方式,具体取决于IOS:

创建一个NSObject类"Schalter"(德语中的"Switch").

在Schalter.h中说:

#import <Foundation/Foundation.h>

@interface Schalter : NSObject
+ (void)loadController:(UIViewController*)VControllerToLoad andRelease:(UIViewController*)VControllerToRelease;
@end
Run Code Online (Sandbox Code Playgroud)

在Schalter.m说:

#import "Schalter.h"
#import "AppDelegate.h"

@implementation Schalter
+ (void)loadController:(UIViewController*)VControllerToLoad andRelease:(UIViewController*)VControllerToRelease{

    //adjust the frame of the new controller
    CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
    CGRect windowFrame = [[UIScreen mainScreen] bounds];
    CGRect firstViewFrame = CGRectMake(statusBarFrame.origin.x, statusBarFrame.size.height, windowFrame.size.width, windowFrame.size.height - statusBarFrame.size.height);
    VControllerToLoad.view.frame = firstViewFrame;

    //check version and go
    if (IOS_OLDER_THAN_6)
        [((AppDelegate*)[UIApplication sharedApplication].delegate).window addSubview:VControllerToLoad.view];
    else
        [((AppDelegate*)[UIApplication sharedApplication].delegate).window setRootViewController:VControllerToLoad];

    //kill the previous view controller
    [VControllerToRelease.view removeFromSuperview];
}
@end
Run Code Online (Sandbox Code Playgroud)

现在,这是您使用Schalter的方式(假设您从Warehouse控制器转到Products控制器):

#import "Warehouse.h"
#import "Products.h"

@implementation Warehouse
Products *instance_to_products;

- (void)goToProducts{
    instance_to_products = [[Products alloc] init];
    [Schalter loadController:instance_to_products andRelease:self];
}

bla-bla-bla your methods

@end
Run Code Online (Sandbox Code Playgroud)

当然你必须释放instance_to_products对象:

- (void)dealloc{
     [instance_to_products release];
     [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

好吧,就是这样.不要犹豫,我不在乎.这适用于那些寻求解决方案而非声誉的人.干杯! Sava Mazare.

  • 那些`#ifdef IOS_OLDER_THAN_6`行没有做任何事情,因为你显然无条件地定义了这些宏.即使他们这样做了,他们也会进行编译时检查.你以后使用这些宏是没问题的. (7认同)
  • 这些宏(例如`IOS_OLDER_THAN_6`)不应该用于检查iOS版本.`systemVersion`不是浮点值(例如5.1.1不是浮点数),实际上它有时会导致错误的结果.[请参阅此处了解正确的方法](http://stackoverflow.com/a/5337804/119114) (3认同)

小智 34

这应该工作,它类似于iOS 6之前的版本,但有一个UINavigationController:

UIViewController *portraitViewController = [[UIViewController alloc] init];
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:portraitViewController];
[self.navigationController presentModalViewController:nc animated:NO];
[self.navigationController dismissModalViewControllerAnimated:NO];
Run Code Online (Sandbox Code Playgroud)

我在推动下一个之前就打电话给我UIViewController.UIViewController即使当前UIViewController处于横向状态(也应该适用于纵向横向),它将强制下一个按下以纵向模式显示.适用于iOS 4 + 5 + 6.

  • 你能详细说明何时应该使用它?我遇到了同样的问题,当我的其他视图控制器是纵向时,我需要下一个推动的视图控制器处于横向状态.我正在使用UINavigationController,但不确定应该放置此代码的位置.在推动我的横向视图控制器之前,我尝试使用此代码,但这不起作用 (2认同)

Sko*_*k.o 14

我认为最好的解决方案是坚持官方的苹果文档.所以根据我使用以下方法,一切都在iOS 5和6上运行良好.在我的VC中我覆盖以下方法:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
Run Code Online (Sandbox Code Playgroud)

适用于iOS 6的方法,第一种方法返回支持的方向掩码(如其名称所示)

-(NSUInteger)supportedInterfaceOrientations{

    return UIInterfaceOrientationMaskPortrait;
}
Run Code Online (Sandbox Code Playgroud)

第二个告诉你的VC,当VC要显示时,哪个是首选的界面方向.

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}
Run Code Online (Sandbox Code Playgroud)

只需改变你想要的方向肖像;)这个解决方案工作顺利,我不喜欢创建宏和其他东西的想法,这就是这个简单的解决方案.希望这有帮助......


小智 7

我有同样的问题,在我的应用程序中有27个视图,其中26个是纵向的,只有一个在所有方向(图像查看器:)).在每个类上添加宏并替换导航不是我觉得舒服的解决方案......

所以,我想在我的应用程序中保留UINavigationController机制,而不是用其他代码替换它.

该怎么办:

@ 1在方法didFinishLaunchingWithOptions中的应用程序委托中

if ([[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
    // how the view was configured before IOS6
    [self.window addSubview: navigationController.view];
    [self.window makeKeyAndVisible];
}
else
{
    // this is the code that will start the interface to rotate once again
    [self.window setRootViewController: self.navigationController];
}
Run Code Online (Sandbox Code Playgroud)

@ 2因为navigationController只响应YES以进行自转,我们需要添加一些限制:扩展UINavicationController - > YourNavigationController并将其链接到Interface Builder中.

@ 3从导航控制器覆盖"anoying new methods".

由于此类仅适用于此应用程序,因此它可以对其控制器负责并在其位置进行响应.

-(BOOL)shouldAutorotate {

    if ([self.viewControllers firstObject] == YourObject)
    {
         return YES;
    }
    return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
     if ([self.viewControllers firstObject] == YourObject)
    {
         return UIINterfaceOrientationMaskLandscape;
    }
    return UIInterfaceOrientationMaskPortrait;
}
Run Code Online (Sandbox Code Playgroud)

我希望这能帮到您,