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

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


当前回答

虽然这条线索已经得到了足够的答案,但我想建议一种更简单但更通用的方法,就像苹果一样,将键盘的高度考虑在内,这在我们使用键盘顶部的自定义工具栏时非常有用。尽管苹果在这方面的做法没有什么问题。

这是我的方法(略微修改了苹果的方法)-

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;
}

其他回答

实际上,最好只使用苹果的实现,正如文档中所提供的那样。然而,他们提供的代码是错误的。将keyboardWasShow:注释下方的部分替换为以下内容:

NSDictionary* info = [aNotification userInfo];
CGRect keyPadFrame=[[UIApplication sharedApplication].keyWindow convertRect:[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue] fromView:self.view];
CGSize kbSize =keyPadFrame.size;
CGRect activeRect=[self.view convertRect:activeField.frame fromView:activeField.superview];
CGRect aRect = self.view.bounds;
aRect.size.height -= (kbSize.height);

CGPoint origin =  activeRect.origin;
origin.y -= backScrollView.contentOffset.y;
if (!CGRectContainsPoint(aRect, origin)) {
    CGPoint scrollPoint = CGPointMake(0.0,CGRectGetMaxY(activeRect)-(aRect.size.height));
    [backScrollView setContentOffset:scrollPoint animated:YES];
}

苹果代码存在以下问题:(1) 他们总是计算该点是否在视图的框架内,但它是一个ScrollView,因此它可能已经滚动,您需要考虑该偏移:

origin.y -= scrollView.contentOffset.y

(2) 他们按键盘的高度移动contentOffset,但我们希望相反(我们希望按屏幕上可见的高度而不是不可见的高度移动contentOffset):

activeField.frame.origin.y-(aRect.size.height)

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

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

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

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

当UITextField位于UITableViewCell中时,应自动设置滚动。

如果不是,可能是因为表视图的代码/设置不正确。

例如,当我重新加载长表时,底部有一个UITextField,如下所示:,

-(void) viewWillAppear:(BOOL)animated
{
   [self.tableview reloadData];
}

然后,当我在文本字段内单击时,底部的文本字段被键盘遮挡。

为了解决这个问题,我必须这样做-

-(void) viewWillAppear:(BOOL)animated
{
    //add the following line to fix issue
    [super viewWillAppear:animated];
    [self.tableview reloadData];
}

对于Swift Developer,使用Swift 3,这里是回购https://github.com/jamesrochabrun/KeyboardWillShow

import UIKit

class ViewController: UIViewController {

    //1 Create a view that will hold your TEXTFIELD
    let textField: UITextField = {
        let tf = UITextField()
        tf.translatesAutoresizingMaskIntoConstraints = false
        tf.layer.borderColor = UIColor.darkGray.cgColor
        tf.layer.borderWidth = 3.0
        return tf
    }()
    //2 global variable that will hold the bottom constraint on changes
    var textfieldBottomAnchor: NSLayoutConstraint?

    override func viewDidLoad() {
        super.viewDidLoad()
        //3 add the view to your controller
        view.addSubview(textField)
        textField.heightAnchor.constraint(equalToConstant: 80).isActive = true
        textField.widthAnchor.constraint(equalToConstant: view.frame.width).isActive = true
        textField.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        textfieldBottomAnchor = textField.bottomAnchor.constraint(equalTo: view.bottomAnchor)
        textfieldBottomAnchor?.isActive = true

        setUpKeyBoardObservers()
    }
    //4 Use NSnotificationCenter to monitor the keyboard updates
    func setUpKeyBoardObservers() {
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

    //5 toggle the bottom layout global variable based on the keyboard's height
    func handleKeyboardWillShow(notification: NSNotification) {

        let keyboardFrame = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect
        if let keyboardFrame = keyboardFrame {
            textfieldBottomAnchor?.constant = -keyboardFrame.height
        }
        let keyboardDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double
        if let keyboardDuration = keyboardDuration {
            UIView.animate(withDuration: keyboardDuration, animations: {
                self.view.layoutIfNeeded()
            })
        }
    }

    func handleKeyboardWillHide(notification: NSNotification) {

        textfieldBottomAnchor?.constant = 0
        let keyboardDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double
        if let keyboardDuration = keyboardDuration {
            UIView.animate(withDuration: keyboardDuration, animations: {
                self.view.layoutIfNeeded()
            })
        }
    }
    //6 remove the observers
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)

        NotificationCenter.default.removeObserver(self)
    }
}

使用IQKeyboardManager,出现键盘时,UITextField和UITextView会自动滚动。Git链接:https://github.com/hackiftekhar/IQKeyboardManager.

豆荚:pod“IQKeyboardManager”#iOS8及更高版本

吊舱“IQKeyboardManager”,“3.3.7”#iOS7