iPhone VoiceOver accessibility setting crashes video recording - iphone

I've finally nailed down a bug that crashes a UIImagePickerController when recording video. When the iPhone's VoiceOver accessibility setting is enabled, the recorder crashes without fail when calling presentModalViewController.
I've been unsuccessful so far in coming up with a workaround. Has anyone else experienced this and been able to fix it?

As #kamens mentioned in the comments above, a workaround is to include camera.showsCameraControls = NO in a completion block when presenting the modal view controller, like this:
[controller presentViewController:self animated:YES completion:^{self.showsCameraControls = NO;}];
However, with this solution, the camera controls flash momentarily as the camera is presented, then they disappear. Obviously not ideal when the controls really need to be hidden. The other workaround is to set camera.showsCameraControls = OFF... even less ideal.
#quellish, this is the output from the crash:
*** -[PLCameraToggleButton setAccessibilityValue:]: message sent to deallocated instance 0x4a330b0
#kamens, here is the code I'm using to set the mediaTypes and captureMode:
tmpCamera.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeMovie];
tmpCamera.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;

As #james mentions, this happens in iOS 5.1 when:
Using picker.showsCameraControls = NO
Using animated:NO in your call to [viewController presentViewController:picker animated:YES completion:nil];
The VoiceOver accessibility option is enabled.
...and, significantly, when only specifying movies as the media types accepted by picker:
picker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeMovie];
However, I was able to fix this by changing the above mediaTypes line to:
picker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:picker.sourceType];
...which works fine given that the default camera controls are hidden and I can programmatically control whether to start recording a video or take a picture.
I don't claim to understand the cause of this crash.

Related

Missing keyboard in MFMailComposeViewController

I've got this code working well for months (on iOS 5.1), but I didn't check it for a long time and now (probably iOS 6.0 issue) I've noticed that my MFMailComposeViewController doesn't show the keyboard even when focusing textfields like message body or recipients.
The strange thing is that it reacts on taps, so i can set cursor on 'To' or 'Subject' and the cursor appears, or I'm able to hold the tap to make the zooming glass pop up. But no keyboard :(
SCREENSHOT OF THIS
Here's the code I'm using:
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[self presentModalViewController:mailer animated:YES];
I've been searching a lot about this and found something that deals with
[self resignFirstResponder] or [mailer becomeFirstResponder], but it didn't work.
If I add this code before or after presenting controller
NSLog(#"mailer become %d", [mailer canBecomeFirstResponder]);
It shows 0, however, the
NSLog(#"self resign %d", [self resignFirstResponder]);
shows 1, but it was 0 too before i added the
- (BOOL)canResignFirstResponder {
return YES;
}
Docs say it should return YES by default, so it's double strange.
If I create an empty project with such code it works well, but I can't really do this because my current project is quite huge.
Any help would be appreciated, getting stuck here...
Tested both on iPhone and iOS Simulator (both deployment target 5.1 and 6.0)
Just LOL. The problem was with the
[UIApplication sharedApplication] delegate] window] setWindowLevel:UIWindowLevelStatusBar + 1]
somewhere in my app. Seems like they changed keyboard windowLevel in iOS 6, so that now it's behind. I'm quite lazy to do so, but it would be interesting to know exact windowLevel of the keyboard window :)
Be careful with that!
Thanks to everyone for helping anyway!
If you want to show the keyboard, you must take the text box from the mailer and then send the message becomeFirstResponder.
However, there is not straight forward way to do that. When you touch the box of the message, does the keyboard appear?
For others who may have come up with this keyboard issue in the MailComposer this solution worked for me:
Present the view then call "becomefirstResponder" on the same
MFMailComposeViewController in the completion method.
MFMailComposeViewController* mailCon = [[MFMailComposeViewController alloc] init];
[self presentViewController:mailCon animated:NO completion:^{
[mailCon becomeFirstResponder];
}];

UIImagePickerController Memory Leak

I am seeing a huge memory leak when using UIImagePickerController in my iPhone app. I am using standard code from the apple documents to implement the control:
UIImagePickerController* imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
switch (buttonIndex) {
case 0:
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:imagePickerController animated:YES];
break;
case 1:
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:imagePickerController animated:YES];
break;
default:
break;
}
}
And for the cancel:
-(void) imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[[picker parentViewController] dismissModalViewControllerAnimated: YES];
[picker release];
}
The didFinishPickingMediaWithInfo callback is just as stanard, although I do not even have to pick anything to cause the leak.
Here is what I see in instruments when all I do is open the UIImagePickerController, pick photo library, and press cancel, repeatedly. As you can see the memory keeps growing, and eventually this causes my iPhone app to slow down tremendously.
As you can see I opened the image picker 24 times, and each time it malloc'd 128kb which was never released. Basically 3mb out of my total 6mb is never released.
This memory stays leaked no matter what I do. Even after navigating away from the current controller, is remains the same. I have also implemented the picker control as a singleton with the same results.
Here is what I see when I drill down into those two lines:
Any help here would be greatly appreciated! Again, I do not even have to choose an image. All I do is present the controller, and press cancel.
Update 1
I downloaded and ran apple's example of using the UIIMagePickerController and I see the same leak happening there when running instruments (both in simulator and on the phone).
http://developer.apple.com/library/ios/#samplecode/PhotoPicker/Introduction/Intro.html%23//apple_ref/doc/uid/DTS40010196
All you have to do is hit the photo library button and hit cancel over and over, you'll see the memory keep growing.
Any ideas?
Update 2
I only see this problem when viewing the photo library. I can choose take photo, and open and close that one over and over, without a leak.
It's a bug in the SDK. File a report with Apple. I have the samme isue. It is also documented here: http://www.cocoabuilder.com/archive/cocoa/285293-iphone-memory-leak-can-explain.html
and that was over a year ago and still no fix.
A few of our apps reuse the same UIImagePickerController due to a leak in 2.x (it makes me feel old...). I was under the impression that the leak was fixed, but I could be wrong.
It's a slightly horrible workaround, but sometimes that's the best you can do.
Try setting the UIImagePickerController.delegate to nil before releasing.
-(void) imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[[picker parentViewController] dismissModalViewControllerAnimated: YES];
picker.delegate = nil;
[picker release];
}
The "Mark Heap" button in Instruments has been, for me, the absolute best way of tracking down these sorts of issues.
This is an OK article on how to use it: http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/
But it will tell you, for sure, which objects are surviving longer than you expect... and, ultimately, what the source of the issue is.
You can also see a complete retain/release trace for each individual object which survived - allowing you to pinpoint where your problem is.
EDIT: I use a UIImagePickerControllers as well, and I can promise it doesn't leak (at lesat for me) the way you're suggesting - so, whatever is going on, it's almost surely fixable.
I used UIImagePickerController and after 40 capture images my application received a DidMemoryWarning message and stop, hidden all my views.
In my application I create 40 objects of
UIImagePickerController( new UIImagePickerController() )
To work correctly I create a unique instance shared to all application and with this all work correctly.
I supusose that control lost memory too, but only one time. My application can capture images from camera correctly:
private static UIImagePickerController picker = new UIImagePickerController();

iOS4 ABNewPersonViewController Loses Data Entered when attempting to add a Photo iPhone 4

I have implemented a basic add contact feature to an iOS 4 application. Following the documentation from Apple, I have created a navigation controller, and set its root view to the ABNewPersonViewController. I have implemented the delegate as well. The basic mechanics all work.
The problem I am having is when you add a photo to the new person that is very large (taking a photo or picking one from the library), the ABNewPersonViewController form returns empty when the camera controls are dismissed. No photo is in the add photo box either. If I pick a small image (say a screenshot from the iPhone), everything works. I can see from the debug output: Received memory warning. Level=1
Has anyone else run into this? Is there a way to set the photo quality to a lower setting for the ABNewPersonViewController? Any help appreciated.
ABNewPersonViewController *abNewPersonView = [[ABNewPersonViewController alloc] init];
abNewPersonView.newPersonViewDelegate = self;
UINavigationController *newNavigationController = [UINavigationController alloc];
[newNavigationController initWithRootViewController:abNewPersonView];
[self presentModalViewController:newNavigationController animated:YES];
[abNewPersonView release];
[newNavigationController release];
If ABNewPersonViewController does not handle memory warnings correctly, file a bug with apple.

iOS4: UIImagePickerController behaving weirdly when presented modally

I'm trying to present a UIImagePickerController from a UITableViewController subclass using the following code:
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
if(library)
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
else
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.delegate = self;
picker.allowsEditing = YES;
[self presentModalViewController:picker animated:YES];
[picker release];
If I create a brand new project and throw this code in, it works absolutely fine. However, in this project, for some reason, the UIImagePickerController's view appears as a blank white screen if I try to show the Photo Library, or shows the camera view but with no camera controls if I try to show the Camera.
Is there anything in a UITableViewController subclass that would be causing this? I get complaints about two-stage animations as well, but from what I've been able to find, this is an issue with Apple's code.
For some reason, changing the PRODUCT_NAME in the Info.plist (something which I was going to do anyway but hadn't gotten around to until just now) fixed this issue. I have absolutely no idea why, but I'm going to assume it was some obscure bug in the iPhone SDK.

iPhone: taking a picture programmatically

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];
}