[英]How to “lock” a view's orientation during device rotation
Let's say I have a view controller, call it ViewControllerPortrait, which is designed to display in portrait mode only. 假设我有一个视图控制器,称为ViewControllerPortrait,它仅设计为以纵向模式显示。 Eg:
例如:
When the user rotates the device to landscape, I don't want ViewControllerPortrait to ever re-orient itself to landscape, but I do want to present a new full-screen view. 当用户将设备旋转为横向时,我不希望ViewControllerPortrait再次将自身重新定向为横向,但我确实希望呈现一个新的全屏视图。 Let's call the full-screen view controller ViewControllerLandscapeFull.
我们将其称为全屏视图控制器ViewControllerLandscapeFull。 Eg:
例如:
What I don't ever want to see is this: 我永远不想看到的是:
The way I tried to do this is to have the window's rootViewController present ViewControllerLandscapeFull in full screen when it gets a willRotateToInterfaceOrientation:duration:
我尝试执行此操作的方法是让窗口的rootViewController在获取
willRotateToInterfaceOrientation:duration:
时全屏显示ViewControllerLandscapeFull willRotateToInterfaceOrientation:duration:
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
[navigationViewController setNavigationBarHidden:YES animated:YES];
self.viewControllerPortrait = [[ViewControllerPortrait alloc] init];
self.viewControllerPortrait.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:self.viewControllerPortrait animated:NO completion:NULL];
And then in ViewControllerLandscapeFull I have: 然后在ViewControllerLandscapeFull中,我有:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape | UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return (UIInterfaceOrientation)[UIDevice currentDevice].orientation;
}
This works fairly well. 这工作得很好。 Since ViewControllerLandscapeFull "prefers" landscape and has a
UIModalPresentationFullScreen
modalPresentationStyle
, it only ever shows in landscape. 由于ViewControllerLandscapeFull“更喜欢”风景并且具有
UIModalPresentationFullScreen
modalPresentationStyle
,因此它仅在风景中显示。 By returning landscape | portrait
返回
landscape | portrait
landscape | portrait
for supportedInterfaceOrientations, device rotations back to portrait are allowed which happens when ViewControllerLandscapeFull gets willRotateToInterfaceOrientation:duration:
and eventually dismissViewControllerAnimated:NO
is called on it. landscape | portrait
用于supportedInterfaceOrientations,设备旋转回纵向被允许时ViewControllerLandscapeFull得到这恰好willRotateToInterfaceOrientation:duration:
最终dismissViewControllerAnimated:NO
叫就可以了。
The only problem I have is that during the rotation back to portrait, you can momentarily see ViewControllerPortrait in landscape orientation, and that's what I'm trying to avoid. 我唯一的问题是,在旋转回纵向时,您可以暂时以横向看到ViewControllerPortrait,这就是我要避免的事情。
ViewControllerPortrait does implement: ViewControllerPortrait确实实现了:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
And I've verified that UIKit is calling it but it apparently has no effect. 而且我已经证实UIKit正在调用它,但是它显然没有作用。 (The docs say that
supportedInterfaceOrientations
is only called on root view controllers and view controllers presented full screen, so I'm actually surprised UIKit calls it at all.) (文档说,
supportedInterfaceOrientations
仅在根视图控制器上调用,并且视图控制器全屏显示,因此,我真的很惊讶UIKit完全调用它。)
FWIW, I'm working with the iOS 8 beta 5 SDK and building for 7/8. FWIW,我正在使用iOS 8 beta 5 SDK,并为7/8构建。
Muchas gracias. Muchas gracias。
I'm just beginning programming with iPhones, but maybe this will work... 我刚刚开始使用iPhone进行编程,但这也许行得通...
Click on your project file > deployment info. 单击项目文件>部署信息。 Then unclick everything except portrait.
然后取消单击除肖像以外的所有内容。 This way rotating the device won't reorientate itself.
这样,旋转设备不会重新定位自身。
However, you can still test whether the device rotates or not with this: 但是,您仍然可以使用以下方法测试设备是否旋转:
- (BOOL)shouldAutorotate
{
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
{
NSLog(@"ROTATE to landscape");
kitty.hidden = NO;
//(kitty is my imageview, hidden on load), once the device rotates to landscape, you can show your image.(or you can do something else)
}
else{
NSLog(@"ROTATE to portrait");
kitty.hidden = YES;
}
return YES;
}
houldAutorotate, supportedInterfaceOrientations, preferredInterfaceOrientationForPresentation
The above methods don't get called of a viewcontroller if they are inside any tabbarcontroller of navigationcontroller. 如果上述方法位于Navigationcontroller的任何tabbarcontroller中,则不会调用viewcontroller。 If these methods are declared inside tabbarcontroller or navigation controller then they will get called.
如果在tabbarcontroller或导航控制器中声明了这些方法,则将调用它们。 In my case the viewcontrollers was inside navigationcontroller and the navigation controllers are inside a tabbarcontroller.
在我的情况下,视图控制器位于navigationcontroller内,而导航控制器位于tabbarcontroller内。
For solving this I make a class FixedOrientationTab
, it is a subclass of UITabBarController
, and a navigation class OrientationEnabledNavigation
, it is a subclass of UINavigationController
. 为了解决这个问题,我创建了
FixedOrientationTab
类,它是UITabBarController
的子类,而导航类OrientationEnabledNavigation
是UINavigationController
的子类。 Then I implemented shouldAutorotate
, supportedInterfaceOrientations
, preferredInterfaceOrientationForPresentation
methods inside FixedOrientationTab
and OrientationEnabledNavigation
. 然后,我实现
shouldAutorotate
, supportedInterfaceOrientations
, preferredInterfaceOrientationForPresentation
方法里面FixedOrientationTab
和OrientationEnabledNavigation
。
OrientationEnabledNavigation.h OrientationEnabledNavigation.h
#import <UIKit/UIKit.h>
@interface OrientationEnabledNavigation : UINavigationController
@end
OrientationEnabledNavigation.m OrientationEnabledNavigation.m
#import "OrientationEnabledNavigation.h"
@interface OrientationEnabledNavigation ()
@end
@implementation OrientationEnabledNavigation
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
// return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
FixedOrientationTab.h FixedOrientationTab.h
#import <UIKit/UIKit.h>
@interface FixedOrientationTab : UITabBarController
@end
FixedOrientationTab.m FixedOrientationTab.m
#import "FixedOrientationTab.h"
@interface FixedOrientationTab ()
@end
@implementation FixedOrientationTab
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (BOOL)shouldAutorotate
{
return [self.selectedViewController shouldAutorotate];
// return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
Then if you want to use navigation controller in your project then use OrientationEnabledNavigation
and for tabbar FixedOrientationTab
. 然后,如果要在项目中使用导航控制器,请使用
OrientationEnabledNavigation
并将其用于FixedOrientationTab
。 After that if you implement shouldAutorotate
, supportedInterfaceOrientations
, preferredInterfaceOrientationForPresentation
these method inside your viewcontroller then they will get called. 之后,如果您在viewcontroller中实现了
shouldAutorotate
, supportedInterfaceOrientations
, preferredInterfaceOrientationForPresentation
这些方法,则将调用它们。
Hope this helps.. :) 希望这可以帮助.. :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.