How to move bottom textFields up when key board appears? - ios

fields in my view, i want to move my text-view up when keyboard appears when i started entering text in 6th, 7th, 8th. text-Fields only.

I tried solution for you question and I simply got.
#define kOFFSET_FOR_KEYBOARD 80.0
#interface ViewController ()
{
NSInteger tagTF;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)setMovedUp:(BOOL)movedUP
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = self.view.frame;
if(movedUP)
{
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
}
else{
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
self.view.frame = rect;
[UIView commitAnimations];
}
#pragma mark - UITextFieldDelegate Methods
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
tagTF = textField.tag;
if(textField.tag>=6)
{
if(self.view.frame.origin.y >= 0)
{
[self setMovedUp:YES];
}
}
return YES;
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
if(textField.tag>=6)
{
[self setMovedUp:NO];
}
[textField resignFirstResponder];
return YES;
}
From my above answer I set the textField tag from 1 to 8.It works perfectly what you want.Please set the delegate for textField.

I have an extensive blog post explaining how to do this:
Shifting views to make room for the keyboard
The gist of it is that you add notification handlers for the keyboard will show and keyboard will hide notifications. In those handlers, you get the height of the keyboard, then do some math to figure out how much you need to move the field up so the keyboard doesn't cover it. You then move your view controller's view up just enough to keep the field exposed.
It gets more complicated than that, but that's all covered in the blog post (which is part of a larger blog post on animating random shapes that includes a working example of the keyboard technique.)

here is the official documentation by Apple regarding handling the keyboard.

There are lots of options for that.
I was using TPKeyboardAvoidingScrollView for a long time. Right now, i am using IQKeyboardManager much more simple and easy to integrate.
IQKeyboardManager

- (BOOL) textFieldShouldBeginEditing:(UITextField *)textField {
CGRect frame = self.view.frame;
Float y = frame.origin.y - 70;
frame.origin.y = y;
self.view.frame = frame;
return YES;
}
- (void) textFieldDidEndEditing:(UITextField *)textField{
CGRect frame = self.view.frame;
Float y = frame.origin.y + 70;
frame.origin.y = y;
self.view.frame = frame;
}
if you have change y value(like 70, 80, ...)in textFieldShouldBeginEditing method, and add same value to y in textFieldDidEndEditing method.
try this code.

Related

How can I perform a check on all check UITextField's in if condition

I have been looking out for solutions but haven't found one so far, please refer to the answer to this, i want to know if there is a way i can perform the check on all UITextFields, instead of having a hard coded value, thanks for help.
first your make sure that all textField have their delegate set to self ( means your viewController)
Ex. [myTextField setDelegate:self];// you can also set the delegate in Storyboard or xib directly
Then add a instance variable in your class implementation like -
#implementation myViewController
{
UITextField *activeField;
}
and then simply implement the method as below
in your textFieldShouldBeginEditing, set activeField
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
activeField = textField; // HERE get reference of your active field
return true;
}
There is a very nice method provided for all handling
CGRectContainsRect
if (!CGRectContainsRect(viewableAreaFrame, activeTextFieldFrame))
{
/*Scroll or move view up*/
}
Implement below in your keyboardWillShow method
EX.
- (void)keyboardWillShow:(NSNotification *)notification
{
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
float viewWidth = self.view.frame.size.width;
float viewHeight = self.view.frame.size.height;
CGRect viewableAreaFrame = CGRectMake(0.0, 0.0, viewWidth, viewHeight - keyboardHeight);
CGRect activeTextFieldFrame = [activeTextField frame];
if (!CGRectContainsRect(viewableAreaFrame, activeTextFieldFrame))
{
/*Scroll or move view up*/
[UIView animateWithDuration:0.3 animations:^{
CGRect f = self.view.frame;
f.origin.y = -keyboardSize.height;
self.view.frame = f;
}];
}
}

Why view moves down while displaying keyboard?

I have a tab controller based app, where I have a uitextview on selecting which I m moving view up as keyboard appears , the entire thing works well until I switch tab , when I come back to this tab and try editing in uitextview view moves down and then back to normal position on keyboard appearing instead of moving up . here is the entire code
- (void)textViewDidBeginEditing:(UITextView *)textField
{
[self keyboardWillShow];
}
-(void)textViewDidEndEditing:(UITextView *)textField
{
[self keyboardWillHide];
}
-(void)keyboardWillShow {
// Animate the current view out of the way
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
-(void)keyboardWillHide {
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5]; // if you want to slide up the view
CGRect rect = self.view.frame;
if (movedUp)
{
// 1. move the view's origin up so that the text field that will be hidden come above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
}
else
{
// revert back to the normal state.
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
self.view.frame = rect;
[UIView commitAnimations];
}
Well I had similar issues and figured it out. You can check my recent post:
https://stackoverflow.com/a/28177645/2989374

How to create animation for UIview that needs to pull down to up?

I want to create a screen to pull up from down and need to pull down.like iOS notifications screen (but in reverse direction).Please share if any example is there.Thanks in advance.
The full-on way to do this in iOS 7 is with an interactive custom transition. You will use a UIScreenEdgePanGestureRecognizer and respond to the drag gesture from the edge of the screen by performing part of the transition animation to match the distance the user's finger has travelled. Look into the UIPercentDrivenInteractiveTransition class to help you do that.
Here's a complete example you can download and run: it happens that I'm doing it from the left or right, not the top or bottom, but it is the same basic idea.
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch06p296customAnimation2/ch19p620customAnimation1/AppDelegate.m
But beware: if you try to do it from the top or the bottom you will get interference from the notification center (top) and the control center (bottom). It can be tricky to prevent that interference.
Hi you can use it.
- (void)showShareView {
[self.view bringSubviewToFront:self.view_Email];
[UIView beginAnimations:#"Show"
context:nil];
[UIView setAnimationDuration:0.3F];
CGRect frame = self.view_Email.frame;
if (IS_IPHONE5) {
if(txtFieldActiveFlag==1){
frame.origin.y = 568-420;
}else{
frame.origin.y = 568-220;
}
} else {
frame.origin.y = 480 - 275 - 88;
}
self.view_Email.frame = frame;
[UIView commitAnimations];
}
- (void)hideShareView {
[UIView beginAnimations:#"Show"
context:nil];
[UIView setAnimationDuration:0.3F];
CGRect frame = self.view_Email.frame;
if (IS_IPHONE5) {
if(txtFieldActiveFlag==2){
frame.origin.y = 568-220;
}else{
frame.origin.y = 568;
}
} else {
frame.origin.y = 480;
}
self.view_Email.frame = frame;
[UIView commitAnimations];
}
//call method from any button action.
[self showShareView]; //show the view up
[self hideShareView]; //show the view down
Thanks

How to scroll to a certain point in a UIScrollView

Below I have a line of code that scrolls to a certain point in a UIScrollView. However once it has scrolled there it does not allow me to scroll back up.
[scroller setContentOffset:CGPointMake(0,500) animated:NO];
Any help will be appreciated, thank you.
did you try using UIScrollView method scrollRectToVisible:
Here is an example
- (void)goToPage:(int)page animated:(BOOL)animated
{
CGRect frame;
frame.origin.x = self.scroller.frame.size.width * page;
frame.origin.y = 0;
frame.size = self.scroller.frame.size;
[self.scroller scrollRectToVisible:frame animated:animated];
// update the scroll view to the appropriate page
}
I use this. The button calls this method. Should work well.
- (void)downExecute:(id)sender {
NSLog(#"scroll down");
CGFloat currentOffset = _scrollView.contentOffset.y;
CGFloat newOffset;
newOffset = currentOffset + self.view.bounds.size.height;
[UIScrollView animateWithDuration:0.3 animations:^(void) {
[_scrollView setContentOffset:CGPointMake(0.0, newOffset)];
} completion:^(BOOL finished) {
}];
}
I had this kind of problem because I called this method from viewDidLayoutSubviews(). Check where are you calling it from. When I moved the logic to viewDidAppear() everything worked as expected. Hope it helps, cheers.

Strange behavior when animating UITextField

I'm trying to animate a UITextField but I've been caught by a annoying and strange problem. My animation has the following sequence:
In first state the application has the UITextField, the camera UIButton and the cancel UIButton after the camera button that is not been showed because it is been positioned out of the limits of the application. Actually my application has 320 of width and the cancel button origin is (350,7)
In second state, when user touches on UITextField, the camera button alpha channel is set to 0 and the origin of cancel button is set to (247,7).
The final state is the same as first state after user touched on Return button of keyboard or in cancel button.
During process the UITextField width and the cancel button origin in x axis are animated.
My code is:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
barcodeSearchButton.userInteractionEnabled = NO;
cancelButton.userInteractionEnabled = NO;
CGFloat cancelButtonXOffset = CGRectGetMaxX(barcodeSearchButton.frame) - cancelButton.frame.size.width;
CGFloat searchFieldWidth = searchField.frame.size.width - cancelButton.frame.size.width + barcodeSearchButton.frame.size.width;
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldWidth, searchField.frame.size.height);
cancelButton.alpha = 1.0;
cancelButton.frame = CGRectMake(cancelButtonXOffset, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 0.0;
}
completion:^(BOOL finished) {
barcodeSearchButton.userInteractionEnabled = NO;
cancelButton.userInteractionEnabled = YES;
}];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
barcodeSearchButton.userInteractionEnabled = NO;
cancelButton.userInteractionEnabled = NO;
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldStartWidth, searchField.frame.size.height);
cancelButton.alpha = 0.0;
cancelButton.frame = CGRectMake(cancelButtonStartX, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 1.0;
}
completion:^(BOOL finished) {
barcodeSearchButton.userInteractionEnabled = YES;
cancelButton.userInteractionEnabled = NO;
}];
}
When the animation is executed until the final state ONLY for the first time, which means, user touched on UITextField, WROTE DOWN (this part is important) some text on field and after that the user touched on keyboard return button the problem appears. The problem is that the typed text in UITextField is animated when the width of UITextField is animated too.
The animation behaves like bellow:
The UITextField stretches back to its initial value.
Cancel button backs to its initial origin
Camera button is set to 1.0
The typed text flies from the top-left corner of UITextField and it lands into UITextfield to the position the it should not have gone.
The problem is that the step 4 should not happen and the problem is it happens only one time. If a start the process again (touch on uitextfield, type some text, touch on return key) the step 4 does not happen.
I spend a day long trying to solve this problem but I was unsuccessful.
Thanks for answers of everyone but I've found the solution some time ago. The correct way to start an animation in a UITextField, depending on the keyboard state, is overriding the methods textFieldShouldBeginEditing and textFieldShouldEndEditing.
My first attempt I was overriding textFieldDidBeginEditing and textFieldDidEndEditing to create the animations. I don't know the reason to the animations work in textFieldShouldBeginEditing and textFieldShouldEndEditing but not in textFieldDidBeginEditing and textFieldDidEndEditing. But it just works.
My revised code version:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
CGFloat cancelButtonXOffset = CGRectGetMaxX(barcodeSearchButton.frame) - cancelButton.frame.size.width;
CGFloat searchFieldWidth = searchField.frame.size.width - cancelButton.frame.size.width + barcodeSearchButton.frame.size.width;
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldWidth, searchField.frame.size.height);
cancelButton.alpha = 1.0;
cancelButton.frame = CGRectMake(cancelButtonXOffset, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 0.0;
} completion:^(BOOL finished) {
searchField.clearButtonMode = UITextFieldViewModeAlways;
}];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
[UIView animateWithDuration:0.3
animations:^{
searchField.frame = CGRectMake(searchField.frame.origin.x, searchField.frame.origin.y, searchFieldStartWidth, searchField.frame.size.height);
cancelButton.alpha = 0.0;
cancelButton.frame = CGRectMake(cancelButtonStartX, cancelButton.frame.origin.y, cancelButton.frame.size.width,cancelButton.frame.size.height);
barcodeSearchButton.alpha = 1.0;
} completion:^(BOOL finished) {
searchField.clearButtonMode = UITextFieldViewModeNever;
}];
return YES;
}
Set some placeholder text on the search field,
_searchField.text = #"placeholder"
and also set
_searchField.clearsOnBeginEditing = YES;
Or you can just clear out the value if it's equal to your placeholder text
on textDidBeginEditing
{edited to improve the fix}
I have this exact same problem, and some further details as well as a small hack that is indeed fixing it for me.
So first the further details:
The problem only occurs the first time the frame animation expands
the UITextField and there is entered text in the field. If the
UITextField is edited again, and the same animations happen again,
the problem does not happen.
searchField.clearsOnBeginEditing = YES; does not clear the problem.
I've been using placeholder text the entire time the problem has
been observed. It has no effect on the results.
Changing the text property for 1 frame does have the effect of clearing the problem.
Here is what I am doing to fix it:
In my viewDidLoad I am setting the text property to a single space, then dispatching once an assignment to an empty string.
-(void)viewDidLoad {
searchField.text = #" ";
dispatch_async(dispatch_get_main_queue(), ^{
searchField.text = #"";
});
}
Then in my methods that shrink and expand the UITextField, as well as move a cancel button on-screen, I check if this is an instantaneous animation and set the duration to 0.0f.
- (void)showCancelButton {
NSTimeInterval duration = 0.3f;
[UIView animateWithDuration:duration animations:^{
CGPoint buttonOrigin = cancelButton.frame.origin;
CGSize buttonSize = cancelButton.frame.size;
CGFloat buttonTravelDist = buttonSize.width + 10.0f;
CGPoint onscreenPos = CGPointMake(buttonOrigin.x - buttonTravelDist, buttonOrigin.y);
cancelButton.frame = CGRectMake(onscreenPos.x, onscreenPos.y, buttonSize.width, buttonSize.height);
CGPoint fieldOrigin = searchField.frame.origin;
CGSize fieldSize = searchField.frame.size;
searchField.frame = CGRectMake(fieldOrigin.x, fieldOrigin.y, fieldSize.width - buttonTravelDist, fieldSize.height);
}];
}
- (void)hideCancelButton {
NSTimeInterval duration = 0.3f;
[UIView animateWithDuration:duration animations:^{
CGPoint buttonOrigin = cancelButton.frame.origin;
CGSize buttonSize = cancelButton.frame.size;
CGFloat buttonTravelDist = buttonSize.width + 10.0f;
CGPoint onscreenPos = CGPointMake(buttonOrigin.x + buttonTravelDist, buttonOrigin.y);
cancelButton.frame = CGRectMake(onscreenPos.x, onscreenPos.y, buttonSize.width, buttonSize.height);
CGPoint fieldOrigin = searchField.frame.origin;
CGSize fieldSize = searchField.frame.size;
searchField.frame = CGRectMake(fieldOrigin.x, fieldOrigin.y, fieldSize.width + buttonTravelDist, fieldSize.height);
}];
}
This has completely fixed the situation for me.

Resources