如何将自身作为不同UIImagePickerController的代理并区分来源
哈哈,这个问题我太有共鸣了!刚接触iOS的时候,也纠结过为啥不像Android那样有个现成的requestCode用来区分请求。不过别慌,咱们有好几种办法能实现类似的效果,给你详细说说:
方法1:给UIImagePickerController加自定义标识(关联对象)
这个方法的核心是给每个图片选择器对象绑定一个自定义的标识,就像Android的requestCode一样,回调时直接从picker对象上取出来判断,非常灵活安全。
首先定义一个关联用的唯一key:
static char kPickerRequestCodeKey;
然后在启动选择器的两个方法里,给picker设置不同的标识:
- (void)openAvatarPicker { UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; // 给这个picker绑定标识1,代表是头像选择器 objc_setAssociatedObject(picker, &kPickerRequestCodeKey, @(1), OBJC_ASSOCIATION_RETAIN_NONATOMIC); [self presentViewController:picker animated:YES completion:nil]; } - (void)openCoverPicker { UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; // 给这个picker绑定标识2,代表是封面选择器 objc_setAssociatedObject(picker, &kPickerRequestCodeKey, @(2), OBJC_ASSOCIATION_RETAIN_NONATOMIC); [self presentViewController:picker animated:YES completion:nil]; }
最后在代理回调里取出标识,区分处理:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info { NSNumber *requestCode = objc_getAssociatedObject(picker, &kPickerRequestCodeKey); if ([requestCode integerValue] == 1) { // 处理头像相关逻辑 UIImage *selectedAvatar = info[UIImagePickerControllerOriginalImage]; // ...你的操作 } else if ([requestCode integerValue] == 2) { // 处理封面相关逻辑 UIImage *selectedCover = info[UIImagePickerControllerOriginalImage]; // ...你的操作 } [picker dismissViewControllerAnimated:YES completion:nil]; }
方法2:用控制器属性记录当前选择器类型
如果你的场景里不会同时弹出多个图片选择器(大部分情况都是这样),那用一个属性记录当前启动的是哪个选择器会更简单。
先定义一个枚举来区分类型:
typedef NS_ENUM(NSInteger, PickerType) { PickerTypeAvatar, PickerTypeCover }; @interface YourViewController () @property (nonatomic, assign) PickerType currentPickerType; @end
启动选择器时设置对应的类型:
- (void)openAvatarPicker { UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; self.currentPickerType = PickerTypeAvatar; [self presentViewController:picker animated:YES completion:nil]; } - (void)openCoverPicker { UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.delegate = self; self.currentPickerType = PickerTypeCover; [self presentViewController:picker animated:YES completion:nil]; }
回调时根据属性判断:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info { if (self.currentPickerType == PickerTypeAvatar) { // 处理头像逻辑 } else if (self.currentPickerType == PickerTypeCover) { // 处理封面逻辑 } [picker dismissViewControllerAnimated:YES completion:nil]; }
小总结
如果你的项目有复杂场景(比如可能同时弹出多个选择器),优先用关联对象的方法,每个picker自己带标识,不会互相干扰;如果只是普通的单一场景,用控制器属性记录的方式更省事,代码也更简洁。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

