I am creating a landscape only application using sdk 3.0 that uses mapkit. I need to use iphone camera in my application. But I am getting following warning when I try to open camera.
"Can't perform full-screen transition. The fromViewController's view must be within a view that occupies the full screen."
The view from which I am calling camera method is mapview with size of 480*320. I have written following code to call camera:
UIImagePickerController *picker = [[UIImagePickerController alloc]init];
picker.delegate = self;
picker.sourceType=UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController: picker animated:YES];
[picker release];
After that I have written the usual method :
-(void)imagePickerController : (UIImagePickerController *)picker didFinishPickingImage : (UIImage *)image editingInfo : (NSDictionary *)editingInfo
But this is never called , since camera is never opened. So my question is what am I missing here...? I am testing this app on actual iphone device , not on simulator. I have used this code in another app and it works fine. But here, it simply doesnt work! Plz help if you have any idea about this..
it sounds like the warning is telling you the problem: the parent view you're passing in to presentModalViewController needs to be a full-screen view. So instead of using "self" in this code you need to use something else, like the parent view controller.
now, you're going to have another problem, because the camera controller doesn't like landscape mode, so you may have to switch back to portrait mode before showing it....
just replace "self" with the parent ViewController which is probably declared in you appDelegate.
Related
When we use UIImagePickerController to get camera action we need to open it in different viewController like as:
UIImagePickerController *imagepicker;
[self presentModalViewController:imagepicker animated:YES];
but I want to use this in same View controller from where this UIImagePickerController is called in different View.
Is it possible?
Try creating a view where you want the image picker to appear say destView.
Create the image picker and then use [destView addSubview: imagepicker.view]
You may need to play with size of destView to get things right.
I have made a UIImagePickerController with a custom overlay view in order to enhance the interface and it's working great the first time I load it, it's perfect.
The problem is that if I dismiss it and then shows it again I have a strange bug. the camera view and the overlay appear behind the NavBar and the TabBar of the previous view controller.
I have try different ways of implementing this but I can't get this bug solved.
Here is how I call my UIImagePickerController. It's inspired by this sample code.
[self.cameraOverlayViewController setupImagePicker:UIImagePickerControllerSourceTypeCamera];
[self presentModalViewController:self.cameraOverlayViewController.imagePickerController animated:YES];
Once my picture taken, I dismiss the UIImagePickerController:
[self dismissModalViewControllerAnimated:YES];
Definitly nothing special in the way of implementing it.
And here 2 screenshots:
And now taken at second launch:
At second launch http://puic.dev.madebykawet.com/IMG_0929.PNG
Thanks for your answers !
have you tried something like that?
//hide all controls
picker.showsCameraControls = NO;
picker.navigationBarHidden = YES;
picker.toolbarHidden = YES;
Thanks for your help Peko but it was not that.
After hours trying stuff, I found out that I needed to launch the UIImagePickerController from the root controller.
This is maybe because I'm using TTNavigator from the Three20 library.
So in my case to have this working:
[[TTNavigator navigator].rootViewController presentModalViewController:self.cameraOverlayViewController.imagePickerController animated:YES];
instead of:
[self presentModalViewController:self.cameraOverlayViewController.imagePickerController animated:YES];
same thing for dismissModalViewControllerAnimated:
[[TTNavigator navigator].rootViewController dismissModalViewControllerAnimated:YES];
Is it a known issue that if you try to test your UIImagePickerController using the Camera as a source type then the simulator will crash?
I have the following code:
self.imgPicker = [[UIImagePickerController alloc] init];
self.imgPicker.allowsEditing = NO;
self.imgPicker.delegate = self;
[self.imgPicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[self presentModalViewController:self.imgPicker animated:YES];
[imgPicker release];
Running this in simulator, I get an objc-exception-throw error on the stack # -[UIImagePickerController setSourceType:].
Now if I set the source type to the Photo Library though, everything runs smoothly and fine? What's the deal?
Simulator doesn't have the camera and can't simulate to take a picture (it would have been nice to use the isight but Apple has not been so kindly). However Your code is not safe because, for example, old ipod touch doesn't have a camera and in this case your app will crash on this device.
As Apple suggest in UIImagePickerController documentation:
To use an image picker controller
containing its default controls,
perform these steps:
1.Verify that the device is capable of picking content from the
desired source. Do this calling the
isSourceTypeAvailable: class method,
providing a constant from the
“UIImagePickerControllerSourceType”
enum.
2.Check which media types are available, for the source type you’re
using, by calling the
availableMediaTypesForSourceType:
class method. This lets you
distinguish between a camera that can
be used for video recording and one
that can be used only for still
images.
3.Tell the image picker controller to adjust the UI according to the
media types you want to make
available—still images, movies, or
both—by setting the mediaTypes
property.
4.Present the user interface by calling the
presentModalViewController:animated:
method of the currently active view
controller, passing your configured
image picker controller as the new
view controller.
5.When the user taps a button to pick a newly-captured or saved image
or movie, or cancels the operation,
dismiss the image picker using your
delegate object. For newly-captured
media, your delegate can then save it
to the Camera Roll on the device. For
previously-saved media, your delegate
can then use the image data according
to the purpose of your app.
So you have to call isSourceTypeAvailable and set your sourceType consistently.
I have an opengl game for iPhone/iPad (universal). I added the ability to send an SMS message using MFMessageComposeViewController. Testing in a real iPhone. The SMS composer sheet animates up over my view, I can send the message or not, didFinishWithResult gets called, and when I [self dismissModalViewControllerAnimated:YES] it goes away and my glview is asked to layoutSubviews. At that point the backing width and height are now zero, and my frame buffer status check fails. The self.layer.frame.size.width is still 320x460.
- (void)layoutSubviews
{
NSLog(#"layoutSubviews");
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
[self drawView];
}
I do have a UIViewController for my glView which is where I handle orientation changes for the iPad and where I also put the MFMessage stuff. (Technically I guess since it's universal there are two different viewControllers, two app Delegates and two nibs - but I'm working in the iPhone set here because the iPad doesn't sms). On the iPad layoutSubviews gets called when the orientation changes, we destroy and re-create the framebuffers at the new size and everything is fine. But here when coming back from sending the SMS it fails on the re-creating. I can post the code if necessary but its the standard creating framebuffer code.
Another important point is that I'm using a notification to tell the method inside of the viewcontroller to start the sms stuff. I tried just having those methods in my glview and making it the MFMessageComposeViewControllerDelegate but then I was getting errors because glview is a UIView and not a UIViewController.
Any ideas?
Not sure if it's a bug or what the deal is but I had to create another view, make self.view = anotherView, retain my glview and removeFromSuperview before presenting the modal. And then wait to bring my glview back until everything was animated back into place.
If anyone wants more info please let me know.
Edit with actual answer:
It is a bug and as I suspected it has to do with the status bar. My app has no status bar. But when I
[self presentModalViewController:controller animated:YES];
the SMS message composer view does show the iphone status bar. When it is dismissed and my app showed through underneath my framebuffer was getting borked. I had figured out a weird work around of switching views to protect my glview framebuffer - but then figured out to add a statusBarHidden before the dismiss and all is well now. Here's the dismiss code:
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result {
// Notifies users about errors associated with the interface
switch (result)
{ ... }
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
[self dismissModalViewControllerAnimated:YES];
}
I'm trying to use the UIImagePickerController interface from OS 3.1, with the cameraOverlayView and takePicture, but I've clearly failed to understand how this works, and so I'm not getting the behaviour I want.
What I want to do is open the camera and take a picture automatically without having to having the user interact with the picker or edit the image. So I subclass UIImagePickerController (similar to the example in http://github.com/pmark/Helpful-iPhone-Utilities/tree/master/BTL%20Utilities/) and turn off all of the controls:
- (void)displayModalWithController:(UIViewController*)controller animated:(BOOL)animated {
self.sourceType = UIImagePickerControllerSourceTypeCamera;
self.showsCameraControls = NO;
self.navigationBarHidden = YES;
self.toolbarHidden = YES;
// Setting the overlay view up programmatically.
ipView = [[ImagePickerView alloc] init];
self.cameraOverlayView = ipView;
[controller presentModalViewController:self animated:NO];
}
In the overlayView, I've managed to force the takePicture method of UIImagePickerController to fire (I know this, because I can NSLog it, and I hear the sound of the camera taking a picture). The overlayView shows up just fine. However, the delegate method didFinishPickingMediaWithInfo: never gets called, and imagePickerControllerDidCancel doesn't get called either.
So, how do I either get the delegate methods to get called, or save the picture by overriding the takePicture method? (I have no idea how to capture the picture data here, and Google seems to have failed me). I can't help feeling that I've failed to understand how the guts of UIImagePickerController works, but the docs aren't overly helpful:
e.g.:
"You can provide a custom overlay view to display a custom picture-taking interface and you can initiate the taking of pictures from your code. Your custom overlay view can be displayed in addition to, or instead of, the default controls provided by the image picker interface."
or from showCameraControls:
"If you set this property to NO and provide your own custom controls, you can take multiple pictures before dismissing the image picker interface." - How do I dismiss the picker interface?
Note: the delegate is set properly in IB, so that's not the problem.
Thanks for any help you can provide!
I've found that you just have to wait "long enough" before calling takePicture, or it just silently fails. I don't have a good answer for how to determine the minimum value of "long enough" that will always work, but if you set a timer and wait five or ten seconds you should be okay. It would be nice if it returned some kind of an "I'm not ready to take a picture yet, sorry" error either directly from takePicture or through the delegate, but as far as I know it doesn't.
As an update to my own question: It turns out that I was trying to use takePicture too early. When I moved the action to a button on the overlay and sent takePicture from that button (once the picker was presented modally), the delegate methods fired as they should. I don't know if what I wanted is achievable - taking the image without having to press that button, automatically - but if it is, it will probably have to be done by sending takePicture sometime after I was trying to use it.
-(void)imageMethod:(id)sender{
imagePickerController = [[UIImagePickerController alloc]init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePopover=[[UIPopoverController alloc]initWithContentViewController:imagePickerController];
[imagePopover presentPopoverFromRect:importButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
}