我注意到在OS 3.1中,您可以使用
overlay
视图将覆盖层添加到图像选择器中。
cameraOverlayView
然而,我也注意到使用这种方法添加视图时,在整个UIImagePicker显示期间也会显示该视图,但我只想在预览阶段显示它。
有没有办法只在预览阶段发生这种情况? 我不希望在打开快门动画或询问是否要使用图像或重新拍摄的屏幕中出现它。我注意到在OS 3.1中,您可以使用
overlay
视图将覆盖层添加到图像选择器中。
cameraOverlayView
然而,我也注意到使用这种方法添加视图时,在整个UIImagePicker显示期间也会显示该视图,但我只想在预览阶段显示它。
有没有办法只在预览阶段发生这种情况? 我不希望在打开快门动画或询问是否要使用图像或重新拍摄的屏幕中出现它。我只是想展示一种无需操作子视图的可能性。 在CameraPicker中,存在用于通知系统更改的通知。它们也没有被记录下来(就像子视图结构一样)。因此,它们也可能会发生变化,但你可以接收到这些通知。
你可以使用无名称注册它们:
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(notificationReceived:) name: nil object: nil];
我们在这里获得一些有趣的(自我解释的)通知:
PLCameraControllerPreviewStartedNotification
PLCameraViewIrisAnimationWillBeginNotification
PLCameraViewIrisAnimationDidEndNotification
Recorder_DidStartPreviewing
Recorder_SourceStarted
Recorder_WillCapturePhoto
Recorder_DidCapturePhoto
Recorder_PhotoStillImageSampleBufferReady
Recorder_DidStopPreviewing
_UIImagePickerControllerUserDidCaptureItem // Photo was taken, preview is shown
_UIImagePickerControllerUserDidRejectItem // Repeat was pressed, camera is shown again
您可以使用它们来触发您的覆盖视图的隐藏状态或其他任何操作。我已经想出了一种方法让你实现所需的结果,虽然有点……不太标准。:)
这个想法是稍微重新排列 UIImagePickerController
使用的内部视图顺序。
好的,我们创建一个 UIImagePickerController
对象,初始化它并添加一个叠加视图。请注意!这个 UIView
对象(在示例代码中为 UIImageView
)从一开始就被隐藏了。千万别错过。最后,我们将图像选择器控制器呈现为模态视图控制器。这段代码应该放在你的 applicationDidFinishLaunching:
、viewWillAppear:
或类似的适当即将启动的方法中。
UIImagePickerController *anImagePickerController = [UIImagePickerController new];
anImagePickerController.delegate = self;
anImagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
UIImageView *anImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Watermark.png"]];
anImageView.frame = CGRectMake(0, 1, anImageView.image.size.width, anImageView.image.size.height);
anImageView.hidden = YES;
anImagePickerController.cameraOverlayView = anImageView;
[viewController presentModalViewController:anImagePickerController animated:NO];
[anImagePickerController release];
[NSTimer scheduledTimerWithTimeInterval:0.1
target:self
selector:@selector(timerFireMethod:)
userInfo:anImageView
repeats:YES];
[anImageView release];
在遮盖视图 (anImageView
) 被释放之前,创建了一个 NSTimer
,并用 anImageView
(NSTimer
的 userInfo
属性) 进行初始化,并立即安排定时器。下面是它调用的方法:
- (void)timerFireMethod:(NSTimer*)theTimer {
UIView *cameraOverlayView = (UIView *)theTimer.userInfo;
UIView *previewView = cameraOverlayView.superview.superview;
if (previewView != nil) {
[cameraOverlayView removeFromSuperview];
[previewView insertSubview:cameraOverlayView atIndex:1];
cameraOverlayView.hidden = NO;
[theTimer invalidate];
}
}
整个NSTimer
的过程被添加到流程中,以确保重新排序解决方法恰好在UIImagePickerController
完全准备好时发生。
就是这样。它很有效,虽然不是标准的,但简单粗暴。再次请随意优化并使其更加正确(哦,请务必这样做,我的目的是为了向您展示该方法)。
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
if (!viewController)
return;
UIView* controllerViewHolder = viewController.view;
UIView* controllerCameraView = [[controllerViewHolder subviews] objectAtIndex:0];
UIView* controllerPreview = [[controllerCameraView subviews] objectAtIndex:0];
[controllerCameraView insertSubview:self.overlayView aboveSubview:controllerPreview];
}
当您构建选择器时,请将覆盖层添加到选择器中(picker.cameraOverlayView = myView)。
覆盖层不会出现在拍摄的照片中。它只是一个覆盖视图,就像它所说的那样。
您可以在拍照之前(takePicture
方法)删除覆盖视图,并在imagePickerController:didFinishPickingMediaWithInfo:
中再次添加视图。