您的位置:首页 > 产品设计 > UI/UE

UIPopoverController和UIActionSheet在iPad中使用

2015-07-19 09:20 453 查看

UIPopoverController和UIActionSheet在iPad中使用

这两天在做iPad版的应用,其中使用到了UIPopoverControllerUIActionSheet做相片获取,其中遇到了一些问题,总结如下:

UIActionSheet

当用户点击弹出UIActionSheet,选择相机或相册按钮时启动UIImagePickerController

代码如下:

- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex==actionSheet.cancelButtonIndex) return;
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
if (buttonIndex == 0) {
//拍照
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.allowsEditing = YES;
[self presentViewController:imagePicker animated:YES completion:nil];
}
}
else if (buttonIndex == 1) {
//相册
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePicker animated:YES completion:nil];
}
}
}


当iOS7下执行相册,程序正常调取相册。当iOS8执行相册,则提示如下警告

2015-07-10 17:03:14.771 iPadTest[3353:95820] Warning: Attempt to present <UIImagePickerController: 0x7b3e3400> on <MasterViewController: 0x79a7cd00> which is already presenting (null)


相册无法正常启动。

同理在如下代码:

- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex==actionSheet.cancelButtonIndex) return;
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
if (buttonIndex == 0) {
//拍照
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.allowsEditing = YES;
[self presentViewController:imagePicker animated:YES completion:nil];
}
}
else if (buttonIndex == 1) {
//相册
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
pc = [[UIPopoverController alloc]initWithContentViewController:imagePicker];
pc.popoverContentSize = CGSizeMake(100, 200);
[pc presentPopoverFromRect:CGRectMake(self.view.bounds.size.width-10, -10, 10, 10) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:NO];
}
}
}


在iOS7下执行相册,程序正常调取相册。当iOS8执行相册,则提示如下警告

2015-07-10 17:18:30.296 iPadTest[3611:102813] Warning: Attempt to present <UIImagePickerController: 0x7cac0a00>  on <MasterViewController: 0x7be73f30> which is already presenting (null)


两种不同的相册打开方式,在iOS7和iOS8是相同的结果。

为什么呢?

如果把启动的方法替换如下:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self presentViewController:imagePicker animated:YES completion:nil];
}];




[[NSOperationQueue mainQueue] addOperationWithBlock:^{
pc = [[UIPopoverController alloc]initWithContentViewController:imagePicker];
pc.popoverContentSize = CGSizeMake(100, 200);
[pc presentPopoverFromRect:CGRectMake(self.view.bounds.size.width-10, -10, 10, 10) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:NO];
}];


相册可以正常打开,同理,相机和相册的打开、关闭在iOS8下都需要通过

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
}]




dispatch_async(dispatch_get_main_queue(), ^{

});


这样就避免了无法启动或无法关闭的异常问题。



问题解决了,但原因是为什么呢?



经过测试、数据抓取

iOS7下UIActionSheet 调取- (void)showInView:(UIView *)view方法打印信息如下:

<UIActionSheet: 0x7a6524d0; frame = (0 0; 272 136.5); opaque = NO; layer = <CALayer: 0x7a940050>>


iOS8下UIActionSheet 调取- (void)showInView:(UIView *)view方法打印信息如下:

<UIActionSheet: 0x7a7859b0; frame = (0 0; 0 0); layer = <CALayer: 0x7a728bd0>>


官方文档介绍:

Important:  UIActionSheet is deprecated in iOS 8. (Note that UIActionSheetDelegate is also deprecated.) To create and manage action sheets in iOS 8 and later, instead use UIAlertController with a preferredStyle of UIAlertControllerStyleActionSheet.


意思是UIActionSheet在iOS8后废弃(过时),包括UIActionSheetDelegate。使用UIAlertController配合preferredStyle样式来实现想要的效果。

结论:

UIActionSheet在iOS7可用,iOS8下使用需要添加到主线程,才能响应,但建议使用UIAlertController实现自己的样式和功能。

该例子的demo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ipad 应用