简体   繁体   English

键盘重叠时向上移动UITextField

[英]Move UITextField up when keyboard is overlapped

There is a subView presented on top of ViewA. 在ViewA顶部有一个subView。 Please find the screen layout below. 请在下面找到屏幕布局。 When keyboard is shown on selecting UITextField even if its not overlapping with UITextField the view is scrolled up. 当选择UITextField时显示键盘时,即使它不与UITextField重叠,视图也会向上滚动。

ViewA
  -> UIButton

subView
  -> UIScrollView
        -> UITextField
        -> UITextField


   ViewA
 -----------
|           |
|           |
|  Button   |
|           |
|           |
 -----------

   subView
 --------------
|              |
|              |
|  UITextField |
|  UITextField |
|              |
 --------------

I have registered keyboard notification 我已经注册了键盘通知

    - (void) viewWillAppear:(BOOL)animated {

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

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


- (void) keyboardDidShow:(NSNotification *)notification {

            NSDictionary* info = [notification userInfo];
            CGRect kbRect = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];

            UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbRect.size.height, 0.0);
            self.scrollViewIb.contentInset = contentInsets;
            self.scrollViewIb.scrollIndicatorInsets = contentInsets;

            CGRect aRect = self.viewSelf.frame;
            aRect.size.height -= kbRect.size.height;
            CGRect frame = [self.viewSelf convertRect:self.activeField.frame toView:self.viewSelf.superview];
            if (!CGRectContainsPoint(aRect, frame.origin) ) {
                [self.scrollViewIb scrollRectToVisible:self.activeField.frame animated:YES];
            }
    }

- (void) keyboardWillBeHidden:(NSNotification *)notification {

        self.scrollViewIb.scrollEnabled = true;

        UIEdgeInsets contentInsets = UIEdgeInsetsZero;
        self.scrollViewIb.scrollIndicatorInsets = contentInsets;
        [self.scrollViewIb setContentOffset:CGPointZero animated:false];

}

There's a minor mistake in the coordinate system conversion: convertRect:toView: converts from the coordinate system of the receiver to the coordinates of the passed view. 坐标系转换中有一个小错误: convertRect:toView:接收者的坐标系转换为传递的视图的坐标。

If self.activeField.frame is a rectangle in the coordinate system of self.scrollViewIb as the code implies, then the conversion should go like this... 如果self.activeField.frameself.activeField.frame坐标系中的self.scrollViewIb如代码所示),则转换应像这样...

    CGRect frame = [self.scrollViewIb convertRect:self.activeField.frame toView:self.view];

Notice that I also suggest changing self.viewSelf.superview to self.view . 注意,我还建议将self.viewSelf.superview更改为self.view If this code is running in the view controller that contains all of these subviews, then self.view should be sufficient and correct. 如果此代码在包含所有这些子视图的视图控制器中运行,则self.view应该足够且正确。

I think the problem is that you are always scrolling up, no matter if the keyboard overlaps your textfield or not. 我认为问题在于,无论键盘是否与文本字段重叠,您始终在向上滚动。

You would have to get the frame of the textfield, calculate the distance to the bottom of the screen and check if the keyboard height (plus possible toolbar on top of it) would overlap your textfield and only then scroll up. 您将必须获取文本框的框架,计算到屏幕底部的距离,并检查键盘高度(加上其顶部可能的工具栏)是否与文本框重叠,然后才向上滚动。

Anyways, I personally gave up on implementing scroll up behavior again and again. 无论如何,我个人放弃了一次又一次地实现滚动行为。 I now switched to using IQKeyboardManager. 我现在切换到使用IQKeyboardManager。 Simply install it as a Pod in your project and call IQKeyboardManager.sharedManager().enable = true in application(didFinishLaunchingWithOptions) and you are all set. 只需将其作为Pod安装在您的项目中,然后在application(didFinishLaunchingWithOptions)中调用IQKeyboardManager.sharedManager().enable = true

You even get a toolbar with next/previous and done button for free. 您甚至可以免费获得带有下一个/上一个和完成按钮的工具栏。

Don't get worry when we are in the world with the lots of open libraries. 当我们拥有许多开放的图书馆时,请不要担心。

Use KeyboardLib Lib by adding it to code or by the pod. 通过将KeyboardLib Lib添加到代码或容器中来使用它。

Just build it . 只是建立它 On every Keyboard open that will show option for the Next, previous arrow with the Done button. 在每个打开的键盘上,将显示带有“完成”按钮的下一个,上一个箭头的选项。 Zero line of code with automatic event handling. 具有自动事件处理功能的零代码行

May be this one will solve the issue and a solution for the app betterment. 可能这将解决问题并为改善应用程序提供解决方案。

*Add this in your Controller or the other way is to create a category on UITextField. If you are creating a category on UITextfield just call below methods in delegate methods of UITextField. 


            static CGFloat  const  MINIMUM_SCROLL_FRACTION = 0.4;
            static CGFloat  const  MAXIMUM_SCROLL_FRACTION = 0.8;
            static CGFloat  const  PORTRAIT_KEYBOARD_HEIGHT = 185;
            static CGFloat  const  PORTRAIT_KEYBOARD_HEIGHT1 = 230;
            static CGFloat  const  LANDSCAPE_KEYBOARD_HEIGHT = 140;
            static CGFloat  const  KEYBOARD_ANIMATION_DURATION = 0.3;

    - (void)textFieldDidBeginEditing:(UITextField *)textField view:(UIView *)view{

          CGRect textFieldRect = [view.window convertRect:textField.bounds fromView:textField];

          CGRect viewRect = [view.window convertRect:view.bounds fromView: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([[ UIScreen mainScreen ] bounds ].size.height == 568)
                        {
                            if (orientation == UIInterfaceOrientationPortrait ||
                                orientation == UIInterfaceOrientationPortraitUpsideDown)
                            {
                                animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
                            }
                            else
                            {
                                animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
                            }
                        }
                        else{
                            if (orientation == UIInterfaceOrientationPortrait ||
                                orientation == UIInterfaceOrientationPortraitUpsideDown)
                            {
                                animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction + 23);
                            }
                            else
                            {
                                animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction + 23);
                            }
                        }

                        CGRect viewFrame = view.frame;
                        viewFrame.origin.y -= animatedDistance;
                        [UIView beginAnimations:nil context:NULL];
                        [UIView setAnimationBeginsFromCurrentState:YES];
                        [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
                        [view setFrame:viewFrame];
                        [UIView commitAnimations];

}

- (void)textFieldDidEndEditing:(UITextField *)textField view:(UIView *)view 

CGRect viewFrame = view.frame;
         viewFrame.origin.y += animatedDistance;
                        [UIView beginAnimations:nil context:NULL];
                        [UIView setAnimationBeginsFromCur rentState:YES];
                        [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
                        [view setFrame:viewFrame];
                        [UIView commitAnimations];
                    }*

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM