I've been moving an alert view slightly higher so i can fit a keyboard on screen as well. I just do this by grabbing the frame of the alert and changing the Y after i have already shown the alert so that the frame variables are legit. This works fine on the simulator, but when I do this on the hardware, the alert starts at the correct position but then almost immediately jumps down to it's original vertical center place. Is the UIAlertView position a fixed thing that isn't supposed to change per the usability guidelines or am i just doing something incorrectly?
Thanks!
What OS are you trying this against? I got this to work on both the OS 3.0 Simulator and OS 3.0 Device:
UIAlertView * alert = [ [ UIAlertView alloc ] initWithTitle:#"Alert" message:#"Alert"
delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil ];
alert.transform = CGAffineTransformTranslate( alert.transform, 0.0, 100.0 );
[ alert show ];
CGAffineTransformTranslate takes three arguments: the existing transform, an x transform, and a y transform. In the example I used, the alert view appeared 100 pixels higher than it normally would. Give this a try and see what happens.
Also, I'm pretty certain you can modify the frame before showing the alert as it likely sets up the alert's frame in init to be the center of the entire screen by default.
Since iOS4 moving around UIAlertViews gets tricky. I've noticed that if you add a UITextField subview on the UIAlertView, on iOS4 the alert gets moved up so that the keyboard doesn't overlap it. This doesn't happen < iOS4.
Also I've noticed that the alert's frame isn't initialized even after show is called, so there is no easy programatic way of doing a relative CGAffineTransformation. The only solution would be to do conditional transforms based on the OS version.
To me this looks like threading over undocumented behavior of UIAlertViews that is subject to change at any time. I don't think Apple meant for us to be using the alerts for anything more than texts and buttons (even though their own applications break this rule).
I for one will start building my own custom alerts for this type of scenarios.
Isn't an alert meant to be modal - i.e: you wouldn't generally perform any other user input while an alert is active? If this is the case then why would you need visibility of the keyboard?
Related
When using iPhone app on a iPad, the keyboard extension can only know the screen size of an iPad, but actually I should know it's like running on an iPhone, and get a size like an iPhone.
My current code runs in a iPhone app on iPad look like this:
In viewDidAppear of UIInputViewController, I can actually get the frame of self.inputView, that is 320 in this case.
However, self.view and self.inputView's frame are both CGRecteZero in viewDidload or viewWillAppear, and that's actually why we should set keyboard height only after [super viewDidAppear].
The actual size of the keyboard view(self.view.frame) can be checked right after invoking [super viewDidLayoutSubviews] in viewDidLayoutSubviews of UIInputViewController. It is the 1st place to check the size and much faster than viewDidAppear.
Your Keyboard extension should be universal, if so then you can get device type (iPhone/iPad) by using below code.
let isPad = UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad
It may possible that you are using below method to get screen bounds
UIScreen.mainScreen().bounds.size
This method gives device's whole height, width in keyboard extension.
You can use nested condition by using above two condition to solve your problem.
We're using Phonegap to develop our mobile app, and we borrowed code from here to remove the black next/prev/done bar from the keyboard:
https://stackoverflow.com/a/9276023/35364
What that code does is it finds the black bar, as a UIView object, and calls 'removeFromSuperview' on it.
We're not familiar with the iOS SDK/API. So while we can look at the code and get an idea of what it's doing, we can't tell if it's doing it properly, or how to improve it.
The specific problem we're running into:
We have a text field for writing a message, and we're manually controlling the placement of this field to be exactly above the keyboard, similar to the native sms app. In other words, we're putting it where the black bar was supposed to be.
When we focus/type in the message field, the system pushes the view up. It seems like this is a mechanism to make sure the text field is not invisible when the user types in it.
This is happening even though the text field is visible.
I noticed that by putting the input field right above where the black bar would normally be (as oppose to behind it), the view doesn't scroll.
So it seems the system somehow thinks the black bar is still there!
(To double check: when the black bar is not removed, and we put the text field right above it, we can focus and type in it, and the view would not scroll).
So the question is:
Why does the "system" push the content up when editing a text-field that's place right "behind" where the black bar is supposed to be? Is it because the black bar is not completely removed yet? Do we need to do something to "completely" remove the black bar? Do we need to force iOS to recalculate the size of the keyboard? or what exactly?
Is this mechanism (pushing up the view) implemented by iOS's UIWebView, or by Phonegap?
Is there any phonegap app that has solved this problem?
replace
[subviewWhichIsPossibleFormView removeFromSuperview];
with
UIScrollView *webScroll = [webView.subviews lastObject];
CGRect newFrame = webScroll.frame;
float accesssoryHeight = subviewWhichIsPossibleFormView.frame.size.height;
newFrame.size.height += accesssoryHeight;
[subviewWhichIsPossibleFormView removeFromSuperview];
[webScroll setFrame:newFrame];
it resize the content scroll view for the amount of missing accessory space. It is as far using "private API" as the other code. In detail it isn't using private API directly but if Apple decide to change how a view appears (in this case Keyboard and WebView) then it will crash.
For example if they rename UIWebFormAccessory, your code will not work anymore.
EDIT:
on iOS 5.0+ you can call webView.scrollView directly. So you can split the code to have a pre iOS 5 fallback:
UIScrollView *webScroll;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0) {
webScroll = webView.scrollView;
} else {
webScroll = [webView.subviews lastObject]; // iOS 2.x (?) - 4.x
// make sure this code runs appropriate on older SDKs
}
This worked for me: https://github.com/don/KeyboardToolbarRemover
You will have to know though, there is no Cordova.plist file as of Phonegap 2.3.0 - instead edit your config XML file with the following:
<plugin name="KeyboardToolbarRemover" value="KeyboardToolbarRemover" />
in the branch
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).
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
are their any reasons why my UIActionSheet would be taking a while to load. It works fine just after lauch, but as soon as I loop through some actions once or twice, is loads very slow, and you can see the grey backdrop crawl down to finish drawing the sheet.
help?
Sam
Ok, so I found the solution moments later.
I assume this is how it works, feel free to correct me.
U used the cheats animation way of [ UIView ]
and i guess this changed the way for the UIActionSheet to pop up, so I wrote in these two lines before i asked it to show.in.view
- (IBAction)goToBlog{
contactUs.actionSheetStyle = UIActionSheetStyleDefault;
[UIActionSheet setAnimationDelay:0];
[UIActionSheet setAnimationDuration:0.1];
[contactUs showInView:self.view];
}
and that seemed to work. so im happy.