使用iOS SDK:

我有一个带UITextFields的UIView,可以启动键盘。我需要它能够:

启动键盘后,允许滚动UIScrollView的内容以查看其他文本字段自动“跳转”(通过向上滚动)或缩短

我知道我需要一个UIScrollView。我已经尝试将UIView的类更改为UIScrollView,但仍然无法上下滚动文本框。

我需要UIView和UIScrollView吗?一个在另一个里面吗?

要自动滚动到活动文本字段,需要执行哪些操作?

理想情况下,尽可能多的组件设置将在Interface Builder中完成。我只想编写需要的代码。

注意:我使用的UIView(或UIScrollView)是由一个选项卡(UITabBar)启动的,它需要正常工作。


我正在添加滚动条,只为键盘出现时使用。尽管不需要它,但我觉得它提供了一个更好的界面,例如,用户可以滚动和更改文本框。

当键盘上下移动时,我可以改变UIScrollView的框架大小。我只是在使用:

-(void)textFieldDidBeginEditing:(UITextField *)textField {
    //Keyboard becomes visible
    scrollView.frame = CGRectMake(scrollView.frame.origin.x,
                                  scrollView.frame.origin.y,
    scrollView.frame.size.width,
    scrollView.frame.size.height - 215 + 50);   // Resize
}

-(void)textFieldDidEndEditing:(UITextField *)textField {
    // Keyboard will hide
    scrollView.frame = CGRectMake(scrollView.frame.origin.x,
                                  scrollView.frame.origin.y,
                                  scrollView.frame.size.width,
                                  scrollView.frame.size.height + 215 - 50); // Resize
}

然而,这不会自动“向上移动”或将可见区域中的下部文本字段居中,这是我真正想要的。


当前回答

这是我的“仅UITextView扩展”解决方案,基于Paul Hudson@twostraws的解决方案(向他和这里所有类似答案的作者致敬)。

import UIKit

extension UITextView {
    
    func adjustableForKeyboard() {
        let notificationCenter = NotificationCenter.default
        
        notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
        notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
    }
    
    @objc private func adjustForKeyboard(notification: Notification) {
        guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else {
            return
        }

        let keyboardScreenEndFrame = keyboardValue.cgRectValue
        let keyboardViewEndFrame = convert(keyboardScreenEndFrame, from: window)
        
        if notification.name == UIResponder.keyboardWillHideNotification {
            contentInset = .zero
        } else {
            contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height - safeAreaInsets.bottom, right: 0)
        }

        scrollIndicatorInsets = contentInset
        scrollRangeToVisible(selectedRange)
    }
}

用法:

override func viewDidLoad() {
    super.viewDidLoad()
    
    textView.adjustableForKeyboard()
}

其他回答

尝试IQKeyboard库。

这将自动向上移动文本字段。

这段代码将根据键盘高度和文本字段的深度来计算需要向上移动多少。记住在头中添加委托并继承UITextFieldDelegate。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [_tbxUsername resignFirstResponder];
    [_tbxPassword resignFirstResponder];
}

- (void)textFieldDidBeginEditing:(UITextField *) textField
{
    [self animateTextField:textField up:YES];
}

- (void)textFieldDidEndEditing:(UITextField *) textField
{
    [self animateTextField:textField up:NO];
}

- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
    int animatedDistance;
    int moveUpValue = textField.frame.origin.y+ textField.frame.size.height;
    UIInterfaceOrientation orientation =
    [[UIApplication sharedApplication] statusBarOrientation];
    if (orientation == UIInterfaceOrientationPortrait ||
        orientation == UIInterfaceOrientationPortraitUpsideDown)
    {

        animatedDistance = 236-(460-moveUpValue-5);
    }
    else
    {
        animatedDistance = 182-(320-moveUpValue-5);
    }

    if(animatedDistance>0)
    {
        const int movementDistance = animatedDistance;
        const float movementDuration = 0.3f;
        int movement = (up ? -movementDistance : movementDistance);
        [UIView beginAnimations: nil context: nil];
        [UIView setAnimationBeginsFromCurrentState: YES];
        [UIView setAnimationDuration: movementDuration];
        self.view.frame = CGRectOffset(self.view.frame, 0, movement);
        [UIView commitAnimations];
    }
}

要在ViewDidLoad中添加的委托

_tbxUsername.delegate = self;
_tbxPassword.delegate = self;

非常轻量级的解决方案可以使用KeyboardAnimator。

项目获得了示例实现,文档编制仍在进行中。。。

适当用法:它具有UITextField和UITextView的特定实现

限制::它完全基于objective-c,swift版本将很快推出。

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

  [self slideUp];
   return YES;
}

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

    [self slideDown];
   return YES;
}

#pragma mark - Slide Up and Down animation

- (void) slideUp {
    [UIView beginAnimations:nil context:nil];
    layoutView.frame = CGRectMake(0.0, -70.0, layoutView.frame.size.width, layoutView.frame.size.height);

    [UIView commitAnimations];
}


- (void) slideDown {
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDelay: 0.01]; 
    layoutView.frame = CGRectMake(0.0, 0.0, layoutView.frame.size.width, layoutView.frame.size.height);
    [UIView commitAnimations];
}

我最近发现自己在开发消息应用程序时也遇到了类似的情况。我创建了一个自定义的UIView,它粘在键盘顶部,并自动完成您所需的大部分操作

消息生成器视图

(来源:thegamengine.org)

这个项目背后的想法是创建类似于iMessage合成视图AKA的功能:

当键盘关闭时,会粘在键盘顶部并移动到屏幕底部处理文本中的更改控制柄旋转

为了调整/重新配置UIScrollView,您需要使用以下可选委托方法:

-(void)messageComposerFrameDidChange:(CGRect)帧,动画持续时间:(float)持续时间;

每当更改帧(调整大小、重新定位、旋转)时都会调用它,并且还会提供动画持续时间。您可以根据需要使用此信息调整UIScrollView的框架和内容插图的大小。