Show iPhone soft keyboard even though a hardware keyboard is connected - iphone

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

Related

Keyboard shows then immediately hides itself when showing MFMessageComposeViewController

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

iOS Keyboard Location and Orientation

I'm relatively new to iOS SDK, and I'm experiencing a very bizarre issue regarding the device keyboard location and orientation for an app I'm working on. The problem is that if the keyboard is open while the user multi-tasks or the app goes into background, after the user comes back to the app, the keyboard will be be displaced (with UIKeyboardWillChangeFrameNotification being raised), but in an incorrect orientation and location.
Sometimes the keyboard shows up completely off the screen too, which is completely undesired behaviour.
My questions are:
What is the position and orientation of the keyboard dependant on? How is it controlled by iOS?
Is there a way to detect when the keyboard is being displayed off-screen regardless of the device type and screen size? I'm thinking it would be doable by tracking UIKeyboardWillChangeFrameNotification or UIKeyboardWillShowNotification.
How would I reset/set the location and orientation of the keyboard prior to displaying it? Is this even possible?
From the documentation:
Use the keys described in “Keyboard Notification User Info Keys” to get the location and size of the keyboard from the userInfo dictionary.
Keys used to get values from the user information dictionary of keyboard notifications:
NSString * const UIKeyboardFrameBeginUserInfoKey;
NSString * const UIKeyboardFrameEndUserInfoKey;
NSString * const UIKeyboardAnimationDurationUserInfoKey;
NSString * const UIKeyboardAnimationCurveUserInfoKey;
1.) Keyboard is a UIWindow, the position is dependent on the Application's Main Window.
2.) What you could do is, upon the one of the notifications UIKeyboardWillShowNotification or UIKeyboardWillChangeFrameNotification method firing, loop through the windows subviews to locate the Keyboard. In one of my applications I needed to add a subview to the keyboard. For your case you can get the frame by doing this:
//The UIWindow that contains the keyboard view - It some situations it will be better to actually
//iterate through each window to figure out where the keyboard is, but In my applications case
//I know that the second window has the keyboard so I just reference it directly
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
//Because we cant get access to the UIPeripheral throught the SDK we will just use UIView.
//UIPeripheral is a subclass of UIView anyways
UIView* keyboard;
//Iterate though each view inside of the selected Window
for(int i = 0; i < [tempWindow.subviews count]; i++)
{
//Get a reference of the current view
keyboard = [tempWindow.subviews objectAtIndex:i];
//Assuming this is for 4.0+, In 3.0 you would use "<UIKeyboard"
if([[keyboard description] hasPrefix:#"<UIPeripheral"] == YES) {
//Keyboard is now a UIView reference to the UIPeripheral we want
NSLog(#"Keyboard Frame: %#",NSStringFromCGRect(keyboard.frame));
}
}
3.) Not completely sure this is possible, but with the supplied code I gave you. keyboard is now casted to a 'UIView', which you can apply your own transforms to.
This might not be the most elegant solution, but it works well for my case.
Hope this Helps !

iPhone/iPad Keyboard Dimming

I am writing a universal app that will be used primarily at night. I will need to display a keyboard but do not want the light colors of the keyboard to blind the user and/or spoil their night vision. I do not want to have to go through the trouble to creating a custom keyboard so I thought a solution might be to place a UIView over the keyboard and give it a black background color with an alpha of 0.5 or something however, I can not figure out how to get a UIView to cover the keyboard. Does anyone know how to do this? Does Apple allow this?
The keyboard is found as a subview of a new window that is added when it appears. Finding it is a little hacky and fragile (will need checking at new iOS versions, as it has changed before) but it does work and it is allowed (I do exactly this for a night mode in an app that is on the app store).
UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1]; // This assumes you aren't adding any new windows yourself
for(UIView *keyboard in tempWindow.subviews)
{
if([[keyboard description] hasPrefix:#"<UIPeripheralHost"] == YES) // This was different in an earlier version of iOS, and may well change again in the future!
{
[keyboard addSubview:maskView];
break;
}
}
This is done inside the method that responds to the UIKeyboardDidShowNotification object. I've not tried it on the iPad, this is iPhone code only.
The mask view is, as you say, just a plain view with a black background and some transparency. You can also use the alert keyboard style which gives a black space in between the keys.
This method does not prevent the little key flashes (the larger keys that pop up when you tap a key) from being at full brightness, unfortunately.
try applying the required changes on inputView property of UITextFiled/UITextArea (the one being used).

I'm just beginning Objective-C and I'm developing an iPhone app. I need some help with Objective-C

I'm 14 and developing my second iOS app: an iPhone version of the web-based chatroom I created for my school. I have very little knowledge of Objective-C and I need some help. This is a very basic app, where I have a UIWebView and a tool bar at the bottom of the view. The toolbar contains a text field and a "Send" button. I have the UIWebView working and pointing to the correct site, but I need two basic things:
1. I need the toolbar to reposition itself to the top of the keyboard when the text box is tapped, also resizing the UIWebView for the correct space.
and
2. I need to find a way to post the contents of my text field to my PHP script online when the "Send" button is tapped or the "Send" key on the keyboard is pressed.
Any help would be much appreciated!
Edit: Here are some screenshots of the app.
App screenshots.
You'll want to take a look at "Managing The Keyboard".
In essense what you want to do is have the delegate of the textfield deal with the keyboard notification "UIKeyboardWillShowNotification", and use the info which it will supply to move the toolbar into place, possibly with an animation.
---UPDATE---
Looking around a little, I found this:
iPhone Keyboard Covers UITextField
Lots of stuff to answer here!
Repositioning the toolbar
To reposition the toolbar you'll need to do a few things:
Get notified when the user starts using it
Resize your webview and move your toolbar
In order to get notified when the user taps on your text field you will need to:
Implement the UITextFieldDelegate protocol in your controller (most likely the main view controller).
Implement the delegate method -textFieldDidBeginEditing:.
Set your controller object as the text field's delegate.
UITextFieldDelegateProtocol Reference should explain this.
To resize your controls you will need to have them declared as IBOutlets and hook them up in interface builder. Your best bet for this is to read the Interface Builder Quick Start Guide.
Sending the data
Sending the data is going to be the trickier bit. A couple of things you could do:
Cheat and send the data as "GET" data by using a method like NSString's -initWithContentsOfURL: (something like this:)
NSString *chatString = [textField stringValue]; //get the chat string
NSString *encodedString = [chatString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]; //URL-encode any special characters
NSString *urlToRequest = [NSString stringWithFormat:#"http://mysite.com/chat.php?message=%#", encodedString];
NSURL *requestURL = [NSURL URLWithString:urlToRequest];
NSString *urlResult = [NSString stringWithContentsOfURL:requestURL];
By doing it this way you will be able to get the message in your php script like so:
$encoded_message = $_GET['message'];
$message = urldecode($encoded_message);
This is not the most robust way but for a high school project it should probably be fine.
The more robust way you could do it is by using the cocoa libraries intended for this. I won't delve into these details as it is quite complex and Apple's own developer documentation does a much better job of explaining it: URL Loading System Programming Guide
Edit: As per Hack Saw's post, using NSNotification to determine when the keyboard will show is better. By doing things the delegate way as I've described, you will only be notified when that particular text field is selected. Documentation on managing the keyboard can be found here: Text, Web, and Editing Programming Guide for iOS
This is a quick unfancy way to do move the toolbar up. I'm sure you'll be able to adapt it to your needs.
First you have to register for the keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
and then you move the toolbar up. Like this.
- (void)keyboardWillShow:(NSNotification *)notification {
if (keyboardShown) {
return;
}
NSDictionary* info = [notification userInfo];
// Get the size of the keyboard.
NSValue* aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
CGSize keyboardSize = [aValue CGRectValue].size;
CGRect currentFrame = self.toolbar.frame;
currentFrame.origin.y = currentFrame.origin.y - keyboardSize.height;
[UIView beginAnimations:#"ShowKeyboard" context:NULL];
[UIView setAnimationCurve:[[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]];
[UIView setAnimationDuration:[[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
self.toolbar.frame = currentFrame;
[UIView commitAnimations];
keyboardShown = YES;
}
of course you have to create another method that will hide the keyboard, but this is basically the same as show keyboard, so I'll omit it.
To make things a little bit more easy you could make the toolbar and the webview subviews of a "content" view. You would then resize the height of the contentview and autoresizing will take care of the rest.
Oh and you should not resize the view just because of textFieldDidBeginEditing:. I don't know for the iphone, but it's possible to connect an external keyboard to the ipad. And you would resize the view without the keyboard showing up, leaving a big blank frame at the bottom.

Scrolling UITextView programmatically

I'm implementing some simple text chatting capabilities in my app and I'm having issues with scrolling the UITextView programmatically. I'm using a UITextView created in Interface Builder that appends a new line and some text to the preexisting text. When the new text is added it should scroll to the bottom.
I built a test application to nail down the concept before adding it to my app. The text in the UITextView updates with the text from a UITextField, however no scrolling occurs.
- (IBAction)enteredText {
CGPoint currentPosition = [textWindow contentOffset];
[textWindow setText:[NSString stringWithFormat:#"%#\n%#", textWindow.text, textInput.text]];
[textWindow setContentOffset:currentPosition animated:NO];
[textWindow scrollRangeToVisible:NSMakeRange([textWindow.text length], 0)];
[textInput setText:#""];
[textInput becomeFirstResponder];
}
I remember implementing a very similar feature in another application I developed a while ago andfrom what I remember the code is similar. The only difference is that the earlier application was for iPhone OS 2 but this one is for 3.0. I read in some forums that the 3.0 beta had some issues with scrolling when the UITextView was created in Interface Builder. I checked the current release notes and I didn't see anything indicating that.
Edit: The IB action is called because text is updated in the UITextView. And "Cancellable Content Touches" is checked.
Edit: Confirmed that the same code works on 2.2.1 but not 3.0
I found that after the user has tapped on the UITextView the scrolling begins to work. So after I loaded this particular view I temporarily set the UITextView as FirstResponder, then the UITextField as FirstResponder:
[myChatRoomViewController.chatWindow becomeFirstResponder];
[myChatRoomViewController.input becomeFirstResponder];
The scrolling then happened automatically, albeit it seemed less smoother than what I remembered in iPhone OS 2.
Are you sure the IBAction is getting called? If so, try making sure that “Cancellable Content Touches” is checked in Interface Builder. This should solve the problem you hinted about in your post.