Thursday, August 9, 2012

Scrolling UIView (UITexField) withrespect to Keyboard

When your UITextFields are  below the middle of device height, it is obvious that the iPhone/iPad keyboard will hide them and we can not see what we are typing.
The following bunch of codes will ensure that the views will be scrolled up when keyboard appears and views will have its original position when keyboard dissapears.  The simple logic for this section is that, we simply play with the vertical origin (origin.y) of UIView and framing it up and down as respect to keyboard appearance.We do include animation effect as well so that the scrolling will look smooth.

1. Lets define some constants :
      static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
      static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
      static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
      static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
      static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;

2. Include textfield delegate in your class <UITextFieldDelegate> and declare variable
            CGFloat animatedDistance;


3. //  When textfield is tapped, the following delegate method will be called and keyboard appears
- (void)textFieldDidBeginEditing:(UITextField *)textField{
         CGRect textFieldRect =  [self.view.window convertRect:textField.bounds fromView:textField];
        CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
         CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
        CGFloat numerator = midline - viewRect.origin.y - MINIMUM_SCROLL_FRACTION  *viewRect.size.height;
        CGFloat denominator = (MAXIMUM_SCROLL_FRACTION -MINIMUM_SCROLL_FRACTION) * viewRect.size.height;
        CGFloat heightFraction = numerator / denominator;
        if (heightFraction < 0.0)
        {
            heightFraction = 0.0;
        }
        else if (heightFraction > 1.0)
        {
            heightFraction = 1.0;
        }
        UIInterfaceOrientation orientation =  [[UIApplication sharedApplication] statusBarOrientation];
        if (orientation == UIInterfaceOrientationPortrait ||
                              orientation == UIInterfaceOrientationPortraitUpsideDown)
        {
            animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
            // floor function returns simply integer value eg: 2.2 it returns 2
        }
        else
        {
            animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
        }
       // getting new y position for UIView
        CGRect viewFrame = self.view.frame;
        viewFrame.origin.y - = animatedDistance;
       // performing smooth animation for scrolling
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
          // assigning new frame for UIView
        [self.view setFrame:viewFrame];
          [UIView commitAnimations];
   }

4. When Return/Done button of Keyboard tapped, following delegate will be called. And we resign the keyboard from here :
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
        [textField resignFirstResponder]; // keyboard will dissapears
        // setting UIView's original frame
        CGRect viewFrame = self.view.frame;
        viewFrame.origin.y += animatedDistance;
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
        [self.view setFrame:viewFrame];
        [UIView commitAnimations];
   
    return YES;
}

No comments:

Post a Comment