I have an iPad app that has a UIWebView containing several text inputs. I have the web view set to only scroll vertically. When I click on a text input and show and hide the keyboard -- I can no longer scroll up and down. I can tap on more inputs, but I can't scroll.
It's strange because when I tap on an input, I'm able to scroll up and down with the keyboard being shown. But, as soon as I hide the keyboard, I can no longer scroll.
I'm currently using NSNotification center to capture the event that happens when the keyboard is hidden, but I'm not sure what needs to happen. I've tried re-enabling scrolling or resigning the first responder back to the web view or to the web view's scrollview.
- (void)viewDidLoad
{
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(keyboardHidden) name:UIKeyboardWillHideNotification object:nil];
}
-(void)keyboardHidden
{
// Does something need to happen in here??
}
Related
This is Screenshot
In View B, When keyboard is shown and pop viewController to View A with interactivePopGestureRecognizer, the keyboard is still stay here :(
How can let keyboard move with view B ?
(like iMessage or Facebook Messenger)
ps: I'm try to get keyboard view and add to self.view, it's useful, but i think it's not a good way.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShown)
name:UIKeyboardDidShowNotification object:nil];
and
- (void)keyboardDidShown
{
UIView * keyboardView = self.textView.inputAccessoryView.superview;
[self.view addSubview: keyboardView];
}
Try this solution:
https://github.com/cotap/TAPKeyboardPop
This is lightweight category that listens interactivePopGestureRecognizer gesture and animating keyboard accordingly.
You don't add keybordView to the view. If you want to show keyboard for your UITextField/UITextView you call becomeFirstResponder on that object. In your example it should be:
[self.textView becomeFirstResponder];
If you want to hide keyboard you call:
[self.textView resignFirstResponder];
And if you want to hide your keyboard before you dismiss your ViewA you should call it in the beginning of your interactivePopGestureRecognizer when you start animation to show ViewB.
Hope it help.
//EXTENDED
I don't know why you are trying to add accessoryView as a subview to your view
- (void)keyboardDidShown
{
UIView * keyboardView = self.textView.inputAccessoryView.superview;
[self.view addSubview: keyboardView];
}
And I don't understand why do you use notification centre.
The functionality that the keyboard stay when you dismissed the view (as iMessage app) is a standard functionality.
Just use
[self.textView becomeFirstResponder];
when you want to show the keyboard and don't call
[self.textView resignFirstResponder];
when you pop your view controller. iOS does the job for you.
I've done large enough research but couldn't find answer to my question.
Suppose I have a webView in which I have some text fields, some of them are placed on the bottom of screen so that when keyboard appears it should hide that fields. After keyboard appears the content of webView slides up in order to make that fields visible. The problem is that I DON'T want the content to slide up.
Question is: How can I disable that feature of webview , or somehow make the content not scroll up.???
Thanks, any help would be appreciated.
If you want to disable ALL scrolling, including the auto-scroll when you navigate between form fields, setting webView.scrollView.scrollEnabled=NO doesn't quite cover everything. That stops normal tap-and-drag scrolling, but not the automatic bring-field-into-view scrolling when you navigate around a web form.
Also, watching for UIKeyboardWillShowNotification will let you prevent scrolling when the keyboard appears, but that will do nothing if the keyboard is already up from editing a different form field.
Here's how to prevent ALL scrolling in three simple steps:
1) After you create the UIWebView, disable normal scrolling:
myWebView.scrollView.scrollEnabled = NO;
2) Then register your view controller as the scrollView's delegate:
myWebView.scrollView.delegate = self;
(And make sure to add <UIScrollViewDelegate> to your class's #interface definition to prevent compiler warnings)
3) Capture and undo all scroll events:
// UIScrollViewDelegate method
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
scrollView.bounds = myWebView.bounds;
}
I think this class should help with your problem. It scrolls content up, so if u have textfield at the bottom of the screen, it will move it above the keyboard.
I found the solution for me. I just scroll it down again after scrolling up.
First I catch notification UIKeyboardWillShowNotification by adding observer to it
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
then implement method:
-(void)keyboardWillShow:(NSNotification*)aNotification{
NSDictionary* info = [aNotification userInfo];
float kbHeight = [[NSNumber numberWithFloat:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height]floatValue];
float kbWidth = [[NSNumber numberWithFloat:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.width]floatValue];
BOOL keyboardIsVisible=[self UIKeyboardIsVisible];
//Check orientation and scroll down webview content by keyboard size
if(kbWidth==[UIScreen mainScreen].bounds.size.width){
if (!keyboardIsVisible) {
[[chatView scrollView] setContentOffset:CGPointMake(0, -kbHeight+10) animated:YES];
} //If is landscape content scroll up is about 113 px so need to scroll down by 113
}else if (kbHeight==[UIScreen mainScreen].bounds.size.height){
if (!keyboardIsVisible) {
[[chatView scrollView] setContentOffset:CGPointMake(0, -113) animated:YES];
}
}
}
This is not what exactly I asked but helped me to solve my problem.
Thanks.
Originally I was looking to stop my webview from zooming in when an input field (in my case the comments section) was focused on. The entire view would zoom in automatically and put everything out of whack.
I managed to do it with this, and at the same time I got the webview to stop scrolling up and out of the way of the soft keyboard as well:
//Stop the webview from zooming in when the comments section is used.
UIScrollView *scrollView = [_webView.subviews objectAtIndex:0];
scrollView.delegate = self;
//_webView.scrollView.delegate = self; //for versions newer than iOS5.
I have an application with Textfields in my MainViewController.m file. There is also a scrollview in that file, so when the keyboard comes up, the view scrolls so the user can see the textfield. The keyboard is dismissed when the user taps on the screen. Everything is working well EXCEPT in the case that the user hits the home button to put the app in the background and then comes back to it. In this case, the keyboard is still up, but my scrollview is down with textfields hidden. Ideally I would like to have the keyboard be dismissed as well.
Having looked into it, the methods that are called are all in the AppDelegate.m file (unfortunately it does not go into ViewDidLoad or any of the View lifecycle methods). How do I dismiss the keyboard from applicationDidEnterBackground in the AppDelegate.m file?
I am kind of a newbie - I have tried making a +dismisskeyboard function in my MainViewController file and calling it from the Appdelegate, but my Textfields are all instance variables and that does not work. I have also tried to create a textfield in my AppDelegate file and then do this -
[_someField becomeFirstResponder];
[_someField resignFirstResponder];
but this also does not work... I can't figure out how to link anything on my storyboard to the AppDelegate property of someField.
Can anyone suggest the correct approach to tackle this problem?
Just register a method for UIApplicationDidEnterBackgroundNotification in your MainViewController class and dismiss your keyboard there. e.g.
Register for the notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receivedNotification:) name:UIApplicationDidEnterBackgroundNotification object:nil];
then add this method
- (void) receivedNotification:(NSNotification *) notification
{
[txtFld resignFirstResponder];
}
I am calling
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:nil];
method in viewDidLoad, but keyboard dos not appearing when i click on web view.
can anybody tell me why is this happening
You can't make the keyboard show up be calling anything on the notification center. You need an UI element that can handle text input (for example an UITextField, a UIWebView can't handle text input by itself) and than call
[textField becomeFirstResponder]
I have an intermittent bug that is confounding me. Any advice on how to track it down or what might be the cause are greatly appreciated.
I have a "DetailView" with a few labels, an Image View and a Text View. In the navbar I also have a camera button to open an Image Picker and take a picture (later added to the image view). Basic stuff.
Sometimes, when taking a picture and then editing the text: the whole view between the navbar and the keyboard goes blank (to my background color). Happens more often the "first time". Repeating the procedure does not give the same problem. Happens almost only on the 3Gs (very rare on the 3G and the original iPhone).
I have two theories.
1 is that it has something to do with the scroll view that is the container for the disappearing GUI elements. The view hierarchy is: ScrollView -> UIView -> labels, texts and image. Is it a bad thing to have the scrollview as the "main" view?
2 is that it has to do with memory. The 3Gs has a better camera and takes bigger pictures... Possibly something happens if the app gets a low memory warning while taking the picture (not uncommon)?
Are any of these two at all feasible? Any other ideas on what to look for?
thanks
Update:
Could two simultaneous animations cause the bug?
On the KeyboardWillShow notification I resize the ScrollView using the UIView beginAnimations ... commitAnimations and right after that (which happens asynchronously I believe) I also tell the scroll view to scrollRectToVisible for the TextView.
like this:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
CGRect rect = [[self view] frame];
rect.size.height -= keyboardFrame.size.height * (up? 1 : -1);
[[self view] setFrame: rect];
[UIView commitAnimations];
// Scroll the active text field into view.
DetailView *tempScrollView = (DetailView *) [self view];
CGRect textFieldRect = [comments frame];
[tempScrollView scrollRectToVisible:textFieldRect animated:YES];
The 3GS also has twice the RAM of the 3G/original (256MB vs 128), so I doubt it's memory-related. You can override didReceiveMemoryWarning: to check, though.
When exactly does the view go blank? Does it happen spontaneously, or only when you press a certain button, etc. For example, does it only happen when you start editing the text view (i.e. when the keyboard pops up)? If so, check your view autoresizing masks.
Are the views actually gone, or are they just offscreen? Try printing their frames to the console or using the debugger to check where exactly they should be.
When you find the bug, please post your solution- it sounds like a problem I might encounter some day.
I managed to track it down in the Sim.
Here it goes:
Going to the DetailView
Tapping the camera buttom to "open" the UIImagePickerController (camera or Library, does not matter)
Now I simulate a memory warning before closing the Picker
Choose the image to close the Picker
Tap the UITextView
Under these circumstances the view will receive TWO UIKeyboardWillShowNotification are eachother... so my copied example code for resizing the view is run twise... making it 416px - 216px - 216px = -16px in height... not a good thing.
The reason for the double notifications were of-course that the ViewController added itself as an observer in viewDidLoad... which runs again when the view "appears" after the memory warning... but the ViewController never removed itself as an observer.
Doing that fixed the bug for sure:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
(void)viewDidUnload {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}