iOS,UIImagePickerController有没有一种方法来检测用户点击拍照button,而不实现自定义控件?

Xcode 7.3,iOS 9.3.1

我想为用户即将拍摄照片和编辑照片之后使用两个自定义叠加视图。 要改变覆盖,我想知道是否有一个从UIImagePickerControllerDelegate的callback方法,让我知道当用户开始编辑图片,或者当用户点击拍照button。

我所知道的唯一方法是:

 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker 

我已经看了这里: UIImagePickerController与cameraOverlayView的重点,当button叠加被点击 , 如何知道我点击“拍照button”与UIImagePicker和iOS – 拍照后button在UIImagePickerController CustomOverlayView点击 。

或者也许有一种方法可以通过添加观察者来从标准button中获取点击事件。

请帮忙! 提前致谢。

您可以使用在使用UIImagePickerController时也必须实现的UINavigationControllerDelegate 。 像这样实现委托方法[...]didShowViewController[...]

 - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated { NSLog(@"%@", [viewController class]); } 

产生以下输出(使用模拟器,selectUIImagePickerControllerSourceTypePhotoLibrary作为sourceType并像这样浏览:相册概述>特定相册>编辑特定照片):

2016-04-08 00:19:36.882 ImagePicker [44578:4705834] PUUIAlbumListViewController
2016-04-08 00:19:41.341 ImagePicker [44578:4705834] PUUIMomentsGridViewController
2016-04-08 00:19:47.929 ImagePicker [44578:4705834] PUUIImageViewController

希望有所帮助!

UIImagePickerControllerDelegate是相当差,但你可以通过添加一个观察者来处理它:

Swift 3:

 NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "_UIImagePickerControllerUserDidCaptureItem"), object:nil, queue:nil, using: { note in //Do something }) 

Objective-C的:

 [[NSNotificationCenter defaultCenter] addObserverForName:@"_UIImagePickerControllerUserDidCaptureItem" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { //Do something }]; 

Xcode 8.2.1,iOS10.2.1

在实施之前,请阅读早期版本的解决scheme以了解基础知识。 谢谢! 问题是,各种子视图的一些名称已经从iOS 9.3.1更改为iOS 10.2.1。

这里是完整的代码(见下面插入位置),代替“//代码在这里”:

 for (UIView *subviewImagePickerControllerView in self.imagePickerController.view.subviews) { if ([subviewImagePickerControllerView.class.description isEqualToString:@"UINavigationTransitionView"]) { for (UIView *subviewUINavigationTransitionView in subviewImagePickerControllerView.subviews) { if ([subviewUINavigationTransitionView.class.description isEqualToString:@"UIViewControllerWrapperView"]) { for (UIView *subviewUIViewControllerWrapperView in subviewUINavigationTransitionView.subviews) { if ([subviewUIViewControllerWrapperView.class.description isEqualToString:@"CAMCameraViewControllerContainerView"]) { for (UIView *subviewCAMCameraViewControllerContainerView in subviewUIViewControllerWrapperView.subviews) { if ([subviewCAMCameraViewControllerContainerView.class.description isEqualToString:@"CAMViewfinderView"]) { for (UIView *subviewCAMViewfinderView in subviewCAMCameraViewControllerContainerView.subviews) { if ([subviewCAMViewfinderView.class.description isEqualToString:@"CAMBottomBar"]) { for (UIView *subviewCAMBottomBar in subviewCAMViewfinderView.subviews) { if ([subviewCAMBottomBar.class.description isEqualToString:@"CUShutterButton"] && [subviewCAMBottomBar.class isSubclassOfClass:[UIButton class]]) { UIButton *shutterButton = (UIButton *)subviewCAMBottomBar; [shutterButton addTarget:self action:@selector(touchUpInsideCMKShutterButton) forControlEvents:UIControlEventTouchUpInside]; } else { nil; } } } } } else if ([subviewCAMCameraViewControllerContainerView.class.description isEqualToString:@"PLCropOverlay"]) { for (UIView *subviewPLCropOverlay in subviewCAMCameraViewControllerContainerView.subviews) { if ([subviewPLCropOverlay.class.description isEqualToString:@"PLCropOverlayBottomBar"]) { for (UIView *subviewPLCropOverlayBottomBar in subviewPLCropOverlay.subviews) { if ([subviewPLCropOverlayBottomBar.class.description isEqualToString:@"PLCropOverlayPreviewBottomBar"]) { for (UIView *itemPLCropOverlayPreviewBottomBar in subviewPLCropOverlayBottomBar.subviews) { if ([itemPLCropOverlayPreviewBottomBar.class isSubclassOfClass:[UIButton class]]) { UIButton *buttonPLCropOverlay = (UIButton *)itemPLCropOverlayPreviewBottomBar; if ([buttonPLCropOverlay.titleLabel.text isEqualToString:@"Retake"]) { UIButton *retakeButton = buttonPLCropOverlay; [retakeButton addTarget:self action:@selector(touchUpInsideButtonRetake) forControlEvents:UIControlEventTouchUpInside]; } else { nil; } } else { nil; } } } else { nil; } } } else { nil; } } } else { nil; } } } else { nil; } } } else { nil; } } } else { nil; } } 

Xcode 7.3,iOS9.3.1

我必须得到这个工作,所以我花了很多时间搞清楚这一点。

其要点在于,在UIImagePickerController出现之后,向下钻取视图层次结构,查找CMKShutterButton和带有“Retake”标题的重拍button,然后将select器附加到button的动作,就像这样…

 [shutterButton addTarget:self action:@selector(touchUpInsideCMKShutterButton) forControlEvents:UIControlEventTouchUpInside]; [retakeButton addTarget:self action:@selector(touchUpInsideButtonRetake) forControlEvents:UIControlEventTouchUpInside]; 

将下面的代码放到您的图像select器出现后调用的完成块中:

 [self presentViewController:self.imagePickerController animated:true completion:^(void){ //Code goes here } 

这里是完整的代码,代替了上面的代码:

 for (UIView *subviewImagePickerControllerView in self.imagePickerController.view.subviews) { if ([subviewImagePickerControllerView.class.description isEqualToString:@"UINavigationTransitionView"]) { for (UIView *subviewUINavigationTransitionView in subviewImagePickerControllerView.subviews) { if ([subviewUINavigationTransitionView.class.description isEqualToString:@"UIViewControllerWrapperView"]) { for (UIView *subviewUIViewControllerWrapperView in subviewUINavigationTransitionView.subviews) { if ([subviewUIViewControllerWrapperView.class.description isEqualToString:@"PLImagePickerCameraView"]) { for (UIView *subviewPLImagePickerCameraView in subviewUIViewControllerWrapperView.subviews) { if ([subviewPLImagePickerCameraView.class.description isEqualToString:@"CMKBottomBar"]) { for (UIView *itemCMKBottomBar in subviewPLImagePickerCameraView.subviews) { if ([itemCMKBottomBar.class.description isEqualToString:@"CMKShutterButton"] && [itemCMKBottomBar.class isSubclassOfClass:[UIButton class]]) { UIButton *shutterButton = (UIButton *)itemCMKBottomBar; [shutterButton addTarget:self action:@selector(touchUpInsideCMKShutterButton) forControlEvents:UIControlEventTouchUpInside]; } else { nil; } } } else if ([subviewPLImagePickerCameraView.class.description isEqualToString:@"PLCropOverlay"]) { for (UIView *subviewPLCropOverlay in subviewPLImagePickerCameraView.subviews) { if ([subviewPLCropOverlay.class.description isEqualToString:@"PLCropOverlayBottomBar"]) { for (UIView *subviewPLCropOverlayBottomBar in subviewPLCropOverlay.subviews) { if ([subviewPLCropOverlayBottomBar.class.description isEqualToString:@"PLCropOverlayPreviewBottomBar"]) { for (UIView *itemPLCropOverlayPreviewBottomBar in subviewPLCropOverlayBottomBar.subviews) { if ([itemPLCropOverlayPreviewBottomBar.class isSubclassOfClass:[UIButton class]]) { UIButton *buttonPLCropOverlay = (UIButton *)itemPLCropOverlayPreviewBottomBar; if ([buttonPLCropOverlay.titleLabel.text isEqualToString:@"Retake"]) { UIButton *retakeButton = buttonPLCropOverlay; [retakeButton addTarget:self action:@selector(touchUpInsideButtonRetake) forControlEvents:UIControlEventTouchUpInside]; } else { nil; } } else { nil; } } } else { nil; } } } else { nil; } } } else { nil; } } } else { nil; } } } else { nil; } } } else { nil; } } 

这里是我附加的方法,它在呈现图像select器控制器的视图控制器中进行:

 - (void)touchUpInsideCMKShutterButton { NSLog(@"Take"); } - (void)touchUpInsideButtonRetake { NSLog(@"Re-take"); } 

希望这可以帮助别人! 谢谢。