I've tried to following methods to force landscape on one my views:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
- (BOOL)shouldAutorotate{
return YES;
}
Neither did work. Note that I'm testing on the simulator and on an iPad.
Thanks
Here is how I forced one of my views to be Landscape using NavigationViewController:
Implemented this answer: https://stackoverflow.com/a/12662433/2394787
Imported message in the View controller: objc/message.h
Added this line of code in the viewDidLoad method:
objc_msgSend([UIDevice currentDevice], #selector(setOrientation:), UIInterfaceOrientationLandscapeLeft);
Hope it helps someone.
The accepted answer doesn't seem to work on iOS 7.1.2. (It works on the simulator but does not work while running on a device.)
This seems to work though:
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:#"orientation"];
[[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationLandscapeLeft] forKey:#"orientation"];
int shouldShowInLandscape = 0;
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(forceToLandscape:)
name:#"yourNameNotification"
object:nil];
}
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
return UIInterfaceOrientationMaskLandscapeLeft;
} else {
if(shouldShowInLandscape)
{
return UIInterfaceOrientationMaskLandscape;
}
return UIInterfaceOrientationMaskPortrait;
}
}
-(void) forceToLandscape:(NSNotification*) theNot
{
shouldShowInLandscape = [[theNot object] intValue];
}
// from the UIViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter]
postNotificationName:#"yourNameNotification"
object:[NSString stringWithFormat:#"1"]];
}
-(void) viewDidDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter]
postNotificationName:#"yourNameNotification"
object:[NSString stringWithFormat:#"0"]];
}
// remove you notificationCenter
Related
After upgrade my project do iOS 9.2 my old code become obsolete
-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
And I found this ugly solution, after receive a rotation notification view set rotation (And repaint with animation my view controller):
-(void)didRotate:(NSNotification *)notification
{
[UIView animateWithDuration:0 animations:^{
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
}];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didRotate:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:YES];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}
How can I lock orientation only in this ViewController?
You can use the below delegate method for the orientation and it can be applicable for the class where the code is being used. These 3 lines of code is fair enough to lock your orientation.
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortrait);
}
For iOS 9 and above
First Identify your base view controller
Suppose it is a Navigation Controller.
Property for Navigation Controller:
#property (strong, nonatomic) UINavigationController *mainNavigationController;
Replace the above with:
#property (strong, nonatomic) MainNavigationContrller *mainNavigationController;
Your MainNavigationContrller.m will look like the below:
#interface MainNavigationContrller ()
#end
#implementation MainNavigationContrller
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if(IPHONE)
{
UIViewController *topVC = ((AppDelegate*)[[UIApplication sharedApplication] delegate]).yourNavigationController.topViewController;
if([topVC isKindOfClass:[yourViewController class]])
{
return UIInterfaceOrientationMaskPortrait;
}
}
return UIInterfaceOrientationMaskAll;
}
With this, you need not to remove your info.plist entries and we can block the orientation for specific view only.
THIS WORKED FOR ME.
I want to disable landscape orientation in some view.
I have overridden the following two methods but these method is not going to call at any time.
- (NSUInteger) supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
Am I missing something?
Please help me.
Create subclass of UINavigationController and override these methods as per below:
- (NSUInteger)supportedInterfaceOrientations
{
if([self.topViewController respondsToSelector:#selector(supportedInterfaceOrientationsForThisContorller)])
{
return(NSInteger)[self.topViewController performSelector:#selector(supportedInterfaceOrientationsForThisContorller) withObject:nil];
}
return UIInterfaceOrientationPortrait | UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight;
}
- (BOOL)shouldAutorotate
{
if([self.visibleViewController respondsToSelector:#selector(shouldAutorotateNow)])
{
BOOL autoRotate = (BOOL)[self.visibleViewController
performSelector:#selector(shouldAutorotateNow)
withObject:nil];
return autoRotate;
}
return YES;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
and use below method in your UIViewController class where you want to set only portrait orientation
- (NSUInteger) supportedInterfaceOrientationsForThisContorller {
// Return a bitmask of supported orientations. If you need more,
// use bitwise or (see the commented return).
return UIInterfaceOrientationMaskPortrait;
// return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
-(BOOL)shouldAutorotateNow
{
return YES;
}
Check out this answer. The guy has probably explained the delegates in much detail.
Also try,
- (void)awakeFromNib
{
isShowingLandscapeView = NO;
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
!isShowingLandscapeView)
{
[self performSegueWithIdentifier:#"DisplayAlternateView" sender:self];
isShowingLandscapeView = YES;
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation) &&
isShowingLandscapeView)
{
[self dismissViewControllerAnimated:YES completion:nil];
isShowingLandscapeView = NO;
}
}
Did you used below method in your code, with out this supportedInterfaceOrientations will not get called
-(BOOL) shouldAutorotate
{
return YES;
}
My app running only in landscape mode, but i want display one View in portrait mode. So i have created project using Unified storyboards (Xcode 6). My project is running only which are targeted in Deployment Info.
and my view controller
What I do wrong? Help me.
I faced the same issue few weeks ago. I created new UIViewController with portrait orientation. Later I realised that changing orientation is not enough, then I used this below code to change the orientation.Use the below code to change orientation.
-(void)viewWillAppear:(BOOL)animated
{
[self willAnimateRotationToInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation duration:.2];
[self awakeFromNib];
}
-(void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
if(is_iPad)
{
return YES;
}else
{
return (UIInterfaceOrientationIsPortrait(toInterfaceOrientation));
}
}
- (void)awakeFromNib
{
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
delegate->isShowingLandscapeView=NO;
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
if (is_iPad) {
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
!delegate->isShowingLandscapeView)
{
yourPotraitViewController *ypvc =[[yourPotraitViewController alloc] initWithNibName:#"yourPotraitViewController" bundle:nil];
[self.navigationController pushViewController:objHomeLandscape animated:YES];
delegate->isShowingLandscapeView=YES;
// isShowingLandscapeView = YES;
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation) &&
delegate->isShowingLandscapeView)
{
[self.navigationController popViewControllerAnimated:YES];
delegate->isShowingLandscapeView=NO;
}
}
}
I need to record video always in landscape mode even my device rotating (Portrait->Landscape->Portrait ).
To take angle is simple, im using hyroscope. My problem is to record video in landscape always. Any advices needed.
Im using AVCaptureSession to video rec. AVMutablecomposition? I dont know what to use...
help me,please
Why not forcing your Controller to be only in landscape mode ?
You can do it like this :
- (BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
You can try this code
#implementation PortraitViewController
- (void)awakeFromNib
{
isShowingLandscapeView = NO;
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
!isShowingLandscapeView)
{
[self performSegueWithIdentifier:#"DisplayAlternateView" sender:self];
isShowingLandscapeView = YES;
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation) &&
isShowingLandscapeView)
{
[self dismissViewControllerAnimated:YES completion:nil];
isShowingLandscapeView = NO;
}
}
Also have look on the Apple's docs HERE for detail rotation implementations.
Try this before starting to record a video:
let videoDataOuputConnection = videoFileOutput.connection(with: .video)
videoDataOuputConnection!.videoOrientation = AVCaptureVideoOrientation.landscapeLeft
Im currently working with a IPhone-app that has a "timetable".
in portrait i want it to have a regular table-view with some customization! When i have the IPhone in landscape i want it to change to a more "timetable"-view, with tables and rows.
Is it possible?
Try This
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self adjustViewsForOrientation:toInterfaceOrientation];
}
-(void) adjustViewsForOrientation:(UIInterfaceOrientation)orientation
{
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{
//write code for portrait mode
}
else if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
//write code for landscape mode
}
}
See Apples documentation Creating an Alternate Landscape Interface
Make sure to read the documentation, but here is the code from the example implementation:
#implementation PortraitViewController
- (void)awakeFromNib
{
isShowingLandscapeView = NO;
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
!isShowingLandscapeView)
{
[self performSegueWithIdentifier:#"DisplayAlternateView" sender:self];
isShowingLandscapeView = YES;
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation) &&
isShowingLandscapeView)
{
[self dismissViewControllerAnimated:YES completion:nil];
isShowingLandscapeView = NO;
}
}
Answer is Yes it's possible through the following method:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation)){
\\ your timetable customisation goes here
}
}
You also need this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}