使用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
}

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


当前回答

如果该文本字段位于表的单元格中(即使table.scrollable=NO),也可以轻松自动完成。

注意:桌子的位置和大小必须合理。例如:如果桌子的y位置是从视图底部算起的100,那么300高的键盘将覆盖整个桌子。如果表的高度为10,并且当键盘出现时,其中的文本字段必须向上滚动100才能可见,那么该文本字段将超出表的范围。

其他回答

RPDP的代码成功地将文本字段移出键盘。但是当你在使用和关闭键盘后滚动到顶部时,顶部已经从视图中向上滚动。模拟器和设备都是如此。要读取该视图顶部的内容,必须重新加载该视图。

他下面的代码难道不应该使视图降低吗?

else
{
    // revert back to the normal state.
    rect.origin.y += kOFFSET_FOR_KEYBOARD;
    rect.size.height -= kOFFSET_FOR_KEYBOARD;
}

仅使用文本字段:

1a)使用界面生成器:选择所有文本字段=>编辑=>嵌入=>滚动视图

1b)在UIScrollView中手动嵌入文本字段,称为scrollView

2) 设置UITextFieldDelegate

3) 设置每个textField.delegate=self;(或在Interface Builder中建立连接)

4) 复制/粘贴:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    CGPoint scrollPoint = CGPointMake(0, textField.frame.origin.y);
    [scrollView setContentOffset:scrollPoint animated:YES];
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [scrollView setContentOffset:CGPointZero animated:YES];
}

我使用Swift和自动布局(但不能评论之前的Swift答案);以下是我在没有滚动视图的情况下的操作方法:

我在IB中使用字段之间的垂直约束来布局表单,以分隔它们。我在容器视图的最顶部字段中添加了一个垂直约束,并为此创建了一个出口(下面代码中的topSpaceForFormConstraint)。所有需要的就是更新这个约束,这是我在动画块中为一个漂亮的软运动所做的。当然,高度检查是可选的,在这种情况下,我只需要对最小的屏幕尺寸进行检查。

这可以使用任何常用的textFieldDidBegginEditing或keyboardWillShow方法调用。

func setFormHeight(top: CGFloat)
{
    let height = UIScreen.mainScreen().bounds.size.height

    // restore text input fields for iPhone 4/4s
    if (height < 568) {
        UIView.animateWithDuration(0.2, delay: 0.0, options: nil, animations: {
            self.topSpaceForFormConstraint.constant = top
            self.view.layoutIfNeeded()
            }, completion: nil)
    }

}

参考以下内容

import UIKit
@available(tvOS, unavailable)
public class KeyboardLayoutConstraint: NSLayoutConstraint {

    private var offset : CGFloat = 0
    private var keyboardVisibleHeight : CGFloat = 0

    @available(tvOS, unavailable)
    override public func awakeFromNib() {
        super.awakeFromNib()

        offset = constant

        NotificationCenter.default.addObserver(self, selector: #selector(KeyboardLayoutConstraint.keyboardWillShowNotification(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(KeyboardLayoutConstraint.keyboardWillHideNotification(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    // MARK: Notification

    @objc func keyboardWillShowNotification(_ notification: Notification) {
        if let userInfo = notification.userInfo {
            if let frameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue {
                let frame = frameValue.cgRectValue
                keyboardVisibleHeight = frame.size.height
            }

            self.updateConstant()
            switch (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber) {
            case let (.some(duration), .some(curve)):

                let options = UIViewAnimationOptions(rawValue: curve.uintValue)

                UIView.animate(
                    withDuration: TimeInterval(duration.doubleValue),
                    delay: 0,
                    options: options,
                    animations: {
                        UIApplication.shared.keyWindow?.layoutIfNeeded()
                        return
                    }, completion: { finished in
                })
            default:

                break
            }

        }

    }

    @objc func keyboardWillHideNotification(_ notification: NSNotification) {
        keyboardVisibleHeight = 0
        self.updateConstant()

        if let userInfo = notification.userInfo {

            switch (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber) {
            case let (.some(duration), .some(curve)):

                let options = UIViewAnimationOptions(rawValue: curve.uintValue)

                UIView.animate(
                    withDuration: TimeInterval(duration.doubleValue),
                    delay: 0,
                    options: options,
                    animations: {
                        UIApplication.shared.keyWindow?.layoutIfNeeded()
                        return
                    }, completion: { finished in
                })
            default:
                break
            }
        }
    }

    func updateConstant() {
        self.constant = offset + keyboardVisibleHeight
    }

}

简单的解决方案和最新的动画api。将origin.y更改215,您可以将其自定义为适合您的值。

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    if (self.view.frame.origin.y >= 0) {

        [UIView animateWithDuration:0.5 animations:^{
           self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y-215, self.view.frame.size.width, self.view.frame.size.height);
       }];
   }
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    if (self.view.frame.origin.y < 0) {
        [UIView animateWithDuration:0.5 animations:^{
           self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+215, self.view.frame.size.width, self.view.frame.size.height);
        }];

    }
}