可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
When [camera takePicture]
is called before the camera is ready, it spits out this message:
UIImagePickerController: ignoring request to take picture; camera is not yet ready.
How can I know when it is ready to take a photo?
[camera isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]
always returns true, even when it's apparently not ready.
回答1:
As @djromero said there is a solution by using AVFoundation
(but not instead of UIImagePickerController
. You just use AVFoundation
to get a notification back).
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(cameraIsReady:)
name:AVCaptureSessionDidStartRunningNotification object:nil];
And then, once the camera is ready you got your notification:
- (void)cameraIsReady:(NSNotification *)notification
{
NSLog(@"Camera is ready...");
// Whatever
}
I have just tested it by calling takePicture
after UIImagePickerController
presentation (where I got the 'camera is not ready' message) and right inside my notification callback, where it worked like a charm.
Side-note:
[camera isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]
always returns Yes
because it only checks that there is a camera device available. As a matter of fact, Apple recommends that you always must check that this returns Yes
and that you have a non nil delegate (to provide a way to dismiss
the picker through the standard interface) before you try to initialize and present the controller.
回答2:
To be honest I haven't tried it and the documentation is somewhat ambiguous, but what about [UIImagePickerController isCameraDeviceAvailable:...]
?
EDIT: As I just learned, this is not the solution for your problem. Sorry, I thought it might be worth a try...
回答3:
What @Alladinian said was most helpful, this answer is supplemental to that. I recommend using his AVCaptureSessionDidStartRunningNotification technique as that tells you when the camera is ready initially (but this is called only once.) I am also concerned with if the device is ready for subsequent pictures as well. I haven't found the best solution, because I don't see any call backs for the device that don't refer to the camera's session. But this callback function seems to be good enough:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
Note the camera most likely will be ready before that callback is called, and you can cram in one or two photos, but it seems that the camera will definitely be ready by the time the callback is called. This should keep you from getting the following error between multiple camera shots.
UIImagePickerController: ignoring request to take picture; image is already being captured or camera not yet ready.
回答4:
As per the documentation for UIImagePickerController. The takePicture() method is ready again when
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
is called. If your interested in blocking pictures during this time period just disable the button interface (button.userInterfaceEnabled = false) until the call returns with media. I solved this very problem using the imagePickerController.
回答5:
Here is a Swift Version :
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.cameraIsReady), name: AVCaptureSessionDidStartRunningNotification, object: nil)
func cameraIsReady(notification :NSNotification ) {
print("Camera is ready...")
}
回答6:
If you are using UIImagePickerController, following is the code for video, similar code implies for image as well.
UIImagePickerController *picker;
BOOL cameraIsOn;
Then check for camera device available
if ([UIImagePickerController isCameraDeviceAvailable:[picker cameraDevice]]) {
if (cameraIsOn) {
NSLog(@"stop camera");
[picker stopVideoCapture];
cameraIsOn = FALSE;
}
else {
NSLog(@"start camera");
[picker startVideoCapture];
self.videoTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(changeValue) userInfo:nil repeats:YES];
cameraIsOn = TRUE;
}
}
回答7:
This makes sure to start capturing video as soon as camera is ready
imgpicker = [[UIImagePickerController alloc] init];
[self presentViewController:imgpicker animated:YES completion:^(void){
while(![imgpicker startVideoCapture]);
}];