Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 420 Vote(s) - 3.44 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How do I scroll the UIScrollView when the keyboard appears?

#1
I'm having trouble with my code. I'm trying to move the `UIScrollView` when I'm editing an `UITextField` that should be hidden by the keyboard pop.

I'm moving the main frame right now because I don't know how to 'scroll up' in the code.
So, I did a little bit of code, it's working fine but when I edit an UItextfield and I switch to another `UITextField` without pressing on the 'return' button the main view goes waaayyyyy to far up.

I did an `NSLog()` with my variables size, distance and textFieldRect.origin.y as you can see below. When I put two `UITextField` at the same place (y origin) and I do this particular 'switch' (wihtout pressing return) , I get the same numbers, whereas my code worked fine for the first `UITextField` editing but not for the second editing.

Check this out:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
{
int size;
CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
size = textFieldRect.origin.y + textFieldRect.size.height;
if (change == FALSE)
{
size = size - distance;
}
if (size < PORTRAIT_KEYBOARD_HEIGHT)
{
distance = 0;
}
else if (size > PORTRAIT_KEYBOARD_HEIGHT)
{
distance = size - PORTRAIT_KEYBOARD_HEIGHT + 5; // +5 px for more visibility
}
NSLog(@"origin %f", textFieldRect.origin.y);
NSLog(@"size %d", size);
NSLog(@"distance %d", distance);
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= distance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
change = FALSE;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
change = TRUE;
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += distance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}

Any ideas ?
Reply

#2
This is what I've been using. It's simple and it works well.

#pragma mark - Scrolling

-(void)scrollElement:(UIView *)view toPoint:(float)y
{
CGRect theFrame = view.frame;
float orig_y = theFrame.origin.y;
float diff = y - orig_y;

if (diff < 0)
[self scrollToY:diff];

else
[self scrollToY:0];
}

-(void)scrollToY:(float)y
{
[UIView animateWithDuration:0.3f animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
self.view.transform = CGAffineTransformMakeTranslation(0, y);
}];
}

Use the `UITextField` delegate call `textFieldDidBeginEditing:` to shift your view upwards, and also add a notification observer to return the view to normal when the keyboard hides:

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

if (self.view.frame.origin.y == 0)
[self scrollToY:-90.0]; // y can be changed to your liking

}

-(void)keyboardWillHide:(NSNotification*)note
{
[self scrollToY:0];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
Reply

#3
You actually don't need a UIScrollView to do this. I used this code and it works for me:

-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{

if (textField==_myTextField)
{
[self keyBoardAppeared];
}
return true;
}

-(void)textFieldDidEndEditing:(UITextField *)textField {
if (textField==_myTextField)
{
[self keyBoardDisappeared];
}
}

-(void) keyBoardAppeared
{
CGRect frame = self.view.frame;

[UIView animateWithDuration:0.3
delay:0
options: UIViewAnimationCurveEaseOut
animations:^{
self.view.frame = CGRectMake(frame.origin.x, frame.origin.y-215, frame.size.width, frame.size.height);
}
completion:^(BOOL finished){

}];
}

-(void) keyBoardDisappeared
{
CGRect frame = self.view.frame;

[UIView animateWithDuration:0.3
delay:0
options: UIViewAnimationCurveEaseOut
animations:^{
self.view.frame = CGRectMake(frame.origin.x, frame.origin.y+215, frame.size.width, frame.size.height);
}
completion:^(BOOL finished){

}];
}
Reply

#4
For this stuff no need to lot's of coding it's very easy like below code:-

your all textfiled in UIScrollview from nib like this image:-

![enter image description here][1]

`YourViewController.h`

@interface cntrInquiryViewController : UIViewController<UIScrollViewDelegate,UITextFieldDelegate>
{
IBOutlet UITextField *txtName;
IBOutlet UITextField *txtEmail;
IBOutlet UIScrollView *srcScrollView;
}
@end

**connect IBOutlet from nib and also Connect each delegate of UItextfiled and scrollview delegate from NIB**

-(void)viewWillAppear:(BOOL)animated
{
srcScrollView.contentSize = CGSizeMake(320, 500);

[super viewWillAppear:YES];
}


-(void)textFieldDidBeginEditing:(FMTextField *)textField
{
[srcScrollView setContentOffset:CGPointMake(0,textField.center.y-140) animated:YES];//you can set your y cordinate as your req also
}

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
[srcScrollView setContentOffset:CGPointMake(0,0) animated:YES];


return YES;
}

**NOTE** if Text-filed delegate not connected then no one method working please insure that all iBOulate and delegate connected correctly


[1]:
Reply

#5
You can scroll by using the property `contentOffset` in `UIScrollView`, e.g.,

CGPoint offset = scrollview.contentOffset;
offset.y -= KEYBOARD_HEIGHT + 5;
scrollview.contentOffset = offset;

There's also a method to do animated scrolling.

As for the reason why your second edit is not scrolling correctly, it could be because you seem to assume that a new keyboard will appear every time editing starts. You could try checking if you've already adjusted for the "keyboard" visible position (and likewise check for keyboard visibility at the moment before reverting it).

A better solution might be to listen for the keyboard notification, e.g.:

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
Reply

#6
The only thing I would update in Apple code is the keyboardWillBeHidden: method, to provide smooth transition.

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;

[UIView animateWithDuration:0.4 animations:^{
self.scrollView.contentInset = contentInsets;
}];
self.scrollView.scrollIndicatorInsets = contentInsets;

}
Reply

#7
I would do that like this. It's a lot of code but it ensures, that the textField currently in focus is is vertically centered in the 'available space':

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

- (void)keyboardWillShow:(NSNotification *)notification {
NSDictionary *info = [notification userInfo];
NSValue *keyBoardEndFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
CGSize keyboardSize = [keyBoardEndFrame CGRectValue].size;
self.keyboardSize = keyboardSize;

[self adjustScrollViewOffsetToCenterTextField:self.currentTextField];
}

- (void)keyboardWillHide:(NSNotification *)notification {
self.keyboardSize = CGSizeZero;
}

- (IBAction)textFieldGotFocus:(UITextField *)sender {
sender.inputAccessoryView = self.keyboardAccessoryView;
self.currentTextField = sender;
[self adjustScrollViewOffsetToCenterTextField:sender];
}

- (void)adjustScrollViewOffsetToCenterTextField:(UITextField *)textField
{
CGRect textFieldFrame = textField.frame;
float keyboardHeight = MIN(self.keyboardSize.width, self.keyboardSize.height);

float visibleScrollViewHeight = self.scrollView.frame.size.height - keyboardHeight;
float offsetInScrollViewCoords = (visibleScrollViewHeight / 2) - (textFieldFrame.size.height / 2);

float scrollViewOffset = textFieldFrame.origin.y - offsetInScrollViewCoords;


[UIView animateWithDuration:.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.scrollView.contentOffset = CGPointMake(self.scrollView.contentOffset.x, scrollViewOffset);
}completion:NULL];

}

you'll need these two properties in your @interface...
@property (nonatomic, assign) CGSize keyboardSize;
@property (nonatomic, strong) UITextField *currentTextField;



Note that the `- (IBAction)textFieldGotFocus:` action is hooked up to the every textField's `DidBeginEditing` state.

Also it would be a little better to get the animation duration from the keyboard notification and use that for the scrollview animation instead of a fixed value, but sue me, this was good enough for me ;)
Reply

#8
All the answers here seem to forget about landscape possibilities. If you would like this to work when the device is rotated to a landscape view, then you will face problems.

The trick here is that although the view is aware of the orientation, the keyboard is not. This means in Landscape, the keyboards width is actually its height and visa versa.

To modify Apples recommended way of changing the content insets and get it support landscape orientation, I would recommend using the following:

// 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
{
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGSize keyboardSize = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight ) {
CGSize origKeySize = keyboardSize;
keyboardSize.height = origKeySize.width;
keyboardSize.width = origKeySize.height;
}
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0);
scroller.contentInset = contentInsets;
scroller.scrollIndicatorInsets = contentInsets;

// If active text field is hidden by keyboard, scroll it so it's visible
// Your application might not need or want this behavior.
CGRect rect = scroller.frame;
rect.size.height -= keyboardSize.height;
NSLog(@"Rect Size Height: %f", rect.size.height);

if (!CGRectContainsPoint(rect, activeField.frame.origin)) {
CGPoint point = CGPointMake(0, activeField.frame.origin.y - keyboardSize.height);
NSLog(@"Point Height: %f", point.y);
[scroller setContentOffset:point animated:YES];
}
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
}


----------


The part to pay attention to here is the following:

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGSize keyboardSize = [[[notif userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight ) {
CGSize origKeySize = keyboardSize;
keyboardSize.height = origKeySize.width;
keyboardSize.width = origKeySize.height;
}
What is does, is detects what orientation the device is in. If it is landscape, it will 'swap' the width and height values of the keyboardSize variable to ensure that the correct values are being used in each orientation.
Reply

#9
I know it's an old question now but i thought it might help others. I wanted something a little easier to implement for a few apps i had, so i made a class for this. You can download it here if you want:

[To see links please register here]


It's as simple as setting all of the UITextFields to have a delegate of self

textfieldname.delegate = self;

And then adding this to your view controller with the name of your scrollView and submit button

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[iOSTextFieldHandler TextboxKeyboardMover:containingScrollView tf:textField btn:btnSubmit];
}
Reply

#10
The following is my solutions which works ( 5 steps )

Step1: Add an observer to catch which UITEXTFIELD or UITEXTVIEW ShoudBeginEditing ( where object is inited or ViewDidLoad.

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateActiveField:)
name:@"UPDATE_ACTIVE_FIELD" object:nil];

Step2: Post a notification when ..ShouldBeginEditing with OBJECT of UITEXTFIELD or UITEXTVIEW

-(BOOL)textViewShouldBeginEditing:(UITextView *)textView {

[[NSNotificationCenter defaultCenter] postNotificationName:@"UPDATE_ACTIVE_FIELD"
object:textView];
return YES;
}

Step3: The method that (Step1 calles ) assigns the current UITEXTFIELD or UITEXTVIEW

-(void) updateActiveField: (id) sender {
activeField = [sender object];
}

Step4: Add Keyboard observer UIKeyboardWillShowNotification ( same place as Step1 )

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
and method:

// 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);

_currentEdgeInsets = self.layoutPanel.contentInset; // store current insets to restore them later
self.layoutPanel.contentInset = contentInsets;
self.layoutPanel.scrollIndicatorInsets = contentInsets;

// If active text field is hidden by keyboard, scroll it so it's visible
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
CGPoint p = [activeField convertPoint:activeField.bounds.origin toView:window];

if (!CGRectContainsPoint(aRect, p) ) {
CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y +kbSize.height);
[self.layoutPanel setContentOffset:scrollPoint animated:YES];
self.layoutPanel.scrollEnabled = NO;
}
}

Step5: Add Keyboard observer UIKeyboardWillHideNotification ( same place as step 1 )

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
and method:

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
self.layoutPanel.contentInset = _currentEdgeInsets;
self.layoutPanel.scrollIndicatorInsets = _currentEdgeInsets;
self.layoutPanel.scrollEnabled = YES;
}

Remember to remove observers!


Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through