Ich habe eine App, die ein Textfeld in der unteren Hälfte der Ansicht hat .. Dies bedeutet, dass die Tastatur das Textfeld abdeckt, wenn ich das Textfeld eingebe.
Wie gehe ich vor, um die Ansicht beim Tippen nach oben zu verschieben, damit ich sehen kann, was ich tippe, und dann wieder an den ursprünglichen Platz schiebe, wenn die Tastatur verschwindet?
Ich habe überall nachgesehen, aber alle Lösungen scheinen in Obj-C zu sein, die ich noch nicht ganz konvertieren kann.
Jede Hilfe wäre sehr dankbar.
Hier ist eine Lösung, ohne den Wechsel von einem Textfeld zu einem anderen zu handhaben:
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)
}
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
self.view.frame.Origin.y -= keyboardSize.height
}
}
func keyboardWillHide(notification: NSNotification) {
self.view.frame.Origin.y = 0
}
Um dies zu lösen, ersetzen Sie die beiden Funktionen keyboardWillShow/Hide
durch diese:
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
if view.frame.Origin.y == 0 {
self.view.frame.Origin.y -= keyboardSize.height
}
}
}
func keyboardWillHide(notification: NSNotification) {
if view.frame.Origin.y != 0 {
self.view.frame.Origin.y = 0
}
}
override func viewDidLoad() {
super.viewDidLoad()
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)
}
@objc func keyboardWillShow(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
}
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if self.view.frame.Origin.y != 0 {
self.view.frame.Origin.y = 0
}
}
EDIT FOR Swift 4.0:
override func viewDidLoad() {
super.viewDidLoad()
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)
}
@objc func keyboardWillShow(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
}
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if self.view.frame.Origin.y != 0 {
self.view.frame.Origin.y = 0
}
}
override func viewDidLoad() {
super.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)
}
@objc 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
}
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if self.view.frame.Origin.y != 0 {
self.view.frame.Origin.y = 0
}
}
Eine der häufigsten Antworten in diesem Thread verwendet den folgenden Code:
func keyboardWillShow(sender: NSNotification) {
self.view.frame.Origin.y -= 150
}
func keyboardWillHide(sender: NSNotification) {
self.view.frame.Origin.y += 150
}
Es gibt ein offensichtliches Problem, wenn Sie Ihre Ansicht um einen statischen Betrag verschieben. Auf einem Gerät sieht es gut aus, in anderen Größenkonfigurationen jedoch schlecht. Sie müssen die Höhe der Tastatur ermitteln und diese als Offset-Wert verwenden.
Hier ist eine Lösung, die auf allen Geräten funktioniert und den Edge-Fall behandelt, bei dem der Benutzer das Textfeld für die Worterkennung beim Tippen verbirgt.
Wichtig zu beachten ist, dass wir als Objektparameter self.view.window übergeben. Dadurch erhalten Sie Daten von unserer Tastatur, z. B. die Höhe!
@IBOutlet weak var messageField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: self.view.window)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: self.view.window)
}
func keyboardWillHide(sender: NSNotification) {
let userInfo: [NSObject : AnyObject] = sender.userInfo!
let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
self.view.frame.Origin.y += keyboardSize.height
}
Wir machen es auf allen Geräten schön und behandeln den Fall, in dem der Benutzer das Textfeld für die Worterkennung hinzufügt oder entfernt.
func keyboardWillShow(sender: NSNotification) {
let userInfo: [NSObject : AnyObject] = sender.userInfo!
let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size
if keyboardSize.height == offset.height {
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.view.frame.Origin.y -= keyboardSize.height
})
} else {
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.view.frame.Origin.y += keyboardSize.height - offset.height
})
}
}
Vergessen Sie nicht, Ihre Beobachter zu entfernen, bevor Sie die Ansicht verlassen, um zu verhindern, dass unnötige Nachrichten übertragen werden.
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: self.view.window)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: self.view.window)
}
Update basierend auf Frage aus Kommentaren:
Wenn Sie zwei oder mehr Textfelder haben, können Sie überprüfen, ob Ihre view.frame.Origin.y auf Null steht.
func keyboardWillShow(sender: NSNotification) {
let userInfo: [NSObject : AnyObject] = sender.userInfo!
let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size
if keyboardSize.height == offset.height {
if self.view.frame.Origin.y == 0 {
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.view.frame.Origin.y -= keyboardSize.height
})
}
} else {
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.view.frame.Origin.y += keyboardSize.height - offset.height
})
}
print(self.view.frame.Origin.y)
}
Die einfachste Möglichkeit, die keinen Code erfordert:
Das Objekt wird automatisch synchron mit der Tastatur nach oben verschoben.
Fügen Sie dies Ihrem Viewcontroller hinzu. Klappt wunderbar. Passen Sie einfach die Werte an.
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(sender: NSNotification) {
self.view.frame.Origin.y -= 150
}
@objc func keyboardWillHide(sender: NSNotification) {
self.view.frame.Origin.y += 150
}
Ich habe eine der Antworten etwas verbessert, damit sie mit verschiedenen Tastaturen und verschiedenen Textansichten/Feldern auf einer Seite funktioniert:
Beobachter hinzufügen:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(notification:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
func keyboardWillHide() {
self.view.frame.Origin.y = 0
}
func keyboardWillChange(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
if YOURTEXTVIEW.isFirstResponder {
self.view.frame.Origin.y = -keyboardSize.height
}
}
}
Beobachter entfernen:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
Für Black Screen Error (Swift 4 & 4.2) .
Ich habe das Problem mit dem schwarzen Bildschirm behoben. In der überprüften Lösung Die Tastaturhöhe ändert sich nach dem Antippen und dies verursacht einen schwarzen Bildschirm.
Verwenden Sie UIKeyboardFrameEndUserInfoKey anstelle von 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
}
}
Ich sehe, dass alle Antworten die Ansicht selbst um den Wert der Tastaturhöhe verschieben. Nun, ich habe eine ausführliche Antwort, die nützlich sein könnte, wenn Sie Einschränkungen verwenden, d. H. autolayout
, die eine Ansicht verschieben, indem sie ihren Einschränkungswert (beispielsweise untere oder obere Beschränkungen) um einen vordefinierten Wert ändert.
In diesem Beispiel verwende ich die untere Einschränkung vom Textfeld in die untere Layoutansicht mit dem Anfangswert 175.
@IBOutlet weak var bottomConstraint: NSLayoutConstraint!
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);
}
func keyboardWillShow(notification: NSNotification) {
//To retrieve keyboard size, uncomment following line
//let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue()
bottomConstraint.constant = 260
UIView.animateWithDuration(0.3) {
self.view.layoutIfNeeded()
}
}
func keyboardWillHide(notification: NSNotification) {
//To retrieve keyboard size, uncomment following line
//let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue()
bottomConstraint.constant = 175
UIView.animateWithDuration(0.3) {
self.view.layoutIfNeeded()
}
}
Es wurden einige Änderungen an der Definition der KeyboardWillHideNotification vorgenommen.
Diese Lösung funktioniert mit Swift 4.2 :
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
@objc func keyboardWillShow(_ notification:Notification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
self.view.frame.Origin.y -= keyboardSize.height
}
}
@objc func keyboardWillHide(_ notification:Notification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
self.view.frame.Origin.y += keyboardSize.height
}
}
Für Swift 3 habe ich eine UIViewController-Unterklasse erstellt, da in allen View-Controllern konstantes Verhalten erforderlich war.
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)
}
}
Ich bemerkte, dass die anderen Antworten darin bestanden, einige der oberen Bereiche aus der Ansicht zu entfernen. Wenn Sie die Größe der Ansicht einfach ändern möchten, ohne Inhalte zu schneiden, versuchen Sie es mit dieser Methode :)
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)
}
}
Die validierte Antwort enthält nicht berücksichtigt die Textfeldposition und hat einen Fehler (doppelte Verschiebung, nie die Primärposition zurückkehren, Verschiebung, auch wenn das Texfeld oben in der Ansicht ist ...)
Die Idee ist:
dann können wir die Ansicht nur bei Bedarf verschieben, um das bestimmte texField direkt über der Tastatur zu verschieben
Hier ist der Code:
Swift 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
}
}
Swift 4:
Ich hatte ein Problem mit der meist akzeptierten Antwort, bei der das Ausblenden der Tastatur die Ansicht nicht ganz zum Ende der Seite zurückkehrte (nur teilweise). Das hat für mich funktioniert (+ aktualisiert für Swift 4).
override func viewDidLoad() {
super.viewDidLoad()
self.hideKeyboardWhenTappedAround()
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 let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.Origin.y == 0{
self.view.frame.Origin.y -= keyboardSize.height
}
}
}
@objc 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 = 0
}
}
}
Meine zwei Cents für Anfänger: In den obigen Beispielen ändert jemand die Koordinaten, andere verwenden "autoresizing mask" und andere Einschränkungen:
Wie Apple sagt, mischen Sie diese drei Arten von Logik nicht. Wenn Sie Einschränkungen im Storyboard haben, versuchen Sie nicht, x/y zu ändern. Es funktioniert definitiv nicht.
Für Swift 3
func textFieldDidBeginEditing(_ textField: UITextField) { // became first responder
//move textfields up
let myScreenRect: CGRect = UIScreen.main.bounds
let keyboardHeight : CGFloat = 216
UIView.beginAnimations( "animateView", context: nil)
var movementDuration:TimeInterval = 0.35
var needToMove: CGFloat = 0
var frame : CGRect = self.view.frame
if (textField.frame.Origin.y + textField.frame.size.height + UIApplication.shared.statusBarFrame.size.height > (myScreenRect.size.height - keyboardHeight - 30)) {
needToMove = (textField.frame.Origin.y + textField.frame.size.height + UIApplication.shared.statusBarFrame.size.height) - (myScreenRect.size.height - keyboardHeight - 30);
}
frame.Origin.y = -needToMove
self.view.frame = frame
UIView.commitAnimations()
}
func textFieldDidEndEditing(_ textField: UITextField) {
//move textfields back down
UIView.beginAnimations( "animateView", context: nil)
var movementDuration:TimeInterval = 0.35
var frame : CGRect = self.view.frame
frame.Origin.y = 0
self.view.frame = frame
UIView.commitAnimations()
}
Keine der anderen Antworten scheint also richtig zu sein.
Die Tastatur mit gutem Verhalten unter iOS sollte:
Mein Code verwendet eine als @IBOutlet
deklarierte NSLayoutConstraint
@IBOutlet private var bottomLayoutConstraint: NSLayoutConstraint!
Sie könnten auch Transformationen verwenden, Offsets anzeigen, ... Ich denke, es ist einfacher mit der Einschränkung tho. Es funktioniert, indem Sie eine Einschränkung nach unten setzen. Möglicherweise müssen Sie den Code ändern, wenn Ihre Konstante nicht 0/Nicht nach unten ist.
Hier ist der Code:
// In ViewDidLoad
NotificationCenter.default.addObserver(self, selector: #selector(?MyViewController.keyboardDidChange), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
@objc func keyboardDidChange(notification: Notification) {
let userInfo = notification.userInfo! as [AnyHashable: Any]
let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let animationDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber
let animationCurve = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as! NSNumber
bottomLayoutConstraint.constant = view.frame.height - endFrame.Origin.y - view.safeAreaInsets.bottom // If your constraint is not defined as a safeArea constraint you might want to skip the last part.
// Prevents iPad undocked keyboard.
guard endFrame.height != 0, view.frame.height == endFrame.height + endFrame.Origin.y else {
bottomLayoutConstraint.constant = 0
return
}
UIView.setAnimationCurve(UIView.AnimationCurve(rawValue: animationCurve.intValue)!)
UIView.animate(withDuration: animationDuration.doubleValue) {
self.view.layoutIfNeeded()
// Do additional tasks such as scrolling in a UICollectionView
}
}
seine 100% perfekte Antwort Für alle Guy's Tableview-Höhe bei geöffneter Tastatur
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(RecipeVC.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(RecipeVC.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func keyboardWillShow(notification: NSNotification) {
if ((notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue) != nil {
//self.view.frame.Origin.y -= keyboardSize.height
var userInfo = notification.userInfo!
var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
keyboardFrame = self.view.convert(keyboardFrame, from: nil)
var contentInset:UIEdgeInsets = self.tbl.contentInset
contentInset.bottom = keyboardFrame.size.height
self.tbl.contentInset = contentInset
}
}
func keyboardWillHide(notification: NSNotification) {
if ((notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue) != nil {
let contentInset:UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
self.tbl.contentInset = contentInset
}
}
Hier ist meine Lösung (eigentlich ist dieser Code für den Fall, dass Sie wenige Textfelder in Ihrer Ansicht haben, dies funktioniert auch für den Fall, wenn Sie ein Textfeld haben)
class MyViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var firstTextField: UITextField!
@IBOutlet weak var secondTextField: UITextField!
var activeTextField: UITextField!
var viewWasMoved: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PrintViewController.keyboardWillShow(_:)), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PrintViewController.keyboardWillHide(_:)), name: UIKeyboardWillHideNotification, object: nil)
}
override func viewDidDisappear(animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func textFieldDidBeginEditing(textField: UITextField) {
self.activeTextField = textField
}
func textFieldDidEndEditing(textField: UITextField) {
self.activeTextField = nil
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func keyboardWillShow(notification: NSNotification) {
let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue()
var aRect: CGRect = self.view.frame
aRect.size.height -= keyboardSize!.height
let activeTextFieldRect: CGRect? = activeTextField?.frame
let activeTextFieldOrigin: CGPoint? = activeTextFieldRect?.Origin
if (!CGRectContainsPoint(aRect, activeTextFieldOrigin!)) {
self.viewWasMoved = true
self.view.frame.Origin.y -= keyboardSize!.height
} else {
self.viewWasMoved = false
}
}
func keyboardWillHide(notification: NSNotification) {
if (self.viewWasMoved) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
self.view.frame.Origin.y += keyboardSize.height
}
}
}
Aktualisiert für Swift 3 ...
Wie andere bereits gesagt haben, müssen Sie in der viewDidLoad () - Methode Ihres Controllers Benachrichtigungsbeobachter hinzufügen.
NotificationCenter.default.addObserver(forName: .UIKeyboardWillShow, object: nil, queue: nil)
{ notification in
self.keyboardWillShow(notification)
}
NotificationCenter.default.addObserver(forName: .UIKeyboardWillHide, object: nil, queue: nil)
{ notification in
self.keyboardWillHide(notification)
}
NotificationCenter.default.addObserver(forName: .UIKeyboardDidShow, object: nil, queue: nil)
{ _ in
self.enableUserInteraction()
}
NotificationCenter.default.addObserver(forName: .UIKeyboardDidHide, object: nil, queue: nil)
{ _ in
self.enableUserInteraction()
}
Denken Sie daran, Ihre Beobachter ggf. zu entfernen (ich mache das in der viewWillDisappear () -Methode)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidHide, object: nil)
Implementieren Sie dann Ihre show and hide-Methoden. Beachten Sie die Zeile, in der die App aufgefordert wird, Interaktionsereignisse zu ignorieren (beginIgnoringInteractionEvents). Dies ist wichtig, da der Benutzer ohne diese Option auf ein Feld oder sogar auf eine Bildlaufansicht tippen und die Verschiebung ein zweites Mal ausführen kann, was zu einer schrecklichen UI-Störung führt. Das Ignorieren von Interaktionsereignissen vor dem Anzeigen und Ausblenden der Tastatur verhindert Folgendes:
func keyboardWillShow(notification: Notification)
{
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
{
UIApplication.shared.beginIgnoringInteractionEvents()
self.view.frame.Origin.y -= keyboardSize.height
// add this line if you are shifting a scrollView, as in a chat application
self.timelineCollectionView.contentInset.top += keyboardSize.height
}
}
func keyboardWillHide(notification: Notification)
{
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
{
UIApplication.shared.beginIgnoringInteractionEvents()
self.view.frame.Origin.y += keyboardSize.height
// add this line if you are shifting a scrollView, as in a chat application
self.timelineCollectionView.contentInset.top -= keyboardSize.height
}
}
Aktivieren Sie abschließend die Benutzerinteraktionen erneut (denken Sie daran, dass diese Methode nach der Tastatur didShow oder didHide ausgelöst wird):
func enableUserInteraction()
{
UIApplication.shared.endIgnoringInteractionEvents()
}
Wenn Sie 2 oder mehr Textfelder auf demselben VC haben und der Benutzer eines davon antippt und dann auf das andere tippt, ohne die Funktion keyboardWillHide aufzurufen, wird die Ansicht noch einmal nach oben verschoben, was nicht erforderlich ist Sie haben die Tastatur, ein leeres Feld, das die Höhe der Tastatur hat, und dann die Ansicht, indem Sie den Code in der Antwort verwenden, die ich bearbeitet habe:
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)
}
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
self.view.frame.Origin.y -= keyboardSize.height
}
}
func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
self.view.frame.Origin.y += keyboardSize.height
}
}
Ersetzen Sie dazu die beiden Funktionen "KeyboardWillShow/Hide":
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
if view.frame.Origin.y == 0{
self.view.frame.Origin.y -= keyboardSize.height
}
}
}
func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
if view.frame.Origin.y != 0 {
self.view.frame.Origin.y += keyboardSize.height
}
}
}
Die Lösung von @ Boris ist sehr gut, aber die Ansicht kann manchmal beschädigt sein.
Verwenden Sie für die perfekte Ausrichtung den folgenden Code
override func viewDidLoad() {
super.viewDidLoad()
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)}
Funktionen:
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.Origin.y == 0{
self.view.frame.Origin.y -= keyboardSize.height
}
}}
Und,
@objc func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
if self.view.frame.Origin.y != 0{
self.view.frame.Origin.y = 0
}
} }
Ich weiß, dass diese Frage beinahe 30 Antworten hat und ich bin so schockiert, dass niemand einmal von diesem wunderschönen GitHub-Projekt gesprochen hat, das alles für Sie und noch besser. Alle Antworten verschieben nur die Ansicht nach oben, aber was ist, wenn die Höhe der Tastatur das UITextField nicht verdeckt? Ich habe gerade alle meine Probleme mit diesem IQKeyboardManager gelöst. Es hat mehr als 13000 Sterne.
Fügen Sie dies einfach in Ihr Podfile ein, wenn Sie Swift verwenden
pod 'IQKeyboardManagerSwift'
und dann in Ihrem AppDelegate.Swift importieren Sie IQKeyboardManagerSwift und
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
}
}
Fügen Sie die Zeile IQKeyboardManager.shared.enable = true
hinzu, um sie zu aktivieren
Diese Lösung ist ein Muss, wenn Sie für die Produktion gehen. Es löst jedes Problem und ist ein Muss für jede Anwendung, die Input hat.
override func viewWillAppear(animated: Bool)
{
super.viewWillAppear(animated)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
// MARK: - keyboard
func keyboardWillShow(notification: NSNotification)
{
if let userInfo = notification.userInfo {
if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
let contentInsets = self.tblView.contentInset as UIEdgeInsets
self.tblView.contentInset = UIEdgeInsets(top: contentInsets.top, left: contentInsets.left, bottom: keyboardSize.height, right:contentInsets.right)
// ...
} else {
// no UIKeyboardFrameBeginUserInfoKey entry in userInfo
}
} else {
// no userInfo dictionary in notification
}
}
func keyboardWillHide(notification: NSNotification)
{
let contentInsets = self.tblView.contentInset as UIEdgeInsets
self.tblView.contentInset = UIEdgeInsets(top: contentInsets.top, left: contentInsets.left, bottom: 0, right:contentInsets.right)
}
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
}
}
}
Ich muss einen UIView
in Swift 4 verschieben, wenn die Tastatur geöffnet und geschlossen wird. und alle Antworten konnten mir nicht helfen. weil sich die Höhe der Tastatur ändert, wenn emojis open geöffnet wird. Mein Code lautet also:
@objc func keyboardWillShow(sender: NSNotification) {
if let keyboardFrame: NSValue = sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
let keyboardRectangle = keyboardFrame.cgRectValue
let keyboardHeight = keyboardRectangle.height
if(self.oldHeight == keyboardHeight){
self.sendingView.frame.Origin.y -= keyboardHeight
self.oldHeight = keyboardHeight
}
else{
self.sendingView.frame.Origin.y += self.oldHeight
self.sendingView.frame.Origin.y -= keyboardHeight
self.oldHeight = keyboardHeight
}
}
}
@objc func keyboardWillHide(sender: NSNotification) {
if let keyboardFrame: NSValue = sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
let keyboardRectangle = keyboardFrame.cgRectValue
let keyboardHeight = keyboardRectangle.height
self.sendingView.frame.Origin.y += keyboardHeight
}
}
und inviewDidLoad()
:
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);
self.oldHeight = CGFloat()
und definiert als Feld an der Spitze der Klasse.
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
}
Swift 4.1
override func viewDidLoad() {
super.viewDidLoad()
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)
}
@objc func keyboardWillShow(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 //can adjust as keyboardSize.height-(any number 30 or 40)
}
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if self.view.frame.Origin.y != 0 {
self.view.frame.Origin.y = 0
}
}
Swift 5.0:
Nach 4-5 Stunden Kampf kam ich mit einer einfachen Erweiterung von UIViewController mit einfachem Code, der wie Charme funktioniert
* Die Ansicht sollte sich nicht bewegen, wenn sich TextField über der Tastatur befindet
* Es muss kein konstanter Wert für NSLayoutConstraint festgelegt werden
* Keine Bibliothek von Drittanbietern erforderlich
* Kein Animationscode erforderlich
* Funktioniert auch in der Tabellenansicht
* Dies funktioniert bei Auto Layout/Auto Resize
extension UIViewController {
func addKeyboardObserver() {
NotificationCenter.default.addObserver(self,
selector: #selector(self.keyboardNotifications(notification:)),
name: UIResponder.keyboardWillChangeFrameNotification,
object: nil)
}
func removeKeyboardObserver(){
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
// This method will notify when keyboard appears/ dissapears
@objc func keyboardNotifications(notification: NSNotification) {
var accurateY = 0.0 //Using this we will calculate the selected textFields Y Position
if let activeTextField = UIResponder.currentFirst() as? UITextField {
// Here we will get accurate frame of which textField is selected if there are multiple textfields
let frame = self.view.convert(activeTextField.frame, from:activeTextField.superview)
accurateY = Double(frame.Origin.y) + Double(frame.size.height)
}
if let userInfo = notification.userInfo {
// here we will get frame of keyBoard (i.e. x, y, width, height)
let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let keyBoardFrameY = keyBoardFrame!.Origin.y
var newHeight: CGFloat = 0.0
//Check keyboards Y position and according to that move view up and down
if keyBoardFrameY >= UIScreen.main.bounds.size.height {
newHeight = 0.0
} else {
if accurateY >= Double(keyBoardFrameY) { // if textfields y is greater than keyboards y then only move View to up
if #available(iOS 11.0, *) {
newHeight = -CGFloat(accurateY - Double(keyBoardFrameY)) - self.view.safeAreaInsets.bottom
} else {
newHeight = -CGFloat(accurateY - Double(keyBoardFrameY)) - 5
}
}
}
//set the Y position of view
self.view.frame.Origin.y = newHeight
}
}
}
Fügen Sie diese Erweiterung von UIResponder hinzu, um zu ermitteln, welches TextField ausgewählt ist
public 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
}
}
Verwenden Sie dies dann in Ihrem ViewController
override func viewWillAppear(_ animated: Bool) {
self.addKeyboardObserver()
}
override func viewWillDisappear(_ animated: Bool) {
self.removeKeyboardObserver()
}
Registrieren Sie diese Benachrichtigung in func viewWillAppear(_ animated: Bool)
Deregistriere diese Benachrichtigung in func viewWillDisappear(_ animated:Bool)
Swift 3 Code
var activeField: UITextField?
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ProfileViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ProfileViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func textFieldDidBeginEditing(_ textField: UITextField){
activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField){
activeField = nil
}
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if (self.activeField?.frame.Origin.y)! >= keyboardSize.height {
self.view.frame.Origin.y = keyboardSize.height - (self.activeField?.frame.Origin.y)!
} else {
self.view.frame.Origin.y = 0
}
}
}
func keyboardWillHide(notification: NSNotification) {
self.view.frame.Origin.y = 0
}
dieses Video-Tutorial ist das Beste. 7 Minuten lang und es macht einfach so viel Sinn. Eine solche einfache Lösung, wenn Sie über mehrere Textfelder verfügen und die Bildlaufansicht um eine "x" Pixelmenge verschoben werden soll, wenn auf dieses bestimmte Textfeld getippt wird.
Nur diese Schritte:
-Platzieren Sie alle Ihre Textfelder in einer Bildlaufansicht, die an die Ränder der Ansicht gebunden ist.
Verbinden Sie alle Textfelder und die Bildlaufansicht als Delegierte zum Ansichtscontroller.
- Verbinden Sie alle Textfelder und die Bildlaufansicht mit einem IBOutlet.
class ViewController: UIViewController, UITextFieldDelegate {
- Fügen Sie der Klasse das UITextFieldDelegate-Protokoll hinzu
@IBOutlet var stateAddress: UITextField!
@IBOutlet var zipAddress: UITextField!
@IBOutlet var phoneNumber: UITextField!
@IBOutlet var vetEmailAddress: UITextField!
@IBOutlet weak var scrollView: UIScrollView!
Fügen Sie UITextFieldDelegate-Methoden zu Ihrer Swift-Datei hinzu:
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)
}
Die erste Methode aktiviert nur die Zurücktaste auf der Tastatur, um die Tastatur zu schließen. Das zweite ist, wenn Sie in ein bestimmtes Textfeld tippen und dann den y-Versatz einstellen, wie weit Ihr Bildlauf durch die Scroll-Ansicht verschoben wird (meiner liegt außerhalb der y-Position auf meinen View-Controllern 25,57,112,142). Der letzte besagt, wenn Sie von der Tastatur weg tippen, kehrt die Bildlaufansicht zum ursprünglichen Ort zurück.
Ich habe meinen Blick auf diese Weise perfekt gemacht!
Diese Implementierung (Swift 4) gibt Ihnen das Verhalten, das dem Standardverhalten von Android am nächsten kommt. Dh: verschiebt die Ansicht nach oben, wenn sich das aktive Textfeld unter der Tastatur befindet, und bewegt sich entsprechend, wenn der Benutzer zu einer anderen Ansicht wechselt, ohne die Tastatur zu schließen. Denken Sie daran, setTextFieldDelegates () aufzurufen.
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
}
}
wenn Sie wie ich sind und alle oben genannten Lösungen ausprobiert haben und Ihr Problem immer noch nicht gelöst ist, habe ich eine großartige Lösung für Sie, die wie ein Zauber wirkt. Zunächst möchte ich einige Dinge über einige der oben genannten Lösungen klären.
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet var myTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
myTextField.resignFirstResponder()
}
func keyboardWillShow(notification: NSNotification) {
// let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey]
// print("duration",duration)
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
let keyboardHeight : Int = Int(keyboardSize.height)
print("keyboardWillShow",keyboardHeight)
if let height = UserDefaults.standard.value(forKey: "keyboardHeight") as? (Int) {
moveTextField(myTextField, moveDistance: -height as Int, moveDuration: 0.43, up: true)
}else{
UserDefaults.standard.set(keyboardHeight, forKey: "keyboardHeight")
moveTextField(myTextField, moveDistance: -keyboardHeight, moveDuration: 0.43, up: true)
}
}
}
func keyboardWillHide(notification: NSNotification){
if let height = UserDefaults.standard.value(forKey: "keyboardHeight") as? (Int) {
moveTextField(myTextField, moveDistance: -height as Int, moveDuration: 0.25, up: false)
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func moveTextField(_ textField: UITextField, moveDistance: Int, moveDuration: Double, up: Bool) {
let movement: CGFloat = CGFloat(up ? moveDistance : -moveDistance)
UIView.beginAnimations("animateTextField", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(moveDuration)
self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
UIView.commitAnimations()
}
}
Sie können sich auch nur nach oben und unten bewegen UITextFiled
Nicht ganzer Bildschirm (UIView).
Mit dieser Methode.
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange), name: .UIKeyboardWillChangeFrame, object: nil)
Und
@objc func keyboardWillChange(notification: NSNotification) {
let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
let curFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = targetFrame.Origin.y - curFrame.Origin.y
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
self.textField.frame.Origin.y+=deltaY
},completion: nil)
}
ich habe Antworten gelesen und mein Problem durch folgende Codezeilen gelöst:
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)
}
}
}
Ich habe ein paar UITextFields und möchte, dass sich die Ansicht je nach dem angetippten textField unterschiedlich bewegt.
Dieses Feature-Shud wurde in Ios eingebaut, wir müssen es jedoch extern tun.
Geben Sie den untenstehenden Code ein
* Um die Ansicht zu verschieben, wenn sich textField unter der Tastatur befindet,
* Ansicht nicht verschieben, wenn sich textField über der Tastatur befindet
* Um die Ansicht je nach Höhe der Tastatur bei Bedarf zu verschieben.
Dies funktioniert und in allen Fällen getestet.
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
}
}
| :: | Manchmal ist die Ansicht unten, in diesem Fall verwenden Sie die Höhe +/- 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)
Swift 3.0 einfügen in viewDidLoad (), this->
{
view.addSubview (Your_messageInputConteinerView)
view.addConstraintWithFormat(format: "H:|[v0]|", views:Your_messageInputConteinerView)
view.addConstraintWithFormat(format: "V:[v0(48)]", views:Your_messageInputConteinerView)
NotificationCenter.default.addObserver (Selbst, Selektor: #selector (handleKeyboardNotification (Benachrichtigung :)), Name: NSNotification.Name.UIKeyboardWillShow, Objekt: nil)
NotificationCenter.default.addObserver (self, Selector: #selector (handleKeyboardNotification (notification :)), name: .UIKeyboardWillHide, object: nil)
bottomConstraint = NSLayoutConstraint(item: Your_messageInputConteinerView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0)
view.addConstraint(bottomConstraint!)
}
func handleKeyboardNotification (Benachrichtigung: Benachrichtigung) {
if let userInfo = notification.userInfo {
if let keyBoardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue{
print(keyBoardFrame)
if bottomConstraint?.constant != CGFloat(0) {
bottomConstraint?.constant = 0
return
}
bottomConstraint?.constant = -keyBoardFrame.height
or
self.view.frame.Origin.y = -keyBoardFrame.height
}
}
}
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
self.view.frame.Origin.y = self.view.frame.height - (self.view.frame.height + keyboardSize.height)
}
}
func keyboardWillHide(notification: NSNotification) {
self.view.frame.Origin.y = 0
}
es muss stabiler sein
Verwenden Sie den folgenden Code für die Anzeige von Up in UITextField Clicked
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()
}
Ich habe einen Cocoapod gemacht, um die Sache zu vereinfachen:
https://github.com/xtrinch/KeyboardLayoutHelper
Wie man es benutzt:
Erstellen Sie eine automatische Layout-Grundbeschränkung, geben Sie im Modul KeyboardLayoutHelper eine Klasse KeyboardLayoutConstraint an, und der Pod führt die erforderliche Arbeit aus, um das Erscheinen und Verschwinden der Tastatur zu unterstützen. Siehe Beispielprojekt zu Beispielen für die Verwendung (Ich habe zwei erstellt: textFields in einem scrollView und vertikal zentrierte textFields mit zwei grundlegenden Ansichten - login & register).
Die untere Layouteinschränkung kann die Containeransicht, das Textfeld selbst oder alles andere sein, wie Sie es nennen.