在做游戏开发时有这样的一个需求,玩家可以使用相机或者从相册中选择图片做头像。由于游戏是横屏,导致ios调出相机或相册时出现闪退现象。观察了下log,log如下:
invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
libc++abi.dylib: terminate_handler unexpectedly threw an exception
然后看到这样的log自己就开始百度了,找了半天还是一头雾水。后来发现有大神说,把友盟的调试打开,就能看到真实的log了。想了下自己项目里面刚好添加了友盟sdk,并且没有把友盟的log打印打开。于是加上了友盟的那句打印log的代码,结果还是一样(有人说可以看到真实log,然我却没那么幸运)。后来一想友盟官网有报错log,于是打开一看,果然错误的log清一色的是:
Supported orientations has no common orientation with the application, and [CAMViewfinderViewController shouldAutorotate] is returning YES
真相大白,看到这条log,问题就清楚了,游戏是横屏的,就没有设置适应竖屏的功能。然后调用相机或相册,而相机和相册都是竖屏的。这样就导致了闪退。然后网上查找了一番,比较好的方法我整理了一下。
解决方案:游戏启动时默认设置横屏,当调用相机或相册时设置成横竖屏都适应。用完相机或相册后,再设置成横屏。
解决方法如下:
一、 AppDelegate.h 中添加变量声明
@property (nonatomic,assign) NSInteger MyInterfaceOrientationMask; // 横竖屏设置
二、 AppDelegate.mm 中添加如下代码 (初始为只支持横屏)
1、在 didFinishLaunchingWithOptions 方法中添加代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
_MyInterfaceOrientationMask = UIInterfaceOrientationMaskLandscape; // 设置初始屏幕方向
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(changeRotate:) name:@"changeRotate" object:nil];// 添加修改横竖屏事件监听
return YES;
}
2、添加下面两个方法
/**
横竖屏设置
@param noti 0: 设置为横屏
*/
- (void)changeRotate:(NSNotification *)noti
{
if ([noti.object isEqualToString:@"0"])
{
// 横屏设置
_MyInterfaceOrientationMask = UIInterfaceOrientationMaskLandscape;
}
else
{
_MyInterfaceOrientationMask = UIInterfaceOrientationMaskAll;
}
}
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return _MyInterfaceOrientationMask;
}
三、此时就是在调用相机或相册以及取消的地方添加 (此时设置为支持横竖屏)
[[NSNotificationCenter defaultCenter] postNotificationName:@"changeRotate" object:@"1"];// 横竖屏切换通知
示例代码如下:
// 打开相机
[[NSNotificationCenter defaultCenter] postNotificationName:@"changeRotate" object:@"1"];// 横竖屏切换通知
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
//设置拍照后的图像可编辑
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
[picker release];
// 打开相册
[[NSNotificationCenter defaultCenter] postNotificationName:@"changeRotate" object:@"1"];// 横竖屏切换通知
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.allowsEditing = YES;
//[self presentModalViewController:picker animated:YES];
[self presentViewController:picker animated:YES completion:^(void){
// NSLog(@"Imageviewcontroller is presented");
}];
[picker release];
四、在拍照或相册选择完成或取消(如果启用图片裁剪就在裁剪完成)的地方添加如下代码(完成(取消)拍照或相册操作后再设置只支持横屏)
[[NSNotificationCenter defaultCenter] postNotificationName:@"changeRotate" object:@"0"];// 横竖屏切换通知
示例如下:
NSLog(@"您取消了选择图片");
[[NSNotificationCenter defaultCenter] postNotificationName:@"changeRotate" object:@"0"];// 横竖屏切换通知
[picker dismissModalViewControllerAnimated:YES];
以上整理来至:https://www.jianshu.com/p/5d95731c8919 和 http://www.cnblogs.com/ZhangShengjie/p/6248772.html 两篇文章