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

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


当前回答

对于通用解决方案,这是我实现IQKeyboardManager的方法。

步骤1:-我在单例类中添加了UITextField、UITextView和UIKeyboard的全局通知。我叫它IQKeyboardManager。

步骤2:-如果找到UIKeyboardWillShowNotification、UITextFieldTextDidBegginEditingNotification或UITextViewTextDidBedginEditingNotice通知,我尝试从UIWindow.rootViewController层次结构获取topMostViewController实例。为了正确显示UITextField/UITextView,需要调整topMostViewController.view的框架。

步骤3:-我计算了topMostViewController.view相对于第一个响应的UITextField/UITextView的预期移动距离。

步骤4:-我根据预期的移动距离向上/向下移动topMostViewController.view.frame。

步骤5:-如果找到UIKeyboardWillHideNotification、UITextFieldTextDidEndEditingNotification或UITextViewTextDidEndEditingNotification通知,我再次尝试从UIWindow.rootViewController层次结构获取topMostViewController实例。

步骤6:-我计算了topMostViewController.view的干扰距离,需要将其恢复到原始位置。

第7步:-我根据干扰距离恢复了topMostViewController.view.frame。

步骤8:-我在应用程序加载时实例化了单例IQKeyboardManager类实例,因此应用程序中的每个UITextField/UUITextView都将根据预期的移动距离自动调整。

这就是IQKeyboardManager在没有代码行的情况下为您所做的一切!!只需将相关的源文件拖放到项目即可。IQKeyboardManager还支持设备定向、自动UIToolbar管理、KeybkeyboardDistanceFromTextField等功能,远远超出您的想象。

其他回答

我认为如果您使用Swift,最好的方法是使用面向协议的编程。

首先,您必须创建KeyboardCapable协议,使符合该协议的任何UIViewController都能够注册和注销键盘观察员:

import Foundation
import UIKit

protocol KeyboardCapable: KeyboardAnimatable {
    func keyboardWillShow(notification: NSNotification)
    func keyboardWillHide(notification: NSNotification)
}

extension KeyboardCapable where Self: UIViewController {
    func registerKeyboardNotifications() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil)
    }

    func unregisterKeyboardNotifications() {
        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
    }
}

您已经注意到上述代码中有一个无关的KeyboardAnimatable关键字。这只是我们需要创建的下一个协议的名称:

import Foundation
import UIKit

protocol KeyboardAnimatable {

}

extension KeyboardAnimatable where Self: UIViewController {
    func performKeyboardShowFullViewAnimation(withKeyboardHeight height: CGFloat, andDuration duration: NSTimeInterval) {
        UIView.animateWithDuration(duration, animations: { () -> Void in
            self.view.frame = CGRectMake(view.frame.origin.x, -height, view.bounds.width, view.bounds.height)
            }, completion: nil)
    }

    func performKeyboardHideFullViewAnimation(withDuration duration: NSTimeInterval) {
        UIView.animateWithDuration(duration, animations: { () -> Void in
            self.view.frame = CGRectMake(view.frame.origin.x, 0.0, view.bounds.width, view.bounds.height)
            }, completion: nil)
    }
}

这个KeyboardAnimatable协议为所有符合它的UIViewController提供了两种方法,分别为整个视图上下设置动画。

好的,如果KeyboardCapable符合KeyboardAnimatable,则所有符合Keyboard Capable的UIViewController也符合KeyboaardAnimatable。这很酷。

让我们看看符合KeyboardCapable的UIViewController,并对键盘事件做出反应:

import Foundation
import UIKit

class TransferConfirmViewController: UIViewController, KeyboardCapable {
    //MARK: - LIFE CYCLE       
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)

        registerKeyboardNotifications()
    }

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)

        unregisterKeyboardNotifications()
    }

    //MARK: - NOTIFICATIONS
    //MARK: Keyboard
    func keyboardWillShow(notification: NSNotification) {
        let keyboardHeight = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().height
        let animationDuration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
        performKeyboardShowFullViewAnimation(withKeyboardHeight: keyboardHeight, andDuration: animationDuration)
    }

    func keyboardWillHide(notification: NSNotification) {
        let animationDuration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
        performKeyboardHideFullViewAnimation(withDuration: animationDuration)
    }
}

现在,您的UIViewController将响应键盘事件,并将因此产生动画效果。

注意:如果您想要自定义动画而不是推拉视图,则必须在KeyboardAnimatable协议上定义自定义方法或在Keyboard功能上执行这些方法。这取决于你。

它很简单:-

在TextFieldDidBegginEditing中:-

self.view.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y-150, self.view.frame.size.width, self.view.frame.size.height);

在TextFieldShouldEndEditing中:-

self.view.frame=CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+150, self.view.frame.size.width, self.view.frame.size.height);

需要考虑的一件事是,您是否希望单独使用UITextField。我还没有遇到任何设计良好的iPhone应用程序在UITableViewCells之外实际使用UITextFields。

这将是一些额外的工作,但我建议您实现表视图中的所有数据条目视图。将UITextView添加到UITableViewCells。

您可以使用这个简单的Git存储库:https://github.com/hackiftekhar/IQKeyboardManager

这是一个自动管理所有字段移动的库。

根据他们的自述文件,集成非常简单:

而不需要输入任何代码,也不需要额外的设置。要使用IQKeyboardManager,您只需将源文件添加到项目中

虽然,这是非常好的控制,但在某些情况下,它会导致冲突,例如在具有滚动视图的视图控制器中。它有时会更改内容大小。不过,你可以去尝试,并按照你的要求尝试,也许你可以做我错过的事情。

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

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

// 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;
}