我给了一个应用程序说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);
}
呈现和解雇模态VC迫使应用程序检查其方向,因此shouldAutorotateToInterfaceOrientation
被调用。
我在IOS 6中尝试过的内容:
- (BOOL)shouldAutorotate{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationLandscapeLeft;
}
在加载时,控制器保持纵向。旋转设备后,方向改变就好了。但是我需要让控制器在加载时自动旋转到横向,因此用户必须旋转设备才能正确查看数据。
另一个问题:将设备旋转回纵向后,虽然我在supportedInterfaceOrientations
中仅指定UIInterfaceOrientationMaskLandscape
,但方向会转为纵向。为什么会这样?
此外,上述3种方法中的 NONE 正在被调用。
一些(有用的)数据:
感谢任何帮助。谢谢。
答案 0 :(得分:43)
好的,伙计们,我会发布我的解决方案。
我有什么:
任务:
访问!
(更新删除了@IvanVučica建议的宏)
在所有PORTRAIT视图控制器中覆盖如下自动旋转方法:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
-(BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
您可以看到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;
}
注意:要强制在 IOS 5 中进行自动旋转,您应该添加以下内容:
- (void)viewDidLoad{
[super viewDidLoad];
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0)
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO];
}
类似地,在您离开LANDSCAPE控制器后,无论您加载什么控制器,都应该再次强制IOS 5进行自动旋转,但现在您将使用UIDeviceOrientationPortrait
,当您转到PORTRAIT控制器时:
- (void)viewDidLoad{
[super viewDidLoad];
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0)
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationPortrait animated:NO];
}
现在最后一件事(而且有点奇怪) - 您必须改变从控制器切换到另一个控制器的方式,具体取决于IOS:
创建一个NSObject类“Schalter”(来自德语的“Switch”)。
在Schalter.h中说:
#import <Foundation/Foundation.h>
@interface Schalter : NSObject
+ (void)loadController:(UIViewController*)VControllerToLoad andRelease:(UIViewController*)VControllerToRelease;
@end
在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
现在,这是您使用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
当然你必须释放instance_to_products
对象:
- (void)dealloc{
[instance_to_products release];
[super dealloc];
}
嗯,就是这样。不要犹豫,我不在乎。这适用于那些寻求解决方案而非声誉的人。 干杯! Sava Mazare。
答案 1 :(得分: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];
我在推动下一个UIViewController
之前打电话给我。即使当前UIViewController
处于横向状态(也应该适用于纵向横向),它将强制下一个推送UIViewController
以纵向模式显示。适用于iOS 4 + 5 + 6。
答案 2 :(得分:14)
我认为最好的解决方案是坚持官方的苹果文档。所以根据我使用以下方法,一切都在iOS 5和6上运行良好。 在我的VC中,我重写了以下方法:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
iOS 6的方法,第一种方法返回支持的方向掩码(如其名称所示)
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
第二个告诉你的VC哪个是VC显示时首选的界面方向。
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
只需更改您想要的方向的肖像;) 这个解决方案工作顺利,我不喜欢创建宏和其他东西的想法,这就是这个简单的解决方案。 希望这有帮助...
答案 3 :(得分: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];
}
@ 2 因为navigationController只响应YES以进行自动旋转,所以我们需要添加一些限制: 扩展UINavicationController - &gt; 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;
}
我希望这会对你有所帮助,
答案 4 :(得分:3)
现在,iOS容器(例如UINavigationController)不会咨询他们的孩子以确定他们是否应该自动旋转。
您的rootViewController
是否将shouldAutoRotate
邮件中的ViewController
邮件传递给您的VC?
答案 5 :(得分:2)
我使用与OP pre-ios6相同的方法(显示和解除模态VC)以横向模式显示单个视图控制器(所有其他视图控制器)。它在ios6中打破了风景VC以肖像显示。
要解决这个问题,我只是在横向VC中添加了preferredInterfaceOrientationForPresentation方法。似乎现在适用于os 5和os 6。
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
- (BOOL)shouldAutorotate
{
return NO;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
答案 6 :(得分:2)
我准备了一个食谱:)。
<强>问题:强> 您需要使用ios 6中的navigationcontroller更改viewcontrollers的方向。
<强>解决方案:强>
第1步。一个初始UIviewcontroler触发模态segue到landscape和 肖像UInavigationControllers如图所示......
在UIViewController1中我们需要根据Appdelegate的全局变量进行2次segues动作....-(void)viewDidAppear:(BOOL)animated{
if([globalDelegate changeOrientation]==0){
[self performSegueWithIdentifier:@"p" sender:self];
}
else{
[self performSegueWithIdentifier:@"l" sender:self];
}
}
我们还需要一种回到肖像&amp; |的方法景观....
- (IBAction)dimis:(id)sender {
[globalDelegate setChangeOrientation:0];
[self dismissViewControllerAnimated:NO completion:nil];
}
第2步。每个NavigationController上的第一个Pushed UiViewControllers都会启动 与...
-(NSUInteger)supportedInterfaceOrientations{
return [self.navigationController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate{
return YES;
}
第3步。我们在UInavigationController的子类中覆盖supportedInterfaceOrientations方法....
你的customNavigationController中的我们有.....
-(NSUInteger)supportedInterfaceOrientations{
if([self.visibleViewController isKindOfClass:[ViewController2 class]]){
return UIInterfaceOrientationMaskPortrait;
}
else{
return UIInterfaceOrientationMaskLandscape;
}
}
第4步。在故事板或代码中,将wantsFullScreenLayout标志设置为yes,同时设置为纵向和横向uinavigationcontrollers。
答案 7 :(得分:1)
尝试使用一个类别或被子类化的UINavigationController
来指定所需的方向,然后转到所需的VC。阅读更多here。
答案 8 :(得分:1)
作为替代方案,你可以使用块来做同样的事情:
UIViewController *viewController = [[UIViewController alloc] init];
viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:viewController animated:NO completion:^{
[self dismissViewControllerAnimated:NO completion:nil];
}];
另外,在推送新视图之前调用它。
答案 9 :(得分:0)
转到Info.plist文件并进行更改
答案 10 :(得分:0)
我遇到了同样的问题。如果要强制特定视图控制器以横向显示,请在将其推入导航堆栈之前立即执行。
UIInterfaceOrientation currentOrientation = [[UIApplication sharedApplication] statusBarOrientation];
if (currentOrientation == UIInterfaceOrientationPortrait ||
currentOrientation == UIInterfaceOrientationPortraitUpsideDown)
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeLeft];
UIViewController *vc = [[UIViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
[vc release];
答案 11 :(得分:0)
我通过继承UINavigationController并覆盖导航控制器的supportedInterfaceOrientations来解决它,如下所示:
- (NSUInteger)supportedInterfaceOrientations
{
return [[self topViewController] supportedInterfaceOrientations];
}
所有控制器都实现了supportedInterfaceOrientations及其所需的方向。
答案 12 :(得分:-1)
我使用了以下解决方案。在具有与所有其他方向不同的方向的一个视图控制器中,我在 prepareForSegue 方法中添加了方向检查。如果目标视图控制器需要的界面方向与显示的当前视图控制器不同,则会发送一条消息,强制界面在隔离期间旋转。
#import <objc/message.h>
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if(UIDeviceOrientationIsLandscape(self.interfaceOrientation))
{
UIInterfaceOrientation destinationOrientation;
if ([[segue destinationViewController] isKindOfClass:[UINavigationController class]])
{
UINavigationController *navController = (UINavigationController *)[segue destinationViewController];
destinationOrientation = [navController.topViewController preferredInterfaceOrientationForPresentation];
} else
{
destinationOrientation = [[segue destinationViewController] preferredInterfaceOrientationForPresentation];
}
if ( destinationOrientation == UIInterfaceOrientationPortrait )
{
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
{
objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait );
}
}
}
}