I'm having a startview like this:
Where The first half of the screen is a Google map and the second half is a UITableview with in the header cell a UISearchbar.
When I click on the searchbar this happens on big screens but on small screens my uisearchbar is covered with the keyboard.
As you can see , when the keyboard shows up the searchbar moves a little bit to the bottom. I don't want that. It should push everything up so the Tableview is visible.
I followed a tutorial about contentInset. But it doesn't do anything.
- (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) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardWillShow:(NSNotification *)notification
{
NSLog(#"KeyboardWillshow");
// Step 1: Get the size of the keyboard.
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// Step 2: Adjust the bottom content inset of your scroll view by the keyboard height.
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize.height, 0.0);
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
// Step 3: Scroll the target text field into view.
CGRect aRect = self.view.frame;
aRect.size.height -= keyboardSize.height;
if (!CGRectContainsPoint(aRect, _searchBar.frame.origin) ) {
CGPoint scrollPoint = CGPointMake(0.0, _searchBar.frame.origin.y - (keyboardSize.height-15));
[self.tableView setContentOffset:scrollPoint animated:YES];
NSLog(#"Scrolled");
}
}
- (void)keyboardWillHide:(NSNotification *)notification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.tableView.contentInset = contentInsets;
self.tableView.scrollIndicatorInsets = contentInsets;
}
It comes in the if test where Scrolled is printed. And still nothing happens.
Where _searchBar is my UISearchbar variable.
Anyone an idea?
EDIT:
Solved the problem except the UISearchbar jump crapy down when clicking on it. This creates a gap like you can see on the screenshot:
See the example below.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
float height =150;
float yPoint = aRect.size.height-height;
[self.tblSearch setFrame:CGRectMake(self.tblSearch.frame.origin.x
, yPoint, self.tblSearch.frame.size.width, height)];
}
If your searchbar, tableview and mapview is all place in a view,
and you want to push the tableview and searchbar visible when keyboardWillshow,
you should update frame instead of contentInset.
Related
I have a problem about the iOS at UIScrollview in Objective-C.
I drag the UI auto layout about below photo.
When I click the textfield, the keyboard will show, and I need can scroll the view.
It is seem is ok, but when I click done button and hide the keyboard,
I click textfield again, the keyboard will show, but I can't scroll the view again.
And other problem is like upper photo,
When I scrolled on the tableview , the tableview is can't scroll,
it is scroll the outside scroll view, how can I set the touch on the tableview , it's scroll tableview .
My keyboard event code below and I had upload this page complete code and auto layout project in GitHub:
this problem link
Have anyone can give me some help? thank you very much.
- (void)viewDidLoad {
[super viewDidLoad];
[self registerForKeyboardNotifications];
self.tf.inputAccessoryView = self.keyboardToolbarVw;
}
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
self.sv.contentInset = contentInsets;
self.sv.scrollIndicatorInsets = contentInsets;
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, self.view.frame.origin) ) {
CGPoint scrollPoint = CGPointMake(0.0, self.view.frame.origin.y-kbSize.height);
[self.sv setContentOffset:scrollPoint animated:YES];
}
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.sv.contentInset = contentInsets;
self.sv.scrollIndicatorInsets = contentInsets;
}
- (IBAction)keyboardToolbarDoenBtnAction:(UIButton *)sender {
[self.tf resignFirstResponder];
}
After reviewing you code, it seems problem UIScrollView frames update in - (void)keyboardWasShown:(NSNotification*)aNotification
Instead of doing such manually work on frames, please try IQKeyboardManager
I’ll suggest to use IQKeyboardManager library in all our projects :) It’s a drop-in universal library which allows you to prevent issues of the keyboard sliding up and covering UITextField/UITextView without needing you to writing any code and much more…
In my iOS app, there are almost 10 ViewControllers inside which UITextFields are present.
I implemented functionality of shifting content view upwards when keyboard appears.
https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
This site explains all.
But my problem is that I have to repeat the same code inside every View Controller. Is their any way so that I can write common class or method which works with all my 10 ViewControllers, so that reusability in code can be achieved?
From the apple doc, I have to use following methods. But I am stuck at a place where I have to pass instance of scrollview and active text field (For each view controller, these instances are different) to my common class/method.
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
[self.scrollView scrollRectToVisible:activeField.frame animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
activeField = nil;
}
Create property in base view controller for scrollView and initialize it in viewDidLoad method of each derived view controllers. Also move activeField property to base view controller.
I am working with fully auto-layout.
Last UITextField (end of the view before done button): I set setContentOffset in textFieldDidBeginEditing, it works fine but when I try to scroll (at keyboard shown), UIScrollView is back to normal.
Then text field back to keyboard. Here my code at textFieldDidBeginEditing.
I am using bskeyboardcontroller for next and previous and done button.
[self.scrollviewDetail setContentOffset:CGPointMake(0, 500) animated:YES];
Problem is your Scroll view height on KeyBoard appearance in View, simply you change scroll insects or frame to avoid this problem, if scroll view content offset greater than (content size - scroll view frame size) while scroll it will reset automatically in Scroll view.
Try this code :
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardDidShow:(NSNotification *)notification {
CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardRect = [self.view convertRect:keyboardRect fromView:nil];
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardRect.size.height, 0.0);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
CGRect aRect = self.view.frame;
aRect.size.height -= keyboardRect.size.height;
if (!CGRectContainsPoint(aRect, currentTextField.frame.origin) ) {
[scrollView scrollRectToVisible:currentTextField.frame animated:NO];
}
}
- (void)keyboardDidHide:(NSNotification *)notification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}
I have 10 textfields on tableview that tableview scrolling disabled.
How to handle keyboard avoiding textfields.
The Following is what I have tried with
// Register notification when the keyboard will be show
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardWillShowNotification
object:nil];
// Register notification when the keyboard will be hide
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification
object:nil];
pragma mark - keyboard notification (Called when the UIKeyboardDidShowNotification is sent.)
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
guestRechargeTableView.contentInset = contentInsets;
guestRechargeTableView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, activeField.frame.origin) )
{
[guestRechargeTableView scrollRectToVisible:activeField.frame animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
guestRechargeTableView.contentInset = contentInsets;
guestRechargeTableView.scrollIndicatorInsets = contentInsets;
}
This is working but not proper when selecting on textfield and moves up.Provide solution for that or any other alternative answer..
Happy Coding....
I have a text box in a TableView and when the user selects a switch it appears ( becomes visible) and a keyboard pops up, and when the user turns off the switch the TextBox disappears and keyboard hides. During the time when the keyboard appears and disappears I want to shift the tableView slightly up and then back to original position. Here is the code
-(IBAction)actionSwitch:(id)sender
{
isSearchTerm = [switchSearchTerm isOn];
[self.tableView reloadData];
if(isSearchTerm == YES)
{
[txtSearchTerm becomeFirstResponder];
floatBottom = self.tableView.contentInset.bottom;
self.tableView.contentInset=UIEdgeInsetsMake(0,0,200,0);
[self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForSelectedRow] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
else
{
[txtSearchTerm resignFirstResponder];
self.tableView.contentInset=UIEdgeInsetsMake(0,0,floatBottom,0);
[self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForSelectedRow] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
}
The else part doesn't bring the tableview back to its original position, please help.
If your tableView lies in a navigation controller or the rootViewController of a navigation controller and you are doing all this on iOS7+ with UIViewController's property automaticallyAdjustsScrollViewInsets set to YES. You'd better handle the keyboard appear as the document suggested
// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
[self.scrollView scrollRectToVisible:activeField.frame animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}
There is another way to do this. Both can be found in "Moving Content That Is Located Under the Keyboard" "Text Programming Guide for iOS"
I solved this by setting the extend under top bar property to NO , under view controllers properties in Property inspector by selecting the ViewController.