我使用Swift与iOS编程,我使用这段代码来移动UITextField,但它不起作用。我正确地调用了函数keyboardWillShow,但是文本字段没有移动。我正在使用自动布局。

override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil);
}

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self);
}

func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        //let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)

        var frame = self.ChatField.frame
        frame.origin.y = frame.origin.y - keyboardSize.height + 167
        self.chatField.frame = frame
        println("asdasd")
    }
}

当前回答

如果你像我一样,使用自动布局,在模拟器上运行应用程序时不使用键盘。这可能是因为苹果让你使用你电脑的键盘作为第一个键盘。

显示设备上的键盘:

shift + cmd + K

听起来很愚蠢,但我很想在3小时前找到这个答案:)

其他回答

如果你像我一样尝试了以上所有的解决方案,但你的问题仍然没有解决,我有一个很棒的解决方案,它就像一个魅力。首先我想澄清一下上面提到的一些解决方案。

In my case IQkeyboardmanager was working only when there is no auto layout applied on the elements, if it is applied then IQkeyboard manager will not work the way we think. Same thing with upward movement of self.view. i have wriiten a objective c header with a swift support for pushing UITexfield upward when user clicks on it, solving the problem of keyboard covering the UITextfield : https://github.com/coolvasanth/smart_keyboard. One who has An intermediate or higher level in iOS app development can easily understand the repository and implement it. All the best

在Swift 4.0 -

func textFieldDidBeginEditing(_ textField: UITextField) {
        animateViewMoving(up: true, moveValue: 100)
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        animateViewMoving(up: false, moveValue: 100)
    }
    func animateViewMoving (up:Bool, moveValue :CGFloat){
        let movementDuration:TimeInterval = 0.3
        let movement:CGFloat = ( up ? -moveValue : moveValue)
        UIView.beginAnimations( "animateView", context: nil)
        UIView.setAnimationBeginsFromCurrentState(true)
        UIView.setAnimationDuration(movementDuration ) 
        self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
        UIView.commitAnimations()
    }

如果视图上有多个文本字段,那么我建议您查看这个方法。当在字段之间切换时,你不会有视图跑开的问题,它会简单地适应所需的文本字段。它在swift 5中工作

  override func viewDidLoad() {
    super.viewDidLoad()
    registerForKeyboardNotification()
}

扩展中的所有方法

extension StartViewController: UITextFieldDelegate {

func registerForKeyboardNotification() {
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(sender:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(sender:)), name: UIResponder.keyboardWillHideNotification, object: nil) 
}

@objc func keyboardWillShow(sender: NSNotification) {
    guard let userInfo = sender.userInfo,
          let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue,
          let currentTextField = UIResponder.currentFirst() as? UITextField  else { return }
         
    let keyboardTopY = keyboardFrame.cgRectValue.origin.y
    let convertedTextFieldFrame = view.convert(currentTextField.frame, from: currentTextField.superview)
    let textFieldBottomY = convertedTextFieldFrame.origin.y + convertedTextFieldFrame.size.height
    
    if textFieldBottomY > keyboardTopY {
        let textBoxY = convertedTextFieldFrame.origin.y
        let newFrameY = (textBoxY - keyboardTopY / 2) * -1
        view.frame.origin.y = newFrameY
    }
}


@objc func keyboardWillHide(sender: NSNotification) {
     self.view.frame.origin.y = 0
}


func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    switch textField {
    case emailTextField :
        passwordTextField.becomeFirstResponder()
    default:
        emailTextField.becomeFirstResponder()  
    }
    return true
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesBegan(touches , with:event)
    view.endEditing(true)
}
}

最后我们用UIResponder建立方法

extension UIResponder {
private struct Static {
    static weak var responder: UIResponder?
}

static func currentFirst() -> UIResponder? {
    Static.responder = nil
    UIApplication.shared.sendAction(#selector(UIResponder._trap), to: nil, from: nil, for: nil)
    return Static.responder
}

@objc private func _trap() {
    Static.responder = self
}
}

斯威夫特4.1,

使用TPKeyBoardAvoiding类来实现这一点。 这与UIScrollView, UICollectionView, UITableView一起工作很好。

只需将这个类分配给storyboard中的scrollview, collectionview或tableview,或以编程方式创建它的对象。 tpkeyboardavoidscrollview内的所有文本字段或文本视图将在键盘出现和消失时自动调整。

这里是tpkeyboardavoidance的链接

tpkeyboardavoidance for Swift 4.1,

import Foundation
import UIKit

// MARK: - TableView
class TPKeyboardAvoidingTableView:UITableView,UITextFieldDelegate, UITextViewDelegate {

    override var frame:CGRect{
        willSet{
            super.frame = frame
        }

        didSet{
            if hasAutomaticKeyboardAvoidingBehaviour() {return}
            TPKeyboardAvoiding_updateContentInset()
        }
    }

    override var contentSize:CGSize{
        willSet(newValue){
            if hasAutomaticKeyboardAvoidingBehaviour() {
                super.contentSize = newValue
                return
            }

            if newValue.equalTo(self.contentSize)
            {
                return
            }

            super.contentSize = newValue
            self.TPKeyboardAvoiding_updateContentInset()
        }

        //        didSet{
        //            self.TPKeyboardAvoiding_updateContentInset()
        //        }
    }


    override init(frame: CGRect, style: UITableViewStyle) {
        super.init(frame: frame, style: style)
        self.setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setup()
    }

    override func awakeFromNib() {
        setup()
    }

    deinit{
        NotificationCenter.default.removeObserver(self)
    }

    func hasAutomaticKeyboardAvoidingBehaviour()->Bool
    {
        if #available(iOS 8.3, *) {
            if self.delegate is UITableViewController
            {
                return true
            }
        }

        return false
    }

    func focusNextTextField()->Bool
    {
        return self.TPKeyboardAvoiding_focusNextTextField()
    }

    @objc func scrollToActiveTextField()
    {
        return self.TPKeyboardAvoiding_scrollToActiveTextField()
    }

    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        if newSuperview != nil {
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.TPKeyboardAvoiding_findFirstResponderBeneathView(self)?.resignFirstResponder()
        super.touchesEnded(touches, with: event)
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if !self.focusNextTextField()
        {
            textField.resignFirstResponder()
        }
        return true
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)

        Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), userInfo: nil, repeats: false)
    }
}

private extension TPKeyboardAvoidingTableView
{
    func setup()
    {
        if self.hasAutomaticKeyboardAvoidingBehaviour() { return }

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillShow(_:)),
                                               name: NSNotification.Name.UIKeyboardWillChangeFrame,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillHide(_:)),
                                               name: NSNotification.Name.UIKeyboardWillHide,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextViewTextDidBeginEditing,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextFieldTextDidBeginEditing,
                                               object: nil)
    }
}

// MARK: - CollectionView
class TPKeyboardAvoidingCollectionView:UICollectionView,UITextViewDelegate {

    override var contentSize:CGSize{
        willSet(newValue){
            if newValue.equalTo(self.contentSize)
            {
                return
            }

            super.contentSize = newValue
            self.TPKeyboardAvoiding_updateContentInset()
        }

        //        didSet{
        //            self.TPKeyboardAvoiding_updateContentInset()
        //        }
    }


    override var frame:CGRect{
        willSet{
            super.frame = frame
        }

        didSet{
            self.TPKeyboardAvoiding_updateContentInset()
        }
    }

    //    override init(frame: CGRect) {
    //        super.init(frame: frame)
    //    }

    override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
        super.init(frame: frame, collectionViewLayout: layout)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        //        fatalError("init(coder:) has not been implemented")
        super.init(coder: aDecoder)
        self.setup()

    }

    override func awakeFromNib() {
        setup()
    }

    deinit{
        NotificationCenter.default.removeObserver(self)
    }

    func focusNextTextField()->Bool
    {
        return self.TPKeyboardAvoiding_focusNextTextField()
    }

    @objc func scrollToActiveTextField()
    {
        return self.TPKeyboardAvoiding_scrollToActiveTextField()
    }

    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        if newSuperview != nil {
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.TPKeyboardAvoiding_findFirstResponderBeneathView(self)?.resignFirstResponder()
        super.touchesEnded(touches, with: event)
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if !self.focusNextTextField()
        {
            textField.resignFirstResponder()
        }
        return true
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)

        Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), userInfo: nil, repeats: false)
    }
}

private extension TPKeyboardAvoidingCollectionView
{
    func setup()
    {
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillShow(_:)),
                                               name: NSNotification.Name.UIKeyboardWillChangeFrame,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillHide(_:)),
                                               name: NSNotification.Name.UIKeyboardWillHide,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextViewTextDidBeginEditing,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextFieldTextDidBeginEditing,
                                               object: nil)
    }
}

// MARK: - ScrollView
class TPKeyboardAvoidingScrollView:UIScrollView,UITextFieldDelegate,UITextViewDelegate
{
    override var contentSize:CGSize{
        didSet{
            self.TPKeyboardAvoiding_updateFromContentSizeChange()
        }
    }


    override var frame:CGRect{
        didSet{
            self.TPKeyboardAvoiding_updateContentInset()
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setup()
    }

    override func awakeFromNib() {
        setup()
    }

    func contentSizeToFit()
    {
        self.contentSize = self.TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames()
    }

    func focusNextTextField() ->Bool
    {
        return self.TPKeyboardAvoiding_focusNextTextField()
    }

    @objc func scrollToActiveTextField()
    {
        return self.TPKeyboardAvoiding_scrollToActiveTextField()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setup()
    }

    deinit{
        NotificationCenter.default.removeObserver(self)
    }

    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        if newSuperview != nil {
            NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.TPKeyboardAvoiding_findFirstResponderBeneathView(self)?.resignFirstResponder()
        super.touchesEnded(touches, with: event)
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if !self.focusNextTextField()
        {
            textField.resignFirstResponder()
        }
        return true
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), object: self)

        Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_:)), userInfo: nil, repeats: false)
    }
}

private extension TPKeyboardAvoidingScrollView
{
    func setup()
    {
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillShow(_:)),
                                               name: NSNotification.Name.UIKeyboardWillChangeFrame,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(TPKeyboardAvoiding_keyboardWillHide(_:)),
                                               name: NSNotification.Name.UIKeyboardWillHide,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextViewTextDidBeginEditing,
                                               object: nil)

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(scrollToActiveTextField),
                                               name: NSNotification.Name.UITextFieldTextDidBeginEditing,
                                               object: nil)
    }
}

// MARK: - Process Event
let kCalculatedContentPadding:CGFloat = 10;
let kMinimumScrollOffsetPadding:CGFloat = 20;

extension UIScrollView
{
    @objc func TPKeyboardAvoiding_keyboardWillShow(_ notification:Notification)
    {
        guard let userInfo = notification.userInfo else { return }
        guard let rectNotification = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else
        {
            return
        }

        let keyboardRect = self.convert(rectNotification.cgRectValue , from: nil)
        if keyboardRect.isEmpty
        {
            return
        }

        let state = self.keyboardAvoidingState()

        guard let firstResponder = self.TPKeyboardAvoiding_findFirstResponderBeneathView(self) else { return}
        state.keyboardRect = keyboardRect
        if !state.keyboardVisible
        {
            state.priorInset = self.contentInset
            state.priorScrollIndicatorInsets = self.scrollIndicatorInsets
            state.priorPagingEnabled = self.isPagingEnabled
        }

        state.keyboardVisible = true
        self.isPagingEnabled = false

        if self is TPKeyboardAvoidingScrollView
        {
            state.priorContentSize = self.contentSize
            if self.contentSize.equalTo(CGSize.zero)
            {
                self.contentSize = self.TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames()
            }
        }

        let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Float ?? 0.0
        let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int ?? 0
        let options = UIViewAnimationOptions(rawValue: UInt(curve))

        UIView.animate(withDuration: TimeInterval(duration),
                       delay: 0,
                       options: options,
                       animations: { [weak self]() -> Void in
                        if let actualSelf = self
                        {
                            actualSelf.contentInset = actualSelf.TPKeyboardAvoiding_contentInsetForKeyboard()
                            let viewableHeight = actualSelf.bounds.size.height - actualSelf.contentInset.top - actualSelf.contentInset.bottom
                            let point = CGPoint(x: actualSelf.contentOffset.x, y: actualSelf.TPKeyboardAvoiding_idealOffsetForView(firstResponder, viewAreaHeight: viewableHeight))
                            actualSelf.setContentOffset(point, animated: false)

                            actualSelf.scrollIndicatorInsets = actualSelf.contentInset
                            actualSelf.layoutIfNeeded()
                        }

        }) { (finished) -> Void in

        }
    }

    @objc func TPKeyboardAvoiding_keyboardWillHide(_ notification:Notification)
    {
        guard let userInfo = notification.userInfo else { return }

        guard let rectNotification = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue else
        {
            return
        }
        let keyboardRect = self.convert(rectNotification.cgRectValue , from: nil)
        if keyboardRect.isEmpty
        {
            return
        }
        let state = self.keyboardAvoidingState()

        if !state.keyboardVisible
        {
            return
        }
        state.keyboardRect = CGRect.zero
        state.keyboardVisible = false

        let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Float ?? 0.0
        let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int ?? 0
        let options = UIViewAnimationOptions(rawValue: UInt(curve))

        UIView.animate(withDuration: TimeInterval(duration),
                       delay: 0,
                       options: options,
                       animations: { [weak self]() -> Void in
                        if let actualSelf = self
                        {
                            if actualSelf is TPKeyboardAvoidingScrollView {
                                actualSelf.contentSize = state.priorContentSize
                                actualSelf.contentInset = state.priorInset
                                actualSelf.scrollIndicatorInsets = state.priorScrollIndicatorInsets
                                actualSelf.isPagingEnabled = state.priorPagingEnabled
                                actualSelf.layoutIfNeeded()
                            }
                        }

        }) { (finished) -> Void in

        }
    }

    func TPKeyboardAvoiding_updateFromContentSizeChange()
    {
        let state = self.keyboardAvoidingState()
        if state.keyboardVisible
        {
            state.priorContentSize = self.contentSize
        }
    }

    func TPKeyboardAvoiding_focusNextTextField() ->Bool
    {
        guard let firstResponder = self.TPKeyboardAvoiding_findFirstResponderBeneathView(self) else { return false}
        guard let view = self.TPKeyboardAvoiding_findNextInputViewAfterView(firstResponder, beneathView: self) else { return false}
        Timer.scheduledTimer(timeInterval: 0.1, target: view, selector: #selector(becomeFirstResponder), userInfo: nil, repeats: false)

        return true

    }

    func TPKeyboardAvoiding_scrollToActiveTextField()
    {
        let state = self.keyboardAvoidingState()

        if !state.keyboardVisible { return }

        let visibleSpace = self.bounds.size.height - self.contentInset.top - self.contentInset.bottom

        let idealOffset = CGPoint(x: 0,
                                  y: self.TPKeyboardAvoiding_idealOffsetForView(self.TPKeyboardAvoiding_findFirstResponderBeneathView(self),
                                                                                viewAreaHeight: visibleSpace))

        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double((Int64)(0 * NSEC_PER_SEC)) / Double(NSEC_PER_SEC)) {[weak self] () -> Void in
            self?.setContentOffset(idealOffset, animated: true)
        }
    }

    //Helper
    func TPKeyboardAvoiding_findFirstResponderBeneathView(_ view:UIView) -> UIView?
    {
        for childView in view.subviews
        {
            if childView.responds(to: #selector(getter: isFirstResponder)) && childView.isFirstResponder
            {
                return childView
            }
            let result = TPKeyboardAvoiding_findFirstResponderBeneathView(childView)
            if result != nil
            {
                return result
            }
        }
        return nil
    }

    func TPKeyboardAvoiding_updateContentInset()
    {
        let state = self.keyboardAvoidingState()
        if state.keyboardVisible
        {
            self.contentInset = self.TPKeyboardAvoiding_contentInsetForKeyboard()
        }
    }

    func TPKeyboardAvoiding_calculatedContentSizeFromSubviewFrames() ->CGSize
    {
        let wasShowingVerticalScrollIndicator = self.showsVerticalScrollIndicator
        let wasShowingHorizontalScrollIndicator = self.showsHorizontalScrollIndicator

        self.showsVerticalScrollIndicator = false
        self.showsHorizontalScrollIndicator = false

        var rect = CGRect.zero

        for view in self.subviews
        {
            rect = rect.union(view.frame)
        }

        rect.size.height += kCalculatedContentPadding
        self.showsVerticalScrollIndicator = wasShowingVerticalScrollIndicator
        self.showsHorizontalScrollIndicator = wasShowingHorizontalScrollIndicator

        return rect.size
    }

    func TPKeyboardAvoiding_idealOffsetForView(_ view:UIView?,viewAreaHeight:CGFloat) -> CGFloat
    {
        let contentSize = self.contentSize

        var offset:CGFloat = 0.0
        let subviewRect =  view != nil ? view!.convert(view!.bounds, to: self) : CGRect.zero

        var padding = (viewAreaHeight - subviewRect.height)/2
        if padding < kMinimumScrollOffsetPadding
        {
            padding = kMinimumScrollOffsetPadding
        }

        offset = subviewRect.origin.y - padding - self.contentInset.top

        if offset > (contentSize.height - viewAreaHeight)
        {
            offset = contentSize.height - viewAreaHeight
        }

        if offset < -self.contentInset.top
        {
            offset = -self.contentInset.top
        }

        return offset
    }

    func TPKeyboardAvoiding_contentInsetForKeyboard() -> UIEdgeInsets
    {
        let state = self.keyboardAvoidingState()
        var newInset = self.contentInset;

        let keyboardRect = state.keyboardRect
        newInset.bottom = keyboardRect.size.height - max(keyboardRect.maxY - self.bounds.maxY, 0)

        return newInset

    }

    func TPKeyboardAvoiding_viewIsValidKeyViewCandidate(_ view:UIView)->Bool
    {
        if view.isHidden || !view.isUserInteractionEnabled {return false}

        if view is UITextField
        {
            if (view as! UITextField).isEnabled {return true}
        }

        if view is UITextView
        {
            if (view as! UITextView).isEditable {return true}
        }

        return false
    }

    func TPKeyboardAvoiding_findNextInputViewAfterView(_ priorView:UIView,beneathView view:UIView, candidateView bestCandidate: inout UIView?)
    {
        let priorFrame = self.convert(priorView.frame, to: priorView.superview)
        let candidateFrame = bestCandidate == nil ? CGRect.zero : self.convert(bestCandidate!.frame, to: bestCandidate!.superview)

        var bestCandidateHeuristic = -sqrt(candidateFrame.origin.x*candidateFrame.origin.x + candidateFrame.origin.y*candidateFrame.origin.y) + ( Float(fabs(candidateFrame.minY - priorFrame.minY))<Float.ulpOfOne ? 1e6 : 0)

        for childView in view.subviews
        {
            if TPKeyboardAvoiding_viewIsValidKeyViewCandidate(childView)
            {
                let frame = self.convert(childView.frame, to: view)
                let heuristic = -sqrt(frame.origin.x*frame.origin.x + frame.origin.y*frame.origin.y)
                    + (Float(fabs(frame.minY - priorFrame.minY)) < Float.ulpOfOne ? 1e6 : 0)

                if childView != priorView && (Float(fabs(frame.minY - priorFrame.minY)) < Float.ulpOfOne
                    && frame.minX > priorFrame.minX
                    || frame.minY > priorFrame.minY)
                    && (bestCandidate == nil || heuristic > bestCandidateHeuristic)
                {
                    bestCandidate = childView
                    bestCandidateHeuristic = heuristic
                }
            }else
            {
                self.TPKeyboardAvoiding_findNextInputViewAfterView(priorView, beneathView: view, candidateView: &bestCandidate)
            }
        }
    }

    func TPKeyboardAvoiding_findNextInputViewAfterView(_ priorView:UIView,beneathView view:UIView) ->UIView?
    {
        var candidate:UIView?
        self.TPKeyboardAvoiding_findNextInputViewAfterView(priorView, beneathView: view, candidateView: &candidate)
        return candidate
    }


    @objc func TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(_ obj: AnyObject)
    {
        func processWithView(_ view: UIView) {
            for childView in view.subviews
            {
                if childView is UITextField || childView is UITextView
                {
                    self.TPKeyboardAvoiding_initializeView(childView)
                }else
                {
                    self.TPKeyboardAvoiding_assignTextDelegateForViewsBeneathView(childView)
                }
            }
        }

        if let timer = obj as? Timer, let view = timer.userInfo as? UIView {
            processWithView(view)
        }
        else if let view = obj as? UIView {
            processWithView(view)
        }
    }

    func TPKeyboardAvoiding_initializeView(_ view:UIView)
    {
        if let textField = view as? UITextField,
            let delegate = self as? UITextFieldDelegate, textField.returnKeyType == UIReturnKeyType.default &&
            textField.delegate !== delegate
        {
            textField.delegate = delegate
            let otherView = self.TPKeyboardAvoiding_findNextInputViewAfterView(view, beneathView: self)
            textField.returnKeyType = otherView != nil ? .next : .done

        }
    }

    func keyboardAvoidingState()->TPKeyboardAvoidingState
    {
        var state = objc_getAssociatedObject(self, &AssociatedKeysKeyboard.DescriptiveName) as? TPKeyboardAvoidingState
        if state == nil
        {
            state = TPKeyboardAvoidingState()
            self.state = state
        }

        return self.state!
    }

}

// MARK: - Internal object observer
internal class TPKeyboardAvoidingState:NSObject
{
    var priorInset = UIEdgeInsets.zero
    var priorScrollIndicatorInsets = UIEdgeInsets.zero

    var keyboardVisible = false
    var keyboardRect = CGRect.zero
    var priorContentSize = CGSize.zero

    var priorPagingEnabled = false
}

internal extension UIScrollView
{
    fileprivate struct AssociatedKeysKeyboard {
        static var DescriptiveName = "KeyBoard_DescriptiveName"
    }

    var state:TPKeyboardAvoidingState?{
        get{
            let optionalObject:AnyObject? = objc_getAssociatedObject(self, &AssociatedKeysKeyboard.DescriptiveName) as AnyObject?
            if let object:AnyObject = optionalObject {
                return object as? TPKeyboardAvoidingState
            } else {
                return nil
            }
        }
        set{
            objc_setAssociatedObject(self, &AssociatedKeysKeyboard.DescriptiveName, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}

在编辑文本框时移动您的视图试试这个,我已经应用了这个,

选项1:—** **在Swift 5.0和iPhone X、XR、XS和XS Max中更新 使用NotificationCenter移动

在func viewWillAppear中注册这个通知(_ animated: Bool) 在func中注销此通知viewWillDisappear(_ animated: Bool)

注意:-如果你不取消注册,那么它将从子类调用,并将导致崩溃或其他。

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver( self, selector: #selector(keyboardWillShow(notification:)), name:  UIResponder.keyboardWillShowNotification, object: nil )
}
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
}

@objc func keyboardWillShow( notification: Notification) {
    if let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
        var newHeight: CGFloat
        let duration:TimeInterval = (notification.userInfo![UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
        let animationCurveRawNSN = notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
        let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
        let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
        if #available(iOS 11.0, *) {
            newHeight = keyboardFrame.cgRectValue.height - self.view.safeAreaInsets.bottom
        } else {
            newHeight = keyboardFrame.cgRectValue.height
        }
        let keyboardHeight = newHeight  + 10 // **10 is bottom margin of View**  and **this newHeight will be keyboard height**
        UIView.animate(withDuration: duration,
                       delay: TimeInterval(0),
                       options: animationCurve,
                       animations: {
                        self.view.textViewBottomConstraint.constant = keyboardHeight **//Here you can manage your view constraints for animated show**
                        self.view.layoutIfNeeded() },
                       completion: nil)
    }
}

方案二:- 工作正常

func textFieldDidBeginEditing(textField: UITextField) {
        self.animateViewMoving(up: true, moveValue: 100)
}
func textFieldDidEndEditing(textField: UITextField) {
        self.animateViewMoving(up: false, moveValue: 100)
}

func animateViewMoving (up:Bool, moveValue :CGFloat){
    var movementDuration:NSTimeInterval = 0.3
    var movement:CGFloat = ( up ? -moveValue : moveValue)
    UIView.beginAnimations( "animateView", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(movementDuration )
    self.view.frame = CGRectOffset(self.view.frame, 0,  movement)
    UIView.commitAnimations()
}

当键盘出现在Swift中时,我从这个源UITextField中得到了这个答案

在斯威夫特4——

func textFieldDidBeginEditing(_ textField: UITextField) {
        animateViewMoving(up: true, moveValue: 100)
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        animateViewMoving(up: false, moveValue: 100)
    }
    func animateViewMoving (up:Bool, moveValue :CGFloat){
        let movementDuration:TimeInterval = 0.3
        let movement:CGFloat = ( up ? -moveValue : moveValue)
        UIView.beginAnimations( "animateView", context: nil)
        UIView.setAnimationBeginsFromCurrentState(true)
        UIView.setAnimationDuration(movementDuration ) 
        self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
        UIView.commitAnimations()
    }