封装后的UIImagePickerConroller在某些情况下没有回调到代理方法中,最近遇到了这个问题,在网上找了一些都没有解决方案。这里我说说我遇到的情况。
先说结论,没有回调代理方法,那就是delegate出了问题。
遇到的情况:
没有直接使用UIImagePickerController,而是封装了一层
封装:
PLCameraAndPhotoPicker.h
@protocol PLCameraAndPhotoPickerDelegate;
@interface PLCameraAndPhotoPicker : NSObject<UINavigationControllerDelegate,UIImagePickerControllerDelegate>
@property (nonatomic, weak) id<PLCameraAndPhotoPickerDelegate> delegate;
-(void)showCamera;
-(void)showPhotoLibrary;
-(void)showVideoRecord;
@end
@protocol PLCameraAndPhotoPickerDelegate <NSObject>
- (void)getCameraAndPhoto:(id)imageResource;
@end
PLCameraAndPhotoPicker.m
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
NSString* type = [info objectForKey:UIImagePickerControllerMediaType];
if ([type isEqualToString:(NSString*)kUTTypeImage]) {
UIImage* edit = [info objectForKey:UIImagePickerControllerEditedImage];
// 获取图片
if (_delegate && [_delegate respondsToSelector:@selector(getCameraAndPhoto:)]) {
[_delegate getCameraAndPhoto:edit];
}
//如果是拍照的照片,则需要手动保存到本地,系统不会自动保存拍照成功后的照片
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum(edit, self, nil, nil);
}
}
[picker dismissViewControllerAnimated:YES completion:^{}];
if (@available(iOS 11, *)) {
[UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
}
调用:
ViewController.m
-(void)getPhoto:(UIButton*)sender {
PLCameraAndPhotoPicker *picker = [[PLCameraAndPhotoPicker alloc] init];
picker.delegate = self;
[picker showCamera];
}
- (void)getCameraAndPhoto:(id)imageResource{
NSLog(@"获取资源");
}
结果:无论是选择照片还是点击取消,都会缩回picker,但是并没有走代理方法。
![](https://img.haomeiwen.com/i26527354/2c89c3e93d5d69f4.png)
疑惑点:
1.检查确实是已经设置了picker的delegate。
2.picker点击选择照片、点击取消确实dimiss掉了
那为什么就是不走代理方法呢?
其实我是犯了一个低级错误,还有UIImagePickController的事件处理误导了我。
我们再看回调用封装类的地方:
-(void)getPhoto:(UIButton*)sender {
PLCameraAndPhotoPicker *picker = [[PLCameraAndPhotoPicker alloc] init];
picker.delegate = self;
[picker showCamera];
}// 到这里,其实picker已经被释放掉了
因为执行完这个方法,picker就被系统释放了,所以UIImagePickerController的delegate自然就是nil了。
那为什么UIImagePickerController选择了照片或点击取消之后能正常运行呢?
我猜测是如果delegate为nil或者没有实现相应的代理方法,UIImagePickerController就会自己dismiss掉。
经过测试确实如此。
调用方式修改一下:
ViewController.m
@interface ViewController ()
@property(nonatomic, strong) PLCameraAndPhotoPicker *picker;
@end
@implementation ViewController
-(void)getPhoto:(UIButton*)sender {
PLCameraAndPhotoPicker *picker = [[PLCameraAndPhotoPicker alloc] init];
picker.delegate = self;
[picker showCamera];
_picker = picker;
}
@end
网友评论