我有一个应用,它在视图的下半部分有一个文本框。 这意味着当我在文本框中输入时,键盘会覆盖文本框。

我如何在打字时向上移动视图,这样我就可以看到我键入的内容,然后在键盘消失时将它移回原来的位置?

我到处都看了,但所有的解似乎都在Obj-C中,我还不能完全转换。

任何帮助都将不胜感激。


当前回答

func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y != 0{
           // self.view.frame.origin.y += keyboardSize.height
            self.view.frame.origin.y = 0
        }
    }
}

其他回答

我已经阅读了答案,并通过以下代码行解决了我的问题:

class ViewController: UIViewController, UITextFieldDelegate {

  @IBOutlet weak var titleField: UITextField!
  @IBOutlet weak var priceField: UITextField!
  @IBOutlet weak var detailsField: UTtextField!

  override func viewDidLoad() {
   super.viewDidLoad()
// Do not to forget to set the delegate otherwise the textFieldShouldReturn(_:)
// won't work and the keyboard will never be hidden.
   priceField.delegate = self
   titleField.delegate = self
   detailsField.delegate = self

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

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

   func textFieldShouldReturn(_ textField: UITextField) -> Bool {
      self.view.endEditing(true)
      return false
   }

 func keyboardWillShow(notification: NSNotification) {
   var translation:CGFloat = 0
   if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
     if detailsField.isEditing{
       translation = CGFloat(-keyboardSize.height)
     }else if priceField.isEditing{
       translation = CGFloat(-keyboardSize.height / 3.8)
     }
   }
    UIView.animate(withDuration: 0.2) {
   self.view.transform = CGAffineTransform(translationX: 0, y: translation)
    }
  }


 func keyboardWillHide(notification: NSNotification) {
    UIView.animate(withDuration: 0.2) {
     self.view.transform = CGAffineTransform(translationX: 0, y: 0)
    } 
  }
}

我有几个UITextFields,并希望视图移动不同取决于哪个textField被点击。

这个视频教程是最好的。7分钟长,会很有意义。这样一个简单的解决方案,当你有多个文本字段,并希望滚动视图移动“x”数量的像素时,特定的文本字段被点击。

https://youtu.be/VuiPGJOEBH4

就这些步骤:

-把你所有的文本字段放在一个滚动视图中,约束到视图的边缘。

-连接所有的文本字段和滚动视图作为视图控制器的委托。

-用IBOutlet连接所有文本字段和滚动视图。

class ViewController: UIViewController, UITextFieldDelegate {

添加UITextFieldDelegate协议到你的类中

@IBOutlet var stateAddress: UITextField!
@IBOutlet var zipAddress: UITextField!
@IBOutlet var phoneNumber: UITextField!
@IBOutlet var vetEmailAddress: UITextField!    
@IBOutlet weak var scrollView: UIScrollView!

-在swift文件中添加UITextFieldDelegate方法:

func textFieldShouldReturn(textField: UITextField) -> Bool {

    textField.resignFirstResponder()
    return true
}


func textFieldDidBeginEditing(textField: UITextField) {

    if (textField == self.stateAddress) {
        scrollView.setContentOffset(CGPointMake(0, 25), animated: true)
    }
    else if (textField == self.zipAddress) {
        scrollView.setContentOffset(CGPointMake(0, 57), animated: true)
    }
    else if (textField == self.phoneNumber) {
        scrollView.setContentOffset(CGPointMake(0, 112), animated: true)
    }
    else if (textField == self.vetEmailAddress) {
        scrollView.setContentOffset(CGPointMake(0, 142), animated: true)
    }
}

func textFieldDidEndEditing(textField: UITextField) {

    scrollView.setContentOffset(CGPointMake(0, 0), animated: true)
}

第一种方法只是激活键盘上的返回按钮来关闭键盘。第二个是当你点击到任何特定的文本域,然后设置你的滚动视图滚动的距离的y偏移(我的是基于我的视图控制器上的y位置25,57,112,142)。最后一个说,当你从键盘上点击时,滚动视图会回到原来的位置。

我使我的视图像素完美的这种方式!

func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y != 0{
           // self.view.frame.origin.y += keyboardSize.height
            self.view.frame.origin.y = 0
        }
    }
}

类似于@Boris的回答,但在Swift 5中:

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

@IBAction func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y == 0 {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }
}

@IBAction func keyboardWillHide(notification: NSNotification) {
    if self.view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}

验证的答案没有考虑到文本字段的位置,并有一些错误(双位移,永远不会回到主位置,位移即使文本字段是在视图的顶部…)

这个想法是:

获取焦点TextField的Y的绝对位置 来获取键盘高度 来获取屏幕高度 然后计算键盘位置和文本框之间的距离(如果< 0 ->向上移动视图) 使用UIView。而不是UIView.frame.origin.y -= ..,因为用UIView更容易回到原来的位置。变换= .identity

然后,我们将能够移动视图,只有在必要和特定的位移,以便有聚焦texField刚刚超过键盘

代码如下:

斯威夫特4

class ViewController: UIViewController, UITextFieldDelegate {

var textFieldRealYPosition: CGFloat = 0.0

override func viewDidLoad() {
    super.viewDidLoad()

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

  // Delegate all textfields

}


@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        let distanceBetweenTextfielAndKeyboard = self.view.frame.height - textFieldRealYPosition - keyboardSize.height
        if distanceBetweenTextfielAndKeyboard < 0 {
            UIView.animate(withDuration: 0.4) {
                self.view.transform = CGAffineTransform(translationX: 0.0, y: distanceBetweenTextfielAndKeyboard)
            }
        }
    }
}


@objc func keyboardWillHide(notification: NSNotification) {
    UIView.animate(withDuration: 0.4) {
        self.view.transform = .identity
    }
}


func textFieldDidBeginEditing(_ textField: UITextField) {
  textFieldRealYPosition = textField.frame.origin.y + textField.frame.height
  //take in account all superviews from textfield and potential contentOffset if you are using tableview to calculate the real position
}

}