可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I believe this is a common issue and many answers don't work anymore, many just partial, if you are under iOS7 and your iPad app is Landscape only, but you want to use the UIImagePickerController
with source UIImagePickerControllerSourceTypePhotoLibrary
or UIImagePickerControllerSourceTypeCamera
.
How to set it right, so it's working 100%? And you don't get mixed orientations and avoid the error "Supported orientations has no common orientation with the application, and shouldAutorotate
returns YES
".
回答1:
If your iPad app is landscape only in all conditions, just do these 3 steps :
1) In your app delegate
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskAll;
}
2) Create a category header
#import "UIViewController+OrientationFix.h"
@implementation UIViewController (OrientationFix)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
@end
3) Create a category implementation
#import "UIImagePickerController+OrientationFix.h"
@implementation UIImagePickerController (OrientationFix)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsLandscape(toInterfaceOrientation);
}
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
@end
Note: You don't need to import these categories anywhere, just enough they are compiled with the project
Note: no need to implement these methods in any VC
Note: no need to change your plist supported orientations
This is tested and working under any conditions
回答2:
I have seen this code from Apple's Sample Code.
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
Due to this UIModalPresentationCurrentContext UIImagePickerController
will be opened as per device's current orientation.
回答3:
Apple's documentation says:
"Important: The UIImagePickerController class supports portrait mode only."
Although, it works fine in landscape for full screen and on iOS 6.
UIImagePickerController class reference
回答4:
Thanks to Peter Lapisu suggestion above. It doesn't work for me (maybe i'm on iOS 8.3) but i was able to modified it to fixed my orientation issues. My codes are below
In app delegate
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskAll;
}
UIImagePickerController category
@implement UIImagePickerController (extensions)
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [[UIApplication sharedApplication] statusBarOrientation];
}
@end
UIViewController category
@implementation UIViewController (extensions)
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
@end
回答5:
Although most answers recommend using .currentContext
, I have found out after dismissing the imagepicker, everything was wrong.
On an Landscaped iPad, imho it's best if you would use .formSheet
:
let picker = UIImagePickerController()
picker.modalPresentationStyle = .formSheet
picker.sourceType = .photoLibrary
picker.delegate = self
self.present(picker, animated: true)
回答6:
Swift 4
solution
Make sure that when you are having the ViewController embedded in a NavigationViewController to have the fix there. It won't work adding this restriction to the ViewController then...
import UIKit
class MainNavigationViewController: UINavigationController {
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscape
}
}
And of course the code mentioned above for the AppDelegate:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return .all
}
Btw this is only necessary for iOS 10 and below. Apple seems to have fixed it from iOS 11 and above...