iOS,UIImagePickerController,有没有办法在不实现自定义控件的情况下检测用户何时点击拍照按钮?
iOS, UIImagePickerController, is there a way to detect when user taps the take picture button without implementing custom controls?
Xcode7.3,iOS9.3.1
我想在用户即将拍照时和编辑照片后使用两个自定义叠加视图。要更改叠加层,我想知道 UIImagePickerControllerDelegate
是否有回调方法可以让我知道用户何时开始编辑图片,或者用户何时点击拍照按钮。
我知道的唯一方法是:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
我看过这里:UIImagePickerController with cameraOverlayView focusses when button in overlay is tapped, How to know I tap "taking photo button" with UIImagePicker and iOS - Taking A Picture After Button Tap in UIImagePickerController CustomOverlayView。
或者也许有一种方法可以通过添加观察者从标准按钮获取点击事件。
请帮忙!提前致谢。
您可以使用 UINavigationControllerDelegate
,您在使用 UIImagePickerController
时也必须实施。像这样实现委托方法 [...]didShowViewController[...]
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
NSLog(@"%@", [viewController class]);
}
产生以下输出(使用模拟器,选择 UIImagePickerControllerSourceTypePhotoLibrary
作为 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
希望对您有所帮助!
Xcode 8.2.1, iOS10.2.1
实施前请阅读早期版本的解决方案以了解基础知识。谢谢!问题是各种子视图的某些名称已从 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;
}
}
Xcode7.3,iOS9.3.1
我必须让它工作,所以我花了很多时间来解决这个问题。
要点是,我在 UIImagePickerController
出现后向下钻取视图层次结构,寻找 CMKShutterButton
和标题为 "Retake" 的重拍按钮,然后我将选择器附加到按钮的操作,就像这样...
[shutterButton addTarget:self action:@selector(touchUpInsideCMKShutterButton) forControlEvents:UIControlEventTouchUpInside];
[retakeButton addTarget:self action:@selector(touchUpInsideButtonRetake) forControlEvents:UIControlEventTouchUpInside];
将下面的代码放入图像选择器出现后调用的完成块中:
[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;
}
}
这里是我附加的方法,它在呈现图像选择器控制器的视图控制器中:
- (void)touchUpInsideCMKShutterButton
{
NSLog(@"Take");
}
- (void)touchUpInsideButtonRetake
{
NSLog(@"Re-take");
}
希望这对某人有所帮助!谢谢。
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
}];
Xcode7.3,iOS9.3.1
我想在用户即将拍照时和编辑照片后使用两个自定义叠加视图。要更改叠加层,我想知道 UIImagePickerControllerDelegate
是否有回调方法可以让我知道用户何时开始编辑图片,或者用户何时点击拍照按钮。
我知道的唯一方法是:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
我看过这里:UIImagePickerController with cameraOverlayView focusses when button in overlay is tapped, How to know I tap "taking photo button" with UIImagePicker and iOS - Taking A Picture After Button Tap in UIImagePickerController CustomOverlayView。
或者也许有一种方法可以通过添加观察者从标准按钮获取点击事件。
请帮忙!提前致谢。
您可以使用 UINavigationControllerDelegate
,您在使用 UIImagePickerController
时也必须实施。像这样实现委托方法 [...]didShowViewController[...]
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
NSLog(@"%@", [viewController class]);
}
产生以下输出(使用模拟器,选择 UIImagePickerControllerSourceTypePhotoLibrary
作为 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
希望对您有所帮助!
Xcode 8.2.1, iOS10.2.1
实施前请阅读早期版本的解决方案以了解基础知识。谢谢!问题是各种子视图的某些名称已从 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;
}
}
Xcode7.3,iOS9.3.1
我必须让它工作,所以我花了很多时间来解决这个问题。
要点是,我在 UIImagePickerController
出现后向下钻取视图层次结构,寻找 CMKShutterButton
和标题为 "Retake" 的重拍按钮,然后我将选择器附加到按钮的操作,就像这样...
[shutterButton addTarget:self action:@selector(touchUpInsideCMKShutterButton) forControlEvents:UIControlEventTouchUpInside];
[retakeButton addTarget:self action:@selector(touchUpInsideButtonRetake) forControlEvents:UIControlEventTouchUpInside];
将下面的代码放入图像选择器出现后调用的完成块中:
[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;
}
}
这里是我附加的方法,它在呈现图像选择器控制器的视图控制器中:
- (void)touchUpInsideCMKShutterButton
{
NSLog(@"Take");
}
- (void)touchUpInsideButtonRetake
{
NSLog(@"Re-take");
}
希望这对某人有所帮助!谢谢。
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
}];