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

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


当前回答

从Dune Buggy的回答中得到了参考。根据TextField的位置向上滚动视图。因为现有的答案是滚动屏幕的整个视图,所以我需要根据文本字段的框架滚动视图。

键盘WillShow

@objc func keyboardWillShow(notification: NSNotification) {
    
    guard let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
        
        // if keyboard size is not available for some reason, don't do anything
        return
    }
    let keyboardFrame = keyboardSize
    
    let maxheightScreen = self.view.frame
    
    
    if (self.txtEmail.frame.origin.y + ((self.txtEmail.superview)!.frame.maxY) + keyboardSize.height) >= maxheightScreen.size.height{
        if self.view.frame.origin.y == 0 {
            self.view.frame.origin.y -= (keyboardFrame.height - (self.txtEmail.frame.maxY + 120)) // Here i added 120 additional height for my additional view space
        }
    }
}

键盘将隐藏

@objc func keyboardWillHide(notification: NSNotification) {
    
    guard let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
        // if keyboard size is not available for some reason, don't do anything
        return
    }
    
    let keyboardFrame = keyboardSize
    
    if self.view.frame.origin.y != 0 {
        self.view.frame.origin.y += (keyboardFrame.height - (self.txtEmail.frame.maxY + 120))
    }
}

其他回答

如果您希望UIView正确移动,并且活动文本字段应准确定位到用户需要的位置,以便用户可以看到输入的内容。

为此,必须使用Scrollview。这假设是您的UIView层次结构。ContainerView->ScrollView->ContentView->您的视图。

如果您已经按照上面讨论的层次结构进行了UIView设计,那么现在在您的控制器类中,您需要在视图中添加通知观察器,并在视图中删除观察器。

但这种方法需要在UIView需要转换的地方添加每个控制器。我一直在使用“TPKeyboardAvoiding”吊舱。无论您是Scrollview、TableView还是CollectionView,它都能可靠且轻松地处理各种可能情况下的UIView转换。您只需要将类传递到“滚动视图”。

如下图所示

如果您是表视图,则可以将此类更改为“TPKeyboardAvoidingTableView”。您可以找到完整的运行项目project Link

我一直遵循这种稳健的开发方法。希望这有帮助!

请在文本字段委派方法中添加这些行,以便在iPad中向上滚动。

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

    CGPoint pt;
    CGRect rc = [textField bounds];
    rc = [textField convertRect:rc toView:scrlView];
    pt = rc.origin;
    pt.x = 0;
    pt.y -= 100;

    [scrlView setContentOffset:pt animated:YES];

    scrlView.contentSize = CGSizeMake(scrlView.frame.size.width, button.frame.origin.y+button.frame.size.height + 8 + 370);
}

您需要以编程方式添加具有特定帧大小的滚动视图。您必须在.h文件中添加UIScrollViewDelegate。您必须启用滚动视图,以便在viewDidLoad()中编写以下内容。

scrollview.scrollEnabled=YES;
scrollview.delegate=self;

scrollview.frame = CGRectMake(x,y,width,height);
//---set the content size of the scroll view--- 

[scrollview setContentSize:CGSizeMake(height,width)];

这样,可以添加x、y、宽度和高度值。

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

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

吊舱“IQKeyboardManager”,“3.3.7”#iOS7

我认为如果您使用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功能上执行这些方法。这取决于你。