I have portrait only app which do video capturing and some other tasks! everything is working fine, I want to keep app in portrait, but Camera view in landscape only. I have rotated single view test in portrait app by using UIInterfaceOrientationMask but Rotating Camera view caused the Following Crash:
Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES'
for further info I m using following line to insert show camera. I insert camera view only when app is in landscape. I use following line of code to show camera!
[self.view insertSubview:imagePicker.view atIndex:0];
any solution/suggestion please?
First change your orientation settings to support landscape and portrait. Create a UINavigationController category and add this lines. (I assume that your center view controller is a navigation controller)
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
and present your image picker.
Edit: In iOS7 this method is not working. I guess the only proper way is creating a layer for camera controls and subclass uiimagepickerview to support landscape only.
Related
I am working on an App which is written in Objective-C. I have more screens and all screens are Landscape Left and Landscape Right orientations and these screens must not be in portrait mode. But I have got 3 different screens which should be in only Portrait mode must not be in Landscape Left or Landscape Right.
This is the code for Landscape mode for all screens-
And this is for Portrait mode for my app
These are all I did in my View Controllers and In app Plist I have added needed orientations like This Info.plist
And the app device orientation will automatically changes. like this -
.
I am pretty sure all is clear and should work as it is expected but for some reason when I use the app and lock the auto rotation and run the app it is automatically opening in Portrait mode and when I unlock the autorotation it will be in Landscape and you rotate it will be rotated to Portrait mode. I used shouldAutorate return YES because it should rotate it automatically between Landscape Left and Landscape Right so I used it also the portrait mode screen is opening in Portrait but it is autorotating when user rotates the device.
Any help would be appreciated, Please share any idea why my app is not working as expected.
Following are the steps to fix this issue:
Remove orientations from plist because it overrides whatever logic you have in your view controller.
Keep below code where you have landscape orientations:
-(BOOL)shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
For portrait mode use it as below:
-(BOOL)shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Now try locking the orientation your first view controller will appear in landscape and other one will be portrait regardless of orientation lock.
I have a UIViewController with the following code:
- (BOOL) shouldAutorotate {
return NO;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationPortrait;
}
I am not using a UINavigationController. When this UIViewController is being displayed, the device will still rotate to landscape. I am targeting iOS 9, what's the issue here?
So the issue was that I had defined the allowed orientations in info.plist which apparently overrides anything you do anywhere else throughout the project.
To correct the issue I removed the entries from info.plist and defined them in the project settings. Now everything works as expected.
I don't think Bryan's answer works,for changing the orientations in project settings also changes the info.plist as #mrhangz commented.
If the issue is iOS9 only,it is probably due to the new feature of iOS9 in iPad called Split view.The iOS9 enable Split view by default in particular iPad device,see Apple documents here.
The split view forced your app to support all orientations in all view once adoptted.So if you set all orientations support in either info.plist or target general setting,and then split view is supported by default,which will ignore the orientation setting though supportedInterfaceOrientations in your viewController and support all orientations.
As the document written,if you checked Requires full screen in your target settings,then your app will not support split view.Now you can control orientations in code again.
I have try many solution, but the correct answer with working solution is:
ios 8 and 9, no need to edit info.plist.
- (BOOL) shouldAutorotate {
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return (UIInterfaceOrientationPortrait | UIInterfaceOrientationPortraitUpsideDown);
}
possible orientation
UIInterfaceOrientationUnknown
The orientation of the device cannot be determined.
UIInterfaceOrientationPortrait
The device is in portrait mode, with the device held upright and the home button on the bottom.
UIInterfaceOrientationPortraitUpsideDown
The device is in portrait mode but upside down, with the device held upright and the home button at the top.
UIInterfaceOrientationLandscapeLeft
The device is in landscape mode, with the device held upright and the home button on the left side.
UIInterfaceOrientationLandscapeRight
The device is in landscape mode, with the device held upright and the home button on the right side.
In swift 5
The code below will lock the current view controller into portrait mode but still allow the other view controllers to transition to landscape. I do believe that you have to enable all the orientations at the project level and then turn then "off" using this method but am not sure if there is way to turn them back "on" one by one.
private var _orientations = UIInterfaceOrientationMask.portrait
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
get { return self._orientations }
set { self._orientations = .portrait }
}
A more thorough explanation of it all can be found here:
The supportedInterfaceOrientations method doesn't override any method from its superclass
For simplicity, for iPad, if Supported interface orientations (iPad) property in info.plist includes all the four orientations, with UIRequiresFullScreen property value as NO, iOS will treat your app as supporting split view. If an app supports split view feature, you can not disable it from rotating, at least by the ways above.
I have a detail answer here.
How to achieve the following functionalities in iphone app.
Always app launch portrait mode. if the simulator is landscape mode first launch in portrait mode then detect the device orientation change the app according to the current device orientation.
Either you can disable all orientations except portrait in your project and then set orientation programmatically throughout your app. Or you can stop orientation for specific view controller (may be in your case, viewcontroller during launching) by returning value NO. like this
- (BOOL)shouldAutorotate {
return NO;
}
and as mentioned by #Conner
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
In the project summary, "Supported Interface Orientations" are all selected, as there is a photo gallery view in my App, which can be rotated with device. The other views are portrait only. The target devices is iPhone, and all things perform well in the iPhone. But when it runs in my iPad with landscape mode, the splash and the rootView are as following:
splash-landscape:
rootview-landscape:
What I expected look should be the same as the iPad is with portrait mode:
splash-portrait:
rootview-portrait:
The rootView is MyNavigationController, some related code is as following:
MyNavigationController.m
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
- (BOOL)shouldAutorotate {
return NO;
}
Please, correct your code with the following:
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
It may seem odd returning YES from shouldAutorotate. The fact is, if you do return NO, then supportedInterfaceOrientations will not be called at all and your project settings will rule. You could as well remove shouldAutorotate and it should work just the same.
Reference:
When the user changes the device orientation, the system calls this method on the root view controller or the topmost presented view controller that fills the window. If the view controller supports the new orientation, the window and view controller are rotated to the new orientation. This method is only called if the view controller’s shouldAutorotate method returns YES.
Do you mean by showing a landscape launch screen and then in app still use portrait mode?
As far I know, iPhone-only app can't launch in landscape mode, which means giving a landscape launch screen to iPhone-only app is useless.
Check the document here at the "Providing Device-Specific Launch Images" section.
I guess what you want is make the status bar be portrait too. Unfortunately, there is no easy way to do this -- you can setup the device/interface orientation to protrait only, but it applies to the whole application. And you will need to process the orientation of all views by yourself. So, I will suggest you follow Hide status bar on launch image, hide your status bar, and use the same image in both orientations. It will make the splash screen look better.
My app only supports landscape orientations via the supportedInterfaceOrientation properties.
Using an iOS prior to iOS 6, my app can successfully load an instance of UIImagePickerController via presentViewController:animated:completion: even though the UIImagePickerController itself only supports portrait orientation.
The image picker simply presented itself sideways to the user. The user rotated the phone, picked their image, and then rotated back to landscape.
Under iOS 6.0, calling presentViewController:animated:completion: with the UIImagePickerController instance crashes the app. I can prevent the crash by adding portrait options to my supportedInterfaceOrientation properties.
However, operating in portrait really does not make sense for my app. I had thought I could use shouldAutorotateToInterfaceOrientation to allow the app to "support portrait" but only be allowed to rotate to portrait in this one view. But now that method is deprecated, and I can't use the same technique with shouldAutorotate.
Does anyone have any ideas how I can get around this issue under iOS 6.0?
iOS 6.1 - fixed
As of iOS 6.1, this no longer occurs, it is very important to follow my tips in order to avoid a crash under iOS 6.0.x, the below still applies to that.
iOS 6.0.x workaround
This is in actual fact a bug in iOS 6.0, this should be fixed in future iOS releases.
An engineer from Apple has explained this bug and a workaround here: https://devforums.apple.com/message/731764
This is happening because the Application wants landscape orientation only but some Cocoa Touch View Controllers require strictly Portrait orientation which is the error - not that they should be requiring more then Portrait but their interpretation of the Applications requirements.
An example of this can be the following:
iPad app supporting landscape only displays a UIImagePickerController
via a UIPopoverController. The UIImagePickerController requires
Portrait orientation, but the app is forcing landscape only. Error
and... crash
Other frameworks that have been reported as problematic include the Game Center login view controller.
The workaround is pretty simple but not ideal... You keep the correct orientations declared in your info.plist/project info pane, but in the Application Delegate class you declare that you allow all orientations.
Now each View Controller you add to the window must specify itself that it can only be Landscape. Please check the link for more details.
I cannot stress how much you should not be subclassing UIImagePickerController as the accepted solution is insisting you do.
The important thing here is "This class is intended to be used as-is and does not support subclassing."
In my case I added this to my application's delegate (I have a landscape only app), this tells the image picker it can display, because portrait is supported:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
return UIInterfaceOrientationMaskAll;
}
And then in my view controller which happened to be a UINavigationController, I included a category with the following:
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscape;
}
Now my app doesn't rotate, and the image picker asks the delegate if it can display as portrait and it gets told that's okay. So all plays out well.
I had a similar issue, but in an iPad landscape app. I was presenting the image picker in a popover. It crashed under iOS 6. The error suggested that the picker wanted portrait, but the app only offered landscape views, and ... importantly ... the picker's shouldRotate was returning YES.
I added this to my ViewControllerClass.m that is creating the picker
#interface NonRotatingUIImagePickerController : UIImagePickerController
#end
#implementation NonRotatingUIImagePickerController
- (BOOL)shouldAutorotate
{
return NO;
}
#end
and then used that class instead
UIImagePickerController *imagePicker = [[NonRotatingUIImagePickerController alloc] init];
[myPopoverController setContentViewController:imagePicker animated:YES];
That solved the problem for me. Your situation is a bit different, but it sounds like fundamentally the same error.
While subclassing UIImagePickerController works, a category is a better solution:
#implementation UIImagePickerController (NonRotating)
- (BOOL)shouldAutorotate
{
return NO;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
#end
Reporting from iOS 7.1:
In addition to what the above answers specify it seems that you have to absolutely enable portrait modes in the info.plist.
Without this none of the above code/fixes worked for me.
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
Will fix the issue but from iOs7