在风景模式呈现导航控制器不工作的ios 6.0(Presenting Navigation Cont

2019-08-17 18:29发布

这是我的代码。

 SomeController *analyticsViewController = [[SomeController alloc] init];

 MTNavigaionLandscapeViewController *analyticsNavigaionObject =  [[MTNavigaionLandscapeViewController alloc] initWithRootViewController:analyticsViewController];

 [analyticsNavigaionObject setNavigationBarHidden:YES];

 if ([self respondsToSelector:@selector(presentModalViewController:animated:completion:)]) {
      [self presentViewController:analyticsNavigaionObject animated:YES completion:nil];
  } else {
          [self presentModalViewController:analyticsNavigaionObject animated:YES];
  }
  [analyticsViewController release];
  [analyticsNavigaionObject release];

这里是SomeController.m的支撑取向

- (NSUInteger)supportedInterfaceOrientations
{
 return UIInterfaceOrientationMaskLandscape;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
  return UIInterfaceOrientationLandscapeRight;
}

而在MTNavigaionLandscapeViewController支撑取向(UINavigationController的子类)

- (NSUInteger)supportedInterfaceOrientations
{
 return UIInterfaceOrientationMaskLandscape;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
 return UIInterfaceOrientationLandscapeRight;
}

最后,如果我目前只有SomeController,它工作得很好。我的问题是,当我提出Navigationcontroller再出现问题。 请帮我

Answer 1:

写这些方法在你的ViewController你所要提出:

- (BOOL)shouldAutorotate
{
    AppDelegate *mainDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
    mainDelegate.shouldRotate = YES;
    return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeRight;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return YES;
}

在您的AppDelegate.m粘贴此

- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    if(self.shouldRotate)
    {
        self.shouldRotate = NO;
        return UIInterfaceOrientationMaskLandscapeRight;
    }
    return UIInterfaceOrientationMaskPortrait;
}

在您的AppDelegate.h粘贴此

@property (assign, nonatomic) BOOL shouldRotate;

在viewWillAppear中你presentingViewController粘贴此:

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];


Answer 2:

如何强制将iPhone旋转至某个方位。

问题

iPhone和iPad应用程序可以支持纵向或横向或两者兼而有之。 有时,一个或极少数的意见需要显示在纵向或横向只或在非常方向,其余的应用程序不支持。 iOS或可可框架分别提供的方法来单独定义对于每个视图,其方向被支撑。 然而,除非任何限制适用于所有的应用程序,并分别对项目或目标水平因此被定义的,它始终是有权执行旋转用户。 该应用程序可以决定是否支持某个方向,但它不能强迫实际旋转系统。

本教程介绍了此功能不全如何可以克服的。

给出的例子是呈现所有,但在纵向模式下的视图控制器之一的iPhone应用程序。 对于良好的设计和易用性的原因,视图控制器之一,仅景观工程。

这是迄今为止被证明在iPhone上的iOS 6。

旋转模态呈现视图控制器

当视图有模式提出了这个任务是很容易。 对于模态呈现视图控制器,被呈现应该支持仅和所述呈现视图模态之前风景视图控制器,视图控制器的取向应设置为风景。

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:YES];
[self presentModalViewController:landscapeVC animated:YES];

这样,视图控制器landscapeVC将在横向呈现。

但是为了保持导航栏等。我想将它推到导航控制器的堆栈。 不幸的是,除非用户实际旋转时,其设备不会转动其方向。

此外,我的应用程序有两个目标。 其中之一的导航是基于标签栏和其他目标的导航(功能减少了免费版)是平原。 因此,我的解决方案需要适合既与标签栏和应用,而无需应用程序。

因此,这种解决方案可能是超大对于只有标签栏或根本就没有一个应用程序。 但是,它在任何情况下。

定向发行与标签栏控制器

当一个选项卡栏显示其视图控制器,那么它是选项卡栏控制器谁控制的取向。 实际上这意味着内提出的所有意见都应该支持所有相同的方向。 为了克服这一点,我们需要继承UITabBar并引入控制标签栏是否应该支持横向或没有的一些功能。

更改应用程序委托

在我来说,我添加了一个布尔变量来申请委托。 这是因为标签栏或不运行的二元性。 如果你只有一个标签栏,你可能会去添加该变量作为财产的标签栏子类。 对于OOP休书单例将是不错,但我认为这是一个布尔开关有点过大。

AppDelegate.h:

@property BOOL  isLandscapePreferred;

它是自动合成。 它的默认值是NO 。 但是,您可能要设置NO明确application:didFinishLoadingWithOptions:在您的应用程序委托。

对于没有标签栏的工作目标,我所有的视图控制器需要到设置作出回应。 基本上是呈现横向视图的一个必须实现以下。 不过,这并不伤害具有都在应用程序尤其是当有在您的应用程序超过一个观点,你需要进行横向显示。

更改的UIApplication

以下一些建议,我在网上找到,我决定继承的UIApplication并覆盖supportedInterfaceOrientations那里。 不过,我仍然标记所有方向为支持在Xcode目标的摘要窗格中,虽然设置应该由UIApplication的覆盖。

MyApp.h和MyApp.m:

#import <UIKit/UIKit.h>

@interface MyApp : UIApplication

@end

#import "MyApp.h"
#import "AppDelegate.h"

@implementation MyApp

- (NSUInteger)supportedInterfaceOrientationsForWindow:(UIWindow *)window {

    if ([(AppDelegate*) [[UIApplication sharedApplication] delegate] isLandscapePreferred]) {
        return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeLeft);
        NSLog(@"PhotocollApp: Landscape");
    } else {
        return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
        NSLog(@"PhotocollApp: Portrait");
   }

}

@end

从主调用MyApp的

接下来,我们需要确保我们的子类的一个应用对象是在应用程序启动实例化。 这需要在main.m.变化

#import <UIKit/UIKit.h>

#import "AppDelegate.h"
#import "PhotocollApp.h"

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, NSStringFromClass([MyApp class]), NSStringFromClass([AppDelegate class]));
    }
}

UIApplicationMain传递两个接收参数argcargv前两个参数,后面两个NSString代表应用程序的类名和应用程序委托类对象。 我没有改变应用程序委托的标准名称,但我们需要在这里找出我们自己的应用程序类。

在所有视图控制器重写supportedInterfaceOrientations

我已经介绍的“抽象”的子类UIViewControllerUITableViewController 。 我所有的视图控制器的从他们继承:

MyRotatingViewController.h和.M:

#import <UIKit/UIKit.h>

@interface MyRotatingViewController : UIViewController

@end

#import "MyRotatingViewController.h"
#import "AppDelegate.h"

@implementation MyRotatingViewController

// … 

#pragma mark - Rotation Management

- (BOOL) shouldAutorotate {

    return NO;
}

- (NSUInteger)supportedInterfaceOrientations {

    if ([(AppDelegate*) [[UIApplication sharedApplication] delegate] isLandscapePreferred]) {
        return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeLeft);
    } else {
        return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
    }

}

@end

正是为同MyRotatingTableViewController 。 唯一的区别是在.h文件。 当然它继承UITableViewController

#import <UIKit/UIKit.h>

@interface MyRotatingTableViewController : UIViewTableController

@end

确保所有(受影响)的视图控制器继承MyRotatingViewControllerMyRotatingTableViewController分别。 相反,实施这个“抽象”类的,你当然可以实现shouldAutorotatesupportedInterfaceOrientations所有相关的视图控制器。

自定义标签栏类

如上所述,在标签栏驱动的应用程序,它是选项卡栏,它的方法控制取向的设置,而不是那些视图控制器通过标签栏呈现。

//  MyTabBarController.h
#import <UIKit/UIKit.h>

@interface MyTabBarController : UITabBarController

@end

//  MyTabBarController.m

#import "MyTabBarController.h"

#import "AppDelegate.h"

@interface MyTabBarController ()

@end

@implementation MyTabBarController

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - Rotation Management

- (BOOL) shouldAutorotate {

    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {


    if ([(AppDelegate*) [[UIApplication sharedApplication] delegate] isLandscapePreferred]) {
        return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeLeft);
    } else {
        return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
    }

}
@end

由于我用故事板我只需要设置MyTabBarController在IB内的唯一标签栏对象的属性面板。 如果编程创建它,然后只需实例化MyTabBarController代替UITabBarController

调用视图控制器被迫景观

根据80/20法则,我们刚刚度过了20%的实际工作,80%的准备。 现在,真正的工作来... ...

这是一个视图控制器,其中,所述横向视图推的那非常方法的中间。 在我而言,这是一个tableView:didSelectRowAtIndexPath:实施。 当然它可以是一个内IBAction方法或内prepareForSegue:sender:方法。 如果你这样做,在prepareForSegue那么你就有可能在运行时错误控制台上的警告。 我还没有看到任何一方面出现故障,但是,从另一方面来说,我不知道什么时候应用程序提交到店,这是否会通过或引起拒绝。

关键是要设置状态栏为横向的方向,然后以呈现视图控制器模态。 现在,设备处于横向模式。 用户不应该迄今所看到的东西。 即使,赤裸裸的视图控制器没有一个视图。 一比零视图不会在所有显示。 接下来这个最近提出视图控制器驳回。 之后,真正的视图控制器将被推到导航堆栈。

这是代码:

//set the landscape switch for the tab bar, view controllers and application
[(AppDelegate*) [[UIApplication sharedApplication] delegate] setIsLandscapePreferred:YES];

//set statusbar to the desired rotation position
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft animated:YES];

// Create any view controller. UIViewController will do. 
// Present it modally and directly after that dismiss it again. 
UIViewController *anyVC = [[UIViewController alloc] init];
[self presentModalViewController: anyVC animated:NO];
[self dismissModalViewControllerAnimated:NO];
// The user should not have noticed anything but how the device is in landscape orientation

//Frankly I am not sure whether the next statement must be included or does not need to be. 
//While working on “my” solution I came across a number of tricks and hints on several places on the web and this was amongst them.
//At least it does not do any harm. 
if ([UIViewController respondsToSelector:@selector(attemptRotationToDeviceOrientation)]) {
    // this ensures that the view will be presented in the orientation of the device
    // This method is only supported on iOS 5.0.  iOS 4.3 users may get a little dizzy.
    [UIViewController attemptRotationToDeviceOrientation];
}

// Get the storyboard named secondStoryBoard from the main bundle:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];

// I am using storyboard in this project. If you don’t do that then you could just instantiate the view controller the usual way with alloc/init or by loading from nib. 
LandscapeVC *landscapeVC = (landscapeVC *)[storyBoard instantiateViewControllerWithIdentifier:@"LandscapeVC"];


// Then push the new view controller in the usual way:
[self.navigationController pushViewController:paintingVC animated:YES];

在横向视图控制器

我们几乎在那里。 现在,新的视图控制器LandscapeVC呈现在标签栏的应用程序风景模式。 对于没有标签栏的应用程序,我们需要用些更改LandscapeVC视图控制器本身。 当然,我们需要确保当在横向模式视图控制器驳回设备转回到肖像。

LandscapeVC.m的Sniplets

#pragma mark - actions

// certain tasks need to be performed before the view controller is dismissed. This could be done within the viewWillDisappar. 
// Again, if you do that in viewWillDisappear: then you risk some warnings on the console. I have decided to overlay the “Back” button (leftBarButtonItem) with a custom button that invokes the following action. 
- (IBAction)done :(id)sender{

    //set the landscape switch back to off/NO/portrait
    [(AppDelegate*) [[UIApplication sharedApplication] delegate] setIsLandscapePreferred:NO];

    //set statusbar to the desired rotation position
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:YES];

    //present/dismiss viewcontroller in order to activate rotating.
    UIViewController *mVC = [[UIViewController alloc] init];
    [self presentModalViewController:mVC animated:NO];
    [self dismissModalViewControllerAnimated:NO];

    [self.navigationController popViewControllerAnimated:YES];
    return;
}

#pragma mark - Rotation
// Rotation

-(BOOL)hidesBottomBarWhenPushed{
// This one is just for my design. I like to use the full screen of the iPhone for my landscape view controller. 
// In the end it is the size of the pane in my case which motivates me to break with UI guidelines and force the user to use this single view controller in landscape only. 
// Besides this design issue this method is not required for the rotation itself. 
// What it does: It overwrites the getter of the UIViewController property hidesBottomBarWhenPushed. 
// By returning YES as constant the bottom bar (= tab bar in my case) will be hidden. 
// However, it remains hidden in the event that any more view controllers are pushed on top of the navigation stack. 
// So if you plan to drill further down in your navigation from here, it may not be a good idea to hide the bottom bar. 
// You will not get it back until the user returns to the calling view controller. 
    return YES;
}

// Well, if all of your view controllers inherit from MyRotatingViewController or MyRotatingTableViewController
// respectively then the following is redundant. 
// While writing this “tutorial” for stack overflow I noticed that this
// very view controller does not. Don’t ask me why. I may fix it later. 
// However, I want to show to you what is proven to work fine. Therefore I owe you these methods. 
-(BOOL)shouldAutorotate{
    return NO;
}

- (NSInteger)supportedInterfaceOrientations{
    return (UIInterfaceOrientationLandscapeRight | UIInterfaceOrientationLandscapeLeft);
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    return (UIInterfaceOrientationLandscapeLeft);
}

而已。 相当直接的,不是吗?



文章来源: Presenting Navigation Controller in Landscape mode is not working ios 6.0