我使用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")
    }
}

当前回答

如果视图上有多个文本字段,那么我建议您查看这个方法。当在字段之间切换时,你不会有视图跑开的问题,它会简单地适应所需的文本字段。它在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
}
}

其他回答

我使用的Swift 4解决方案需要键盘大小。将serverStatusStackView替换为任何你关心的视图,例如:self.view:

deinit {
    NotificationCenter.default.removeObserver(self)
}

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        serverStatusStackView.frame.origin.y = keyboardSize.height * 2 - serverStatusStackView.frame.height
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        serverStatusStackView.frame.origin.y += keyboardSize.height
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

在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()
    }

另一个解决方案,不依赖于自动布局,约束或任何出口。您所需要的是滚动视图中的字段。

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "makeSpaceForKeyboard:", name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "makeSpaceForKeyboard:", name: UIKeyboardWillHideNotification, object: nil)
}

func makeSpaceForKeyboard(notification: NSNotification) {
    let info = notification.userInfo!
    let keyboardHeight:CGFloat = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().size.height
    let duration:Double = info[UIKeyboardAnimationDurationUserInfoKey] as! Double

    if notification.name == UIKeyboardWillShowNotification {
        UIView.animateWithDuration(duration, animations: { () -> Void in
            var frame = self.view.frame
            frame.size.height = frame.size.height - keyboardHeight
            self.view.frame = frame
        })
    } else {
        UIView.animateWithDuration(duration, animations: { () -> Void in
            var frame = self.view.frame
            frame.size.height = frame.size.height + keyboardHeight
            self.view.frame = frame
        })
    }

}
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

func keyboardWillShow(_ notification:Notification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0)
    }
}

func keyboardWillHide(_ notification:Notification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
    }
}

只需将文本框包含在视图中,然后覆盖返回视图的inputAccessoryView。 重要:您的视图应该以编程方式创建。不要使用@IBOutlets。

 override var inputAccessoryView: UIView? {
    get {
        return newlyProgramaticallyCreatedView
    }}