我有一个应用,它在视图的下半部分有一个文本框。 这意味着当我在文本框中输入时,键盘会覆盖文本框。
我如何在打字时向上移动视图,这样我就可以看到我键入的内容,然后在键盘消失时将它移回原来的位置?
我到处都看了,但所有的解似乎都在Obj-C中,我还不能完全转换。
任何帮助都将不胜感激。
我有一个应用,它在视图的下半部分有一个文本框。 这意味着当我在文本框中输入时,键盘会覆盖文本框。
我如何在打字时向上移动视图,这样我就可以看到我键入的内容,然后在键盘消失时将它移回原来的位置?
我到处都看了,但所有的解似乎都在Obj-C中,我还不能完全转换。
任何帮助都将不胜感激。
当前回答
这个实现(Swift 4)将给你的行为最接近Android的默认行为。Ie:当活动文本域在键盘下时,将视图向上移动,当用户切换到另一个视图时,无需关闭键盘。记住调用settextfielddelegate()。
public class DelegateProxy: NSObject, UITextFieldDelegate {
private static let instance = DelegateProxies()
weak var activeTextField: UITextField?
var offset: CGFloat = 0
weak var vc: UIViewController?
var keyboardHeight: CGFloat = 0
public static func getDelegate(root: UIViewController) -> DelegateProxies {
instance.vc = root
return instance
}
public static func getDelegate() -> DelegateProxies {
return instance
}
public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
self.activeTextField = textField
let globalPointY: CGFloat = (textField.superview?.convert(textField.frame.origin, to: nil).y ?? CGFloat(0)) + textField.frame.height
offset = UIScreen.main.bounds.height - globalPointY
if keyboardHeight > 0 {
vc?.moveViewUp(offsetFromKeyboard: keyboardHeight - offset)
}
return true
}
}
extension UIViewController {
private func setTextFieldDelegates(parentView: UIView) {
for child in parentView.subviews {
setTextFieldDelegates(parentView: child)
(child as? UITextField)?.delegate = DelegateProxies.getDelegate(root: self)
}
}
func registerAutoResizeOnKeyboardAppear(){
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 unregisterAutoResizeOnKeyboard(){
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
let offsetFromKeyboard = keyboardSize.height - DelegateProxies.getDelegate().offset
DelegateProxies.getDelegate().keyboardHeight = keyboardSize.height
moveViewUp(offsetFromKeyboard: offsetFromKeyboard)
}
}
func moveViewUp(offsetFromKeyboard: CGFloat){
print("offset from keyboard: \(offsetFromKeyboard)")
let moveOffset = offsetFromKeyboard + 8
if offsetFromKeyboard > 0 {
self.view.frame.origin.y = -moveOffset
}
if offsetFromKeyboard < 0 && view.frame.origin.y < 0 {
self.view.frame.origin.y += -moveOffset
if self.view.frame.origin.y > 0{
self.view.frame.origin.y = 0
}
}
}
@objc func keyboardWillHide(notification: NSNotification) {
self.view.frame.origin.y = 0
}
}
其他回答
这个功能应该在Ios中内置,但是我们需要在外部做。 插入以下代码 *当textField在键盘下时移动视图, *当textField在键盘上方时不移动视图 *在需要时根据键盘的高度移动视图。 这在所有情况下都有效并经过测试。
import UIKit
class NamVcc: UIViewController, UITextFieldDelegate
{
@IBOutlet weak var NamTxtBoxVid: UITextField!
var VydTxtBoxVar: UITextField!
var ChkKeyPadDspVar: Bool = false
var KeyPadHytVal: CGFloat!
override func viewDidLoad()
{
super.viewDidLoad()
NamTxtBoxVid.delegate = self
}
override func viewWillAppear(animated: Bool)
{
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(TdoWenKeyPadVyd(_:)),
name:UIKeyboardWillShowNotification,
object: nil);
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(TdoWenKeyPadHyd(_:)),
name:UIKeyboardWillHideNotification,
object: nil);
}
func textFieldDidBeginEditing(TxtBoxPsgVar: UITextField)
{
self.VydTxtBoxVar = TxtBoxPsgVar
}
func textFieldDidEndEditing(TxtBoxPsgVar: UITextField)
{
self.VydTxtBoxVar = nil
}
func textFieldShouldReturn(TxtBoxPsgVar: UITextField) -> Bool
{
self.VydTxtBoxVar.resignFirstResponder()
return true
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
view.endEditing(true)
super.touchesBegan(touches, withEvent: event)
}
func TdoWenKeyPadVyd(NfnPsgVar: NSNotification)
{
if(!self.ChkKeyPadDspVar)
{
self.KeyPadHytVal = (NfnPsgVar.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().height
var NonKeyPadAraVar: CGRect = self.view.frame
NonKeyPadAraVar.size.height -= self.KeyPadHytVal
let VydTxtBoxCenVal: CGPoint? = VydTxtBoxVar?.frame.origin
if (!CGRectContainsPoint(NonKeyPadAraVar, VydTxtBoxCenVal!))
{
self.ChkKeyPadDspVar = true
UIView.animateWithDuration(1.0,
animations:
{ self.view.frame.origin.y -= (self.KeyPadHytVal)},
completion: nil)
}
else
{
self.ChkKeyPadDspVar = false
}
}
}
func TdoWenKeyPadHyd(NfnPsgVar: NSNotification)
{
if (self.ChkKeyPadDspVar)
{
self.ChkKeyPadDspVar = false
UIView.animateWithDuration(1.0,
animations:
{ self.view.frame.origin.y += (self.KeyPadHytVal)},
completion: nil)
}
}
override func viewDidDisappear(animated: Bool)
{
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self)
view.endEditing(true)
ChkKeyPadDspVar = false
}
}
|::|有时候视图会向下,在这种情况下使用高度+/- 150:
NonKeyPadAraVar.size.height -= self.KeyPadHytVal + 150
{ self.view.frame.origin.y -= self.KeyPadHytVal - 150},
completion: nil)
{ self.view.frame.origin.y += self.KeyPadHytVal - 150},
completion: nil)
我已经阅读了答案,并通过以下代码行解决了我的问题:
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
}
}
对于Swift 3,我做了一个UIViewController子类,因为我需要在所有的视图控制器中恒定的行为。
class SomeClassVC: UIViewController {
//MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
addKeyboardObservers()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
removeKeyboardObservers()
}
//MARK: - Overrides
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
//MARK: - Help
func addKeyboardObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func removeKeyboardObservers() {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: self.view.window)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: self.view.window)
}
func keyboardWillShow(notification: NSNotification) {
let keyboardHeight = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.height
UIView.animate(withDuration: 0.1, animations: { () -> Void in
self.view.window?.frame.origin.y = -1 * keyboardHeight!
self.view.layoutIfNeeded()
})
}
func keyboardWillHide(notification: NSNotification) {
UIView.animate(withDuration: 0.1, animations: { () -> Void in
self.view.window?.frame.origin.y = 0
self.view.layoutIfNeeded()
})
}
func resignTextFieldFirstResponders() {
for textField in self.view.subviews where textField is UITextField {
textField.resignFirstResponder()
}
}
func resignAllFirstResponders() {
view.endEditing(true)
}
}
不是广告、促销或垃圾邮件,只是一个很好的解决方案。我知道这个问题有近30个答案,我很震惊,居然没有人提到过这个美丽的GitHub项目,它为你做了这一切,甚至更好。所有的答案只是向上移动视图。我刚刚用这个IQKeyboardManager解决了我所有的问题。它有13000多颗恒星。 如果你使用swift,只需将此添加到你的podfile中
pod 'IQKeyboardManagerSwift'
然后在你的AppDelegate.swift中导入IQKeyboardManagerSwift
import IQKeyboardManagerSwift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
IQKeyboardManager.shared.enable = true // just add this line
return true
}
}
添加一行IQKeyboardManager.shared.enable = true来启用它 如果您要进行生产,那么这个解决方案是必须的。