wake-up-neo.com

Verschieben Sie die Ansicht mit der Tastatur mit Swift

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.

222
Alex Catchpole

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
    }
}

BEARBEITEN SIE FÜR SWIFT 3.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
    }
}

EDIT FOR Swift 4.2:

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
    }
}
564
Boris

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.

Lösung

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

Beobachter entfernen

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)
}
63
Dan Beaulieu

Die einfachste Möglichkeit, die keinen Code erfordert:

  1. Laden Sie KeyboardLayoutConstraint.Swift herunter, und fügen Sie die Datei in Ihr Projekt ein (Drag & Drop), wenn Sie nicht bereits das Spring-Animations-Framework verwenden.
  2. Erstellen Sie in Ihrem Storyboard eine untere Einschränkung für das Ansichts- oder Textfeld, wählen Sie die Einschränkung aus (doppelklicken Sie darauf), und ändern Sie im Identitätsinspektor die Klasse von NSLayoutConstraint in KeyboardLayoutConstraint.
  3. Erledigt! 

Das Objekt wird automatisch synchron mit der Tastatur nach oben verschoben.

62
gammachill

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
}
30
user3677173

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)
}
21
scipianne

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
    }
}
13
codeByThey

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()
    }
}
12
Amro Shafie

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
    }
}
7

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)
  }
}
6
Pavle Mijatovic

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)
    }
}
5
Grant Park

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: 

  • um die absolute Textposition des TextFields zu erhalten
  • um die Höhe der Tastatur zu ermitteln
  • um das ScreenHeight zu bekommen
  • Berechnen Sie dann den Abstand zwischen Tastaturposition und Textfeld (wenn <0 -> die Ansicht nach oben verschieben).
  • verwenden Sie UIView.transform anstelle von UIView.frame.Origin.y - = .., da es einfacher ist, mit UIView.transform = .identity an die ursprüngliche Position zurückzukehren

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
}

}

3
Quentin N

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
        }
    }
}
2
Rbar

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.

2
ingconti

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()
}
2
Celil Bozkurt

Keine der anderen Antworten scheint also richtig zu sein.

Die Tastatur mit gutem Verhalten unter iOS sollte:

  • Automatisch die Größe ändern, wenn die Tastatur die Größe ändert (JA, ES KANN)
  • Animieren Sie mit der gleichen Geschwindigkeit wie die Tastatur
  • Animieren Sie mit der gleichen Kurve wie auf der Tastatur
  • Respektieren Sie gegebenenfalls die sicheren Bereiche.
  • Funktioniert auch im iPad/Undocked-Modus

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
    }
}
2
Antzi

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
         }
    }
1
Maulik Patel

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
        }
    }
}
1
Vah.Sah

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()
    }
1
Gene Loparco

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 
    }
} }
1
Eray Alparslan

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.

1
weegee
 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)
 }
0
Himali Shah
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
        }
    }
}
0
Puji Wahono

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.

0
MHSFisher
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

    }
0
Kamalkumar.E

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
    }
}
0
Tlzdeveloper786

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)

0
Saifan Nadaf

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
}
0
Rohit Sharma

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.

https://youtu.be/VuiPGJOEBH4

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!

0
bme003

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
  }
}
0
ravindu1024

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.

  1. In meinem Fall funktionierte der IQkeyboardmanager nur, wenn kein automatisches Layout für die Elemente angewendet wurde. Wenn er angewendet wird, funktioniert der IQkeyboard-Manager nicht in der von uns angenommenen Art
  2. Gleiches bei Aufwärtsbewegung von self.view.
  3. ich habe einen Objective C-Header mit einer schnellen Unterstützung geschrieben, um UITexfield nach oben zu drücken, wenn der Benutzer darauf klickt, um das Problem der Tastatur zu lösen, die das UITextfield abdeckt: https://github.com/coolvasanth/smart_keyboard
  4. Wer über eine mittlere oder höhere Ebene in der iOS-App-Entwicklung verfügt, kann das Repository leicht verstehen und implementieren. Alles Gute
0
Vasanth

Simpelst-Methode in Swift 4 enter image description here

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)
    }
0
ZAFAR007

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.

0
Fedya Grab

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)
0
Sujay U N

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
    }
}

}

0
Anton Russia
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

0
Hadevs Play

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()
}
0
Jugal K Balara

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.

0
xtrinch