我有一个应用,它在视图的下半部分有一个文本框。 这意味着当我在文本框中输入时,键盘会覆盖文本框。
我如何在打字时向上移动视图,这样我就可以看到我键入的内容,然后在键盘消失时将它移回原来的位置?
我到处都看了,但所有的解似乎都在Obj-C中,我还不能完全转换。
任何帮助都将不胜感激。
我有一个应用,它在视图的下半部分有一个文本框。 这意味着当我在文本框中输入时,键盘会覆盖文本框。
我如何在打字时向上移动视图,这样我就可以看到我键入的内容,然后在键盘消失时将它移回原来的位置?
我到处都看了,但所有的解似乎都在Obj-C中,我还不能完全转换。
任何帮助都将不胜感激。
当前回答
我已经阅读了答案,并通过以下代码行解决了我的问题:
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被点击。
其他回答
对于黑屏错误(Swift 4和4.2)。
我解决了黑屏的问题。在验证方案中,敲击后键盘高度变化,导致黑屏。
必须使用UIKeyboardFrameEndUserInfoKey而不是UIKeyboardFrameBeginUserInfoKey
var isKeyboardAppear = false
override func viewDidLoad() {
super.viewDidLoad()
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)
}
@objc func keyboardWillShow(notification: NSNotification) {
if !isKeyboardAppear {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y == 0{
self.view.frame.origin.y -= keyboardSize.height
}
}
isKeyboardAppear = true
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if isKeyboardAppear {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.origin.y != 0{
self.view.frame.origin.y += keyboardSize.height
}
}
isKeyboardAppear = false
}
}
func registerForKeyboardNotifications()
{
//Keyboard
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWasShown), name: UIKeyboardDidShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillBeHidden), name: UIKeyboardDidHideNotification, object: nil)
}
func deregisterFromKeyboardNotifications(){
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
func keyboardWasShown(notification: NSNotification){
let userInfo: NSDictionary = notification.userInfo!
let keyboardInfoFrame = userInfo.objectForKey(UIKeyboardFrameEndUserInfoKey)?.CGRectValue()
let windowFrame:CGRect = (UIApplication.sharedApplication().keyWindow!.convertRect(self.view.frame, fromView:self.view))
let keyboardFrame = CGRectIntersection(windowFrame, keyboardInfoFrame!)
let coveredFrame = UIApplication.sharedApplication().keyWindow!.convertRect(keyboardFrame, toView:self.view)
let contentInsets = UIEdgeInsetsMake(0, 0, (coveredFrame.size.height), 0.0)
self.scrollViewInAddCase .contentInset = contentInsets;
self.scrollViewInAddCase.scrollIndicatorInsets = contentInsets;
self.scrollViewInAddCase.contentSize = CGSizeMake((self.scrollViewInAddCase.contentSize.width), (self.scrollViewInAddCase.contentSize.height))
}
/**
this method will fire when keyboard was hidden
- parameter notification: contains keyboard details
*/
func keyboardWillBeHidden (notification: NSNotification) {
self.scrollViewInAddCase.contentInset = UIEdgeInsetsZero
self.scrollViewInAddCase.scrollIndicatorInsets = UIEdgeInsetsZero
}
使用以下代码查看UITextField单击
func textFieldDidBeginEditing(textField: UITextField) {
ViewUpanimateMoving(true, upValue: 100)
}
func textFieldDidEndEditing(textField: UITextField) {
ViewUpanimateMoving(false, upValue: 100)
}
func ViewUpanimateMoving (up:Bool, upValue :CGFloat){
var durationMovement:NSTimeInterval = 0.3
var movement:CGFloat = ( up ? -upValue : upValue)
UIView.beginAnimations( "animateView", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(durationMovement)
self.view.frame = CGRectOffset(self.view.frame, 0, movement)
UIView.commitAnimations()
}
由于在Combine中没有如何做到这一点的答案,这里是我使用的方法。
我们创建一个发布者来监听通知,显示和隐藏。 为了显示,我们从通知userInfo中获取键盘帧,并检查当前活动响应器是否包含在其中。如果被覆盖,返回键盘帧高度。如果它没有被覆盖,返回0,我们不想移动帧。对于隐藏通知,我们简单地返回0。
private var keyboardHeightPublisher: AnyPublisher<CGFloat, Never> {
Publishers.Merge(
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.compactMap { $0.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect }
.map { $0.intersects(self.view.firstResponder!.frame) ? $0.height : 0 }
.map { $0 * -1 },
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.map { _ in CGFloat(0) }
).eraseToAnyPublisher()
}
在viewDidLoad中,我们只需订阅发布者,相应地改变视图框架。
override func viewDidLoad() {
super.viewDidLoad()
keyboardHeightPublisher.sink{ [weak self] height in
self?.view.frame.origin.y = height
}.store(in: &cancelables)
}
编辑 小心!如果firstResponder在子视图中,你必须计算与整个屏幕相对应的帧,以检查它们是否相交。 例子:
let myViewGlobalFrame = myView.convert(myView.frame, to: parentView)
我注意到其他答案涉及从视图中删除一些顶部。如果你想简单地调整视图的大小而不削减任何内容,只需尝试这个方法:)
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
self.view.setTranslatesAutoresizingMaskIntoConstraints(true)
self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.height - keyboardSize.height)
}
}
func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
self.collectionView.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.height + keyboardSize.height)
}
}