54

我目前正在开发一个具有单个视图的 iPhone 应用程序,该应用程序有多个 UITextFields 用于输入。当键盘显示时,它会覆盖底部的文本字段。所以我添加了相应的textFieldDidBeginEditing:方法,将视图向上移动,效果很好:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    if ( ( textField != inputAmount ) && ( textField != inputAge ) ) {
        NSTimeInterval animationDuration = 0.300000011920929;
        CGRect frame = self.view.frame;
        frame.origin.y -= kOFFSET_FOR_KEYBOARD;
        frame.size.height += kOFFSET_FOR_KEYBOARD;
        [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
        [UIView setAnimationDuration:animationDuration];
        self.view.frame = frame;
        [UIView commitAnimations];      
    }
}

此方法检查消息的来源是否是键盘显示时可见的文本字段之一,如果不是,则向上移动视图。

我还添加了该textFieldDidEndEnditing:方法,它再次向下移动视图(并根据更改的输入更新一些模型对象):

- (void)textFieldDidEndEditing:(UITextField *)textField {
    if ( ( textField != inputMenge ) && ( textField != inputAlter ) ) {
        NSTimeInterval animationDuration = 0.300000011920929;
        CGRect frame = self.view.frame;
        frame.origin.y += kOFFSET_FOR_KEYBOARD;
        frame.size.height -= kOFFSET_FOR_KEYBOARD;
        [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
        [UIView setAnimationDuration:animationDuration];
        self.view.frame = frame;
        [UIView commitAnimations];      
    }
    // Additional Code
}

然而,这个解决方案有一个简单的缺陷:当我完成编辑一个“隐藏”文本字段并触摸另一个文本字段时,键盘消失,视图向下移动,视图再次向上移动,键盘重新出现。

是否有可能防止键盘在两次编辑(“隐藏”文本字段的)之间消失和重新出现 - 以便仅当所选文本字段从键盘隐藏的文本字段更改为不会隐藏的文本字段时,视图才会移动)?

4

7 回答 7

47

该解决方案基于 ComSubVie 的解决方案。

好处:

  • 它支持设备旋转 - 适用于所有方向;
  • 它不会对动画持续时间和曲线的值进行硬编码,而是从键盘通知中读取它们;
  • 它利用UIKeyboardWillShowNotification而不是UIKeyboardDidShowNotification同步键盘动画和自定义动作;
  • 它不使用已弃用的UIKeyboardBoundsUserInfoKey;
  • 它处理由于按下国际键而导致的键盘大小调整;
  • 通过取消注册键盘事件来修复内存泄漏;
  • 所有键盘处理代码都封装在一个单独的类中 - KBKeyboardHandler;
  • 灵活性——KBKeyboardHandler类可以很容易地扩展/修改以更好地满足特定需求;

限制:

  • 适用于 iOS 4 及更高版本,需要稍作修改以支持旧版本;
  • 它适用于具有单个UIWindow. 如果您使用多个 UIWindows,您可能需要修改retrieveFrameFromNotification:方法。

用法:

在您的项目中包含 KBKeyboardHandler.h、KBKeyboardHandler.m 和 KBKeyboardHandlerDelegate.h。在您的视图控制器中实现该KBKeyboardHandlerDelegate协议 - 它由一个方法组成,当键盘显示、隐藏或更改其大小时将调用该方法。实例化KBKeyboardHandler并设置它的委托(通常是自己)。请参阅下面的示例MyViewController

KBKeyboardHandler.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@protocol KBKeyboardHandlerDelegate;

@interface KBKeyboardHandler : NSObject

- (id)init;

// Put 'weak' instead of 'assign' if you use ARC
@property(nonatomic, assign) id<KBKeyboardHandlerDelegate> delegate; 
@property(nonatomic) CGRect frame;

@end

KBKeyboardHandler.m

#import "KBKeyboardHandler.h"
#import "KBKeyboardHandlerDelegate.h"

@implementation KBKeyboardHandler

- (id)init
{
    self = [super init];
    if (self)
    {
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillShow:)
                                                     name:UIKeyboardWillShowNotification
                                                   object:nil];

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

    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super dealloc];
}

@synthesize delegate;
@synthesize frame;

- (void)keyboardWillShow:(NSNotification *)notification
{
    CGRect oldFrame = self.frame;    
    [self retrieveFrameFromNotification:notification];

    if (oldFrame.size.height != self.frame.size.height)
    {
        CGSize delta = CGSizeMake(self.frame.size.width - oldFrame.size.width,
                                  self.frame.size.height - oldFrame.size.height);
        if (self.delegate)
            [self notifySizeChanged:delta notification:notification];
    }
}

- (void)keyboardWillHide:(NSNotification *)notification
{
    if (self.frame.size.height > 0.0)
    {
        [self retrieveFrameFromNotification:notification];
        CGSize delta = CGSizeMake(-self.frame.size.width, -self.frame.size.height);

        if (self.delegate)
            [self notifySizeChanged:delta notification:notification];
    }

    self.frame = CGRectZero;
}

- (void)retrieveFrameFromNotification:(NSNotification *)notification
{
    CGRect keyboardRect;
    [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardRect];
    self.frame = [[UIApplication sharedApplication].keyWindow.rootViewController.view convertRect:keyboardRect fromView:nil];
}

- (void)notifySizeChanged:(CGSize)delta notification:(NSNotification *)notification
{
    NSDictionary *info = [notification userInfo];

    UIViewAnimationOptions curve;
    [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&curve];

    NSTimeInterval duration;
    [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&duration];

    void (^action)(void) = ^{
        [self.delegate keyboardSizeChanged:delta];
    };

    [UIView animateWithDuration:duration
                          delay:0.0
                        options:curve
                     animations:action
                     completion:nil];    
}

@end

KBKeyboardHandlerDelegate.h

@protocol KBKeyboardHandlerDelegate

- (void)keyboardSizeChanged:(CGSize)delta;

@end

示例MyViewController.h

@interface MyViewController : UIViewController<KBKeyboardHandlerDelegate>
...
@end

示例MyViewController.m

@implementation MyViewController
{
    KBKeyboardHandler *keyboard;
}

- (void)dealloc
{
    keyboard.delegate = nil;
    [keyboard release];
    [super dealloc];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    keyboard = [[KBKeyboardHandler alloc] init];
    keyboard.delegate = self;
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    keyboard.delegate = nil;
    [keyboard release];
    keyboard = nil;
}

- (void)keyboardSizeChanged:(CGSize)delta
{
    // Resize / reposition your views here. All actions performed here 
    // will appear animated.
    // delta is the difference between the previous size of the keyboard 
    // and the new one.
    // For instance when the keyboard is shown, 
    // delta may has width=768, height=264,
    // when the keyboard is hidden: width=-768, height=-264.
    // Use keyboard.frame.size to get the real keyboard size.

    // Sample:
    CGRect frame = self.view.frame;
    frame.size.height -= delta.height;
    self.view.frame = frame;
}

更新:修复了 iOS 7 警告,感谢@weienv。

于 2012-09-13T09:01:17.270 回答
29

我刚刚解决了这个问题。解决方案是aUIKeyboardDidShowNotificationUIKeyboardDidHideNotificationobserver与上述textFieldDidBeginEditing:textFieldDidEndEditing:方法的组合。

您需要三个附加变量,一个用于存储当前选定的 UITextField(我将其命名为 activeField),一个用于指示当前视图是否已移动,一个用于指示是否显示键盘。

这是两个UITextField委托方法现在的样子:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    activeField = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    activeField = nil;
    // Additional Code
}

加载视图时,会创建以下两个观察者:

- (void)viewDidLoad {
    // Additional Code
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasShown:)
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWasHidden:)
                                                 name:UIKeyboardDidHideNotification
                                               object:nil];
}

并且对应的方法实现如下:

- (void)keyboardWasShown:(NSNotification *)aNotification {
    if ( keyboardShown )
        return;

    if ( ( activeField != inputAmount ) && ( activeField != inputAge ) ) {
        NSDictionary *info = [aNotification userInfo];
        NSValue *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
        CGSize keyboardSize = [aValue CGRectValue].size;

        NSTimeInterval animationDuration = 0.300000011920929;
        CGRect frame = self.view.frame;
        frame.origin.y -= keyboardSize.height-44;
        frame.size.height += keyboardSize.height-44;
        [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
        [UIView setAnimationDuration:animationDuration];
        self.view.frame = frame;
        [UIView commitAnimations];

        viewMoved = YES;
    }

    keyboardShown = YES;
}

- (void)keyboardWasHidden:(NSNotification *)aNotification {
    if ( viewMoved ) {
        NSDictionary *info = [aNotification userInfo];
        NSValue *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
        CGSize keyboardSize = [aValue CGRectValue].size;

        NSTimeInterval animationDuration = 0.300000011920929;
        CGRect frame = self.view.frame;
        frame.origin.y += keyboardSize.height-44;
        frame.size.height -= keyboardSize.height-44;
        [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
        [UIView setAnimationDuration:animationDuration];
        self.view.frame = frame;
        [UIView commitAnimations];

        viewMoved = NO;
    }

    keyboardShown = NO;
}

此代码现在按预期工作。仅当按下 Done 按钮时键盘才会关闭,否则它会保持可见并且视图不会四处移动。

作为附加说明,我认为可以animationDuration通过询问NSNotification对象来动态获取,因为我已经使用过类似的解决方案但没有让它工作(现在它可以工作)。

于 2009-11-21T16:22:20.417 回答
2

此视图控制器必须是UITextViewDelegate 并且您必须self.textview.delegate = selfviewdidload

 -(void) textViewDidBeginEditing:(UITextView *)textView
    {
        NSLog(@"%f",self.view.frame.origin.y);
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.25f];
        CGRect frame = self.view.frame;
        frame.origin.y =frame.origin.y -204;
        [self.view setFrame:frame];
        [UIView commitAnimations];
    }

-(void) textViewDidEndEditing:(UITextView *)textView
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.25f];
    CGRect frame = self.view.frame;
    frame.origin.y = frame.origin.y + 204;
    [self.view setFrame:frame];
    [UIView commitAnimations];
}
于 2013-07-03T23:47:20.563 回答
0

我得到了你的问题只是做简单的事情只是给 UIScrollview 出路。为视图中的每个文本字段设置唯一的 Tag 属性。

-(void)textFieldDidBeginEditing:(UITextField *)textField
    {   
        switch (textField.tag)
        {
            case 2:    //can be your textfiled tag
              { CGPoint scrollPoint = CGPointMake(0, yourtextfield.frame.origin.y-150); 
                                           //set figure y-150 as per your comfirt
                  [scrollview setContentOffset:scrollPoint animated:YES]; 
             }break;

              case 3:   
              { CGPoint scrollPoint = CGPointMake(0, yourtextfield.frame.origin.y-180); 
                                           //set figure y-180 as per your comfirt
                  [scrollview setContentOffset:scrollPoint animated:YES]; 
             }break;

             ...

         }
    }

    -(void)textFieldDidEndEditing:(UITextField *)textField{

        if(textField.tag==3){
            [scrollview setContentOffset:CGPointZero animated:YES];
                }
         //set the last textfield when you want to disappear keyboard.
    }
于 2013-09-04T05:45:34.797 回答
0
Write below code in your view controller. tbl is your table view. 

-(void)viewWillAppear:(BOOL)animated{


    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
    [[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
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}



#pragma mark - Keyboard Methods
-(void)keyboardWillShow:(NSNotification *)notification
{
//    375 × 667  ( 750 × 1334 ) iPhone 6
    //414 × 736
    CGRect keyboardRect = [[[notification userInfo] valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    int H = [[UIScreen mainScreen] bounds].size.height - 64- 20 -keyboardRect.size.height;
    [UIView animateWithDuration:0.5 animations:^{
        tbl.contentInset = UIEdgeInsetsMake(tbl.contentInset.top, tbl.contentInset.left, H, tbl.contentInset.right);
    }];
}

-(void)keyboardWillChangeFrame:(NSNotification *)notification
{
    CGRect keyboardRect = [[[notification userInfo] valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
//    int H = IS_IPHONE_5?504-keyboardRect.size.height:416-keyboardRect.size.height;
     int H = [[UIScreen mainScreen] bounds].size.height - 64- 20  -keyboardRect.size.height;
    [UIView animateWithDuration:0.5 animations:^{
        //        scroll.frame = rect;
        tbl.contentInset = UIEdgeInsetsMake(tbl.contentInset.top, tbl.contentInset.left, H, tbl.contentInset.right);
    }];
}


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

    [UIView animateWithDuration:0.3 animations:^{
        //        scroll.frame = rect;
        tbl.contentInset = UIEdgeInsetsMake(tbl.contentInset.top, tbl.contentInset.left, 0, tbl.contentInset.right);
    }];
}
于 2015-01-08T05:43:04.480 回答
0

相当简单的解决方案,适用于所有屏幕尺寸

首先,您必须将 UITextFields 嵌入到 UIScrollView。就我而言,我有几个 UITextField 和一个 UITextView。

在此处输入图像描述

那么就得继承自UITextFieldDelegate,UITextViewDelegate。

class SettingsVC: UIViewController, UITextFieldDelegate, UITextViewDelegate

将 textfield 和 textview 的委托分配给 self.

fullNameTextField.delegate = self usernameTextField.delegate = self websiteTextField.delegate = self profileDescription.delegate = self

然后使用此代码:

var editingTextInput: UIView!


override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    NotificationCenter.default.addObserver(self,
                                           selector: #selector(self.keyboardShown(notification:)),
                                           name: NSNotification.Name.UIKeyboardDidShow,
                                           object: nil)
    

  }
  
    override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardDidShow, object: nil)
  }
  
  func keyboardShown(notification: NSNotification) {
    
    if let infoKey  = notification.userInfo?[UIKeyboardFrameEndUserInfoKey],
      let rawFrame = (infoKey as AnyObject).cgRectValue {
      
      let keyboardFrame = view.convert(rawFrame, to: view)
      let editingTextInputFrame = self.editingTextInput.convert(self.editingTextInput.frame, to: view)

      
      if editingTextInputFrame.maxY > keyboardFrame.minY{
        
        let diff = keyboardFrame.minY - editingTextInputFrame.maxY
        containerScrollView.setContentOffset(CGPoint(x: 0, y: -diff), animated: true)
        
      }
    }
  }
  
  func textFieldDidBeginEditing(_ textField: UITextField) {
    self.editingTextInput = textField
  }
  
  func textViewDidBeginEditing(_ textView: UITextView) {
    self.editingTextInput = textView
  }
  
  func textFieldDidEndEditing(_ textField: UITextField) {
    containerScrollView.setContentOffset(CGPoint.zero, animated: true)
  }
  
  func textViewDidEndEditing(_ textView: UITextView) {
    containerScrollView.setContentOffset(CGPoint.zero, animated: true)
  }

简而言之,您订阅了 UIKeyboardDidShow 通知。当您点击 textField 或 textView 时,将显示键盘并抓住您点击的输入元素的键盘框架和框架。将它们转换为 viewController 的坐标系,并将输入元素的最低点与键盘的最高点进行比较。如果元素的下部低于键盘的最高点,则将 containerScrollView 的偏移量设置为它们之间的差异。

if editingTextInputFrame.maxY > keyboardFrame.minY{
            
            let diff = keyboardFrame.minY - editingTextInputFrame.maxY
            containerScrollView.setContentOffset(CGPoint(x: 0, y: -diff), animated: true)
            
          }

资源1 资源2

于 2017-05-05T10:03:26.827 回答
0

就像我在这个答案中提到的那样:

我已经根据自己的需要开发了一个框架来更好地解决这个问题,并现在将其公开。它不仅适用于 UITextField 和 UITextView,它适用于任何采用 UITextInput 协议的自定义 UIView,如 UITextField 和 UITextView,并提供许多有用的功能。你可以通过 Carthage、CocoaPods 或 Swift Package Manager 安装它。

ODScrollView GitHub

ODScrollView 中

ODScrollView 只是一个 UIScrollView,它可以根据键盘可见性自动垂直移动 UITextField 和 UITextView 等可编辑文本区域,以提供更好的用户体验。

特征

  • 当键盘出现/消失时,自动向上/向下移动采用 UITextInput 协议的第一响应者 UIView,例如 UITextField、UITextView、UISearchTextField 或任何采用 UITextInput 协议的自定义 UIView。
    • 请注意,如果 UITextInput 的框架不适合 ODScrollView 和键盘之间的剩余区域,则 ODScrollView 会根据光标位置而不是框架调整 UITextInput。在这种情况下,可以使用“trackTextInputCursor”功能。例子
  • 可以为每个 UITextInput 单独应用调整边距,用于 .Top 和 .Bottom 调整方向设置。默认为 20 CGFloat。

  • 可以单独为每个 UITextInput 启用/禁用调整。默认情况下为真。

  • 调整方向 - .Top、.Center、.Bottom - 可以分别应用于每个 UITextInput。.底部默认。例子

  • 调整选项决定了 ODScrollView 如何调整。.始终默认。
    • .Always :ODScrollView 始终调整放置在 ODScrollView 中任何位置的 UITextInput,无论 UITextInput 是否与显示的键盘重叠。例子
    • .IfNeeded :ODScrollView 仅在 UITextInput 与显示的键盘重叠时才调整它。例子
  • 除了 UIScrollView.keyboardDismissModes 之外,还可以通过点击 ODScrollViewDelegate 提供的 UIView 来关闭键盘。键盘关闭后,ODScrollView 可以返回原来的位置。默认情况下为 nil 和 false。例子

用法

1 -您需要做的第一件事是正确设置 ODScrollView 及其内容视图。由于 ODScrollView 只是一个 UIScrollView,因此您可以以与 UIScrollView 相同的方式实现 ODScrollView。您可以使用情节提要或以编程方式创建 ODScrollView。

如果您以编程方式创建 ODScrollView,则可以从步骤 4 继续。

在 Storyboard 中创建 UIScrollView 的建议方法

- If you are using Content Layout Guide and Frame Layout Guide:
    1.1 - scrollView: Place UIScrollView anywhere you want to use.  
    1.2 - contentView: Place UIView inside scrollView.
    1.3 - Set contentView's top, bottom, leading and trailing constraints to Content Layout Guide's constraints.
    1.4 - Set contentView's width equal to Frame Layout Guide's width.
    1.5 - Set contentView's height equal to Frame Layout Guide's height or set static height which is larger than scrollView's height.
    1.6 - Build your UI inside contentView.

- If you are NOT using Content Layout Guide and Frame Layout Guide:
    1.1 - scrollView: Place UIScrollView anywhere you want to use.  
    1.2 - contentView: Place UIView inside scrollView.
    1.3 - Set contentView's top, bottom, leading and trailing constraints to 0.
    1.4 - Set contentView's width equal to scrollView's width.
    1.5 - Set contentView's height equal to scrollView's superview's height or set static height which is larger than scrollView's height.
    1.6 - Build your UI inside contentView.

2 -在 Storyboard 的身份检查器中将滚动视图的类从 UIScrollView 更改为 ODScrollView。

3 -在 ViewController 上为 scrollView 和 contentView 创建 IBOutlets。

4 -在 ViewController 上的 ViewDidLoad() 中调用以下方法:

override func viewDidLoad() {
    super.viewDidLoad()

    //ODScrollView setup
    scrollView.registerContentView(contentView)
    scrollView.odScrollViewDelegate = self
}  

5 -可选:您仍然可以使用 UIScrollView 的功能:

override func viewDidLoad() {
    super.viewDidLoad()

    //ODScrollView setup
    scrollView.registerContentView(contentView)
    scrollView.odScrollViewDelegate = self

    // UIScrollView setup
    scrollView.delegate = self // UIScrollView Delegate
    scrollView.keyboardDismissMode = .onDrag // UIScrollView keyboardDismissMode. Default is .none.

    UITextView_inside_contentView.delegate = self
}

6 -采用 ViewController 中的 ODScrollViewDelegate 并决定 ODScrollView 选项:

extension ViewController: ODScrollViewDelegate {

    // MARK:- State Notifiers: are responsible for notifiying ViewController about what is going on while adjusting. You don't have to do anything if you don't need them.

    // #Optional
    // Notifies when the keyboard showed.
    func keyboardDidShow(by scrollView: ODScrollView) {}

    // #Optional
    // Notifies before the UIScrollView adjustment.
    func scrollAdjustmentWillBegin(by scrollView: ODScrollView) {}

    // #Optional
    // Notifies after the UIScrollView adjustment.
    func scrollAdjustmentDidEnd(by scrollView: ODScrollView) {}

    // #Optional
    // Notifies when the keyboard hid.
    func keyboardDidHide(by scrollView: ODScrollView) {}

    // MARK:- Adjustment Settings

    // #Optional
    // Specifies the margin between UITextInput and ODScrollView's top or bottom constraint depending on AdjustmentDirection
    func adjustmentMargin(for textInput: UITextInput, inside scrollView: ODScrollView) -> CGFloat {
        if let textField = textInput as? UITextField, textField == self.UITextField_inside_contentView {
            return 20
        } else {
            return 40
        }
    }

    // #Optional
    // Specifies that whether adjustment is enabled or not for each UITextInput seperately.
    func adjustmentEnabled(for textInput: UITextInput, inside scrollView: ODScrollView) -> Bool {
        if let textField = textInput as? UITextField, textField == self.UITextField_inside_contentView {
            return true
        } else {
            return false
        }
    }


    // Specifies adjustment direction for each UITextInput. It means that  some of UITextInputs inside ODScrollView can be adjusted to the bottom, while others can be adjusted to center or top.
    func adjustmentDirection(selected textInput: UITextInput, inside scrollView: ODScrollView) -> AdjustmentDirection {
        if let textField = textInput as? UITextField, textField == self.UITextField_inside_contentView {
            return .bottom
        } else {
            return .center
        }
    }

    /**
     - Always : ODScrollView always adjusts the UITextInput which is placed anywhere in the ODScrollView.
     - IfNeeded : ODScrollView only adjusts the UITextInput if it overlaps with the shown keyboard.
     */
    func adjustmentOption(for scrollView: ODScrollView) -> AdjustmentOption {
        .Always
    }

    // MARK: - Hiding Keyboard Settings

    /**
     #Optional

     Provides a view for tap gesture that hides keyboard.

     By default, keyboard can be dismissed by keyboardDismissMode of UIScrollView.

     keyboardDismissMode = .none
     keyboardDismissMode = .onDrag
     keyboardDismissMode = .interactive

     Beside above settings:

     - Returning UIView from this, lets you to hide the keyboard by tapping the UIView you provide, and also be able to use isResettingAdjustmentEnabled(for scrollView: ODScrollView) setting.

     - If you return nil instead of UIView object, It means that hiding the keyboard by tapping is disabled.
     */
    func hideKeyboardByTappingToView(for scrollView: ODScrollView) -> UIView? {
        self.view
    }

    /**
     #Optional

     Resets the scroll view offset - which is adjusted before - to beginning its position after keyboard hid by tapping to the provided UIView via hideKeyboardByTappingToView.

     ## IMPORTANT:
     This feature requires a UIView that is provided by hideKeyboardByTappingToView().
     */
    func isResettingAdjustmentEnabled(for scrollView: ODScrollView) -> Bool {
        true
    }
}

7 -可选:在输入多行 UITextInput 时,当光标与键盘重叠时,您可以调整 ODScrollView。trackTextInputCursor(for UITextInput) 必须由键入时触发的 UITextInput 函数调用。

/**
## IMPORTANT:
This feature is not going to work unless textView is subView of _ODScrollView
*/
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
       _ODScrollView.trackTextInputCursor(for textView)
   return true
}
于 2020-05-01T13:48:52.983 回答