Keyboard shows then immediately hides itself when showing MFMessageComposeViewController - iphone

I am building a PhoneGap app using Cordova 2.2 for IOS. I am experiencing some bizarre behavior when calling out to a native obj-c plugin I have written to show the MFMessageComposeViewController.
The setup is very simple - I have a tap event attached to a UI element, that when pressed, will make a call to my PhoneGap plugin, pass with it a number and a text message, then show the MFMessageComposeViewController with the parameters pre-populated.
My javascript looks like this:
$(document).bind('deviceready', function(){
$(".theButton").tap(function(){
cordova.exec(function(){}, function() {}, "PhoneGapSms", "SendSms", [db.getItem("profile_sms"), db.getItem("profile_emergency")]);
});
});
And my obj-c code looks like this:
- (void)SendSms:(CDVInvokedUrlCommand*)command
{
CDVInvokedUrlCommand* myCommand = command;
MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init];
NSString* body = [command.arguments objectAtIndex:0];
NSString* toRecipientsString = [command.arguments objectAtIndex:1];
if(body != nil)
picker.body = body;
if(toRecipientsString != nil)
[picker setRecipients:[ toRecipientsString componentsSeparatedByString:#","]];
picker.messageComposeDelegate = self;
[self.viewController presentModalViewController:picker animated:YES];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[picker release];
}
So, all in all, very simple stuff.
My Problem is this:
When my iPhone is plugged into my Mac and the app is run from XCode, the Message Composer overlay appears great, with my values pre-populated. Image below demonstrating the SMS interface appears fine while plugged into XCode:
When my iPhone is unplugged from my Mac, and the app is run from the spring board, the Overlay slides up, the keyboard begins to slide up, then immediately slides down - making it impossible to type or send the message. This is what it looks like when not attached to the Mac/Xcode - the keyboard begins to slide up then immediately slides down (~ < 1 sec) leaving the following interface:
I can't for the life of me figure out what would cause the keyboard to hide when not running from XCode, but work perfectly well when it is.
Is there any way to 'force' the keyboard to display, or possibly put the whole modalviewcontroller as first responder in some form or fashion?
Any suggestions are appreciated!
Edit:
The keyboard WILL appear again if you click in the contact area

You must add MessageUI.framework to your Xcode project and include a
#import <MessageUI/MessageUI.h> in your header file.
try this code may be its helpful to you..
[self presentModalViewController:picker animated:YES];
//[self becomeFirstResponder];//try picker also instead of self
Also Refer this bellow tutorial and also check demo..
new-tutorial-developing-and-architecting-a-phonegap-application
SMSComposer
i hope this help you...

I encountered these symptoms with a Sencha Touch 2.2 and Cordova 2.6.0 setup (specifically, iOS 6+ devices).
The issue was with the web framework stealing focus away from the native SMS Composer modal, typically occurring after the first SMS Composer modal had been successfully displayed and closed.
A event.preventDefault() and event.stopPropagation() call once the event had been fired (or event.stopEvent() in Sencha land) resolved this.
Hope this helps,
-James

First: The most likely culprit, without seeing your code, is that your parent (presenting) view controller may have an action in its viewWillDisappear or viewDidDisappear that is affecting who has the "first" responder. These methods get called when presenting a view controller modally. It may be behaving differently on the simulator than the device due to timing - often really close timing conditions are different on the ARM device and the i386 processor.
Second: Does anywhere in your app register for the UIKeyboardWillShowNotification or the UIKeyboardDidShowNotification? If so, put breakpoints in the methods that are called as a result - it's possible some other controller in your view hierarchy is interfering with this one.
To answer your question...
Is there any way to 'force' the keyboard to display, or possibly put the whole modalviewcontroller as first responder in some form or fashion?
No to both. The only way to make the keyboard display is to call the becomeFirstResponder method of the input view. Since Apple doesn't expose the text view, you cannot send it messages. Setting the modalViewController as first responder would be setting the wrong object.

I found the same type of issue But Not Sure it will Solve your problem or not Just Have a Look on the Following Links :
1. http://community.phonegap.com/nitobi/topics/keyboard_is_not_triggerd_in_my_ios_build
2. https://github.com/phonegap/build/issues/31
If its not Solving your issue then you can Download the Sample code Here.
Link: https://github.com/phonegap/phonegap-plugins/tree/master/iPhone/SMSComposer

Related

How to handle a system alert message for iOS?

I have an app where i am using UIImagePickerController to use the native camer inorder to click pictures but the when the photo gallery on the device is full. I get a alert message which says "Cannot Take Photo - There is not enough available storage to take a photo.You can manage your storage in Settings". I am given two options to click the "Done" button or "Settings" button. Clicking either of them does nothing and the app freezes completely.
This is what i get from the console logs
Not enough space to take a picture. Available space is 0
The code for the picker
UIImagePickerController *mediaPicker = [[UIImagePickerController alloc] init];
mediaPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
mediaPicker.delegate=self;
mediaPicker.sourceType=UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:mediaPicker animated:YES];
I have implemented and tried all the delegates already and its not calling any delegate.
Is there any way i can implement something where i can use a listener to detect when this error occurs and take back the user to the previous screen ?
Sounds like your device run out of memory, system sent lots of "Out of Memory" notifications and your app got one, too. As result your app released the UIViewController, which originally launched UIImagePickerController.
Now when you dismiss imagePicker with Done/Settings button, control returns back to your app. The old UIViewController doesn't exist any more and you haven't implemented code to recreate it from scratch in this kind of situations. The device looks like it frozen, but only because UI wasn't redrawn by your app. Otherwise app works just fine.
You can check this case by implementing didReceiveMemoryWarning method into every UIViewController and logging, if it's called:
- (void)didReceiveMemoryWarning
{
NSLog(#"%#", [self description]);
[super didReceiveMemoryWarning];
}
One of my favourite bugs. Easy to miss :)
This sounds like a bug in iOS.
You should file a feedback at https://feedbackassistant.apple.com/.

cut/copy/paste functionality stopped working in my iOS application

UPDATE: cut/copy/paste disabled in my app.
I am confused with my iOS app while developing for iPhone devices. Execution flow enters a point like the code below
[self navigationController] pushViewController:chooseDeviceView animated:YES];
[chooseDeviceView release];
[numberTextField setText:#""];
The view changes and things "work properly". The problem is that after this the cut/copy/paste functionality is missing in my app.
Don't really know how to start debugging the issue. Does it ring a bell to anybody?
That was a very complicated issue for a beginner. Finally the issue was a little bit related with status message corrupts main window in my iPhone app
Add in your new viewController this:
- (BOOL)canBecomeFirstResponder {
return YES;
}
It should solve your issue.

Problem when adding Three20 PhotoViewer to my UINavigationViewController

I want a photo viewer in my iphone app and I liked the Three20 photo viewer. I found it somehow hard to integrate it in my own app where I have my typical UINavigationViewController. So far I succeeded in doing the following:
TTURLMap *map = [[[TTURLMap alloc] init] autorelease];
[map from:#"tt://appPhotos" toSharedViewController:[PhotoViewController class]];
[self.navigationController pushViewController:[map objectForURL:#"tt://appPhotos"] animated:YES];
The only problem is that wenn I click back to my original view, its navigation bar keeps the style of the photo viewer (transperant and shows the view under it).
How can I get back my original navigation bar?
My experience: I once used three20's PhotoViewer and every time I went back from the PhotoViewer to my other view. The system status bar remained black and transparent (while it should be with default style). I solved it by manually and programmatically changing the status bar style every time when the back action was triggered.
Yes, this is a bit of an issue for sure. A good solution, as #diwup says, is to implement a manual fix. I tend to subclass TTPhotoViewer when I need it. Not only does it help with this problem but it also makes it much easier to use I find.
If you decide to subclass, then you should use whatever variation of the following you require:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
self.navigationController.navigationBar.tintColor = myTintColor;
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
}
However, if you don't want to subclass, you can always put the code into the - [viewWillAppear:] method of any class that comes after the photo viewer.

Show iPhone soft keyboard even though a hardware keyboard is connected

My iPad app uses an external "device" that acts as a hardware keyboard. But, at some point in the settings, I need to input text and I can't use the "device" ("device" is not a keyboard).
So, is there any way to force pop the soft keyboard even thought I have a hardware keyboard connected?
Yes. We've done this in a few of our apps for when the user has a Bluetooth scanner "keyboard" paired with the device. What you can do is make sure your textField has an inputAccessoryView and then force the frame of the inputAccessoryView yourself. This will cause the keyboard to display on screen.
We added the following two functions to our AppDelegate. The 'inputAccessoryView' variable is a UIView* we have declared in our app delegate:
//This function responds to all textFieldBegan editing
// we need to add an accessory view and use that to force the keyboards frame
// this way the keyboard appears when the scanner is attached
-(void) textFieldBegan: (NSNotification *) theNotification
{
UITextField *theTextField = [theNotification object];
// NSLog(#"textFieldBegan: %#", theTextField);
if (!inputAccessoryView) {
inputAccessoryView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, navigationController.view.frame.size.width, 1)];
}
theTextField.inputAccessoryView = inputAccessoryView;
[self performSelector:#selector(forceKeyboard) withObject:nil afterDelay:0];
}
//Change the inputAccessoryView frame - this is correct for portrait, use a different
// frame for landscape
-(void) forceKeyboard
{
inputAccessoryView.superview.frame = CGRectMake(0, 759, 768, 265);
}
Then in our applicationDidFinishLaunching we added this notification observer so we would get an event anytime a text field began editing
//Setup the textFieldNotifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textFieldBegan:) name:UITextFieldTextDidBeginEditingNotification object:nil];
Hope that helps!
There’s no way to do this with the current SDK. Please let Apple know via the Bug Reporter.
The solutions here didn't work on iOS 13 or aren't App Store compatible so I solved the problem by creating my own soft keyboard. It is pretty basic but works. Feel free to contribute!
Project on Github
All you have to do is add SoftKeyboardView.swift to your project and somewhere (e.g. appDidFinishLaunching) hit the singleton:
Usage:
SoftKeyboardManager.shared.disabled = false
Since I have the same problem, the closest solution I have found is to use Erica Sadun's app called KeysPlease which is available via cydia and modmyi. It's description is "Use soft kb even when connected to a BT kb.".
Additionally I have found that if you have a physical keyboard also attached, in my case via the iPad keyboard doc, you can bring up the keyboard using a key which seems to map to the eject key on a bluetooth keyboard. Perhaps there is a way to inject this key as if it was pressed on an attached keyboard?
I really wish there was a more official coding solution to this.
When my app connect bluetooth device, keyboard wouldn't show.I try set force the frame of the inputAccessoryView as Brian Robbins say. It didn't work.
Then I use a stupid way to solve.I found when I click textfield or textview one more time, keyboard will show.
So I just need to simulate touch in textfield or textview once , it works.
If you want to do some simulate touch, check this.
https://github.com/HUYU2048/PTFakeTouch

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