Das Folgende ist eine Animation für ein Textfeld und eine Werkzeugleiste, die sich nach oben bewegen, wenn die Tastatur erscheint.
baseConstraint.constant = 211
self.view.setNeedsUpdateConstraints()
UIView.animateWithDuration(0.30, animations: {
self.view.layoutIfNeeded()
})
Es ist eng, aber nicht ganz identisch. Wie würden Sie die obige Animation ändern?
Bearbeiten:
Hier ist der endgültige Code mit der Antwort unten!
func keyboardWillShow(aNotification: NSNotification) {
let duration = aNotification.userInfo.objectForKey(UIKeyboardAnimationDurationUserInfoKey) as Double
let curve = aNotification.userInfo.objectForKey(UIKeyboardAnimationCurveUserInfoKey) as UInt
self.view.setNeedsLayout()
baseConstraint.constant = 211
self.view.setNeedsUpdateConstraints()
UIView.animateWithDuration(duration, delay: 0, options: UIViewAnimationOptions.fromMask(curve), animations: {
self.view.layoutIfNeeded()
}, completion: {
(value: Bool) in println()
})
}
Sie können die Animationsdauer und die Animationskurve aus dem userInfo-Wörterbuch auf der keyboardWillShow: notifications abrufen.
Registrieren Sie sich zuerst für die Benachrichtigung
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
Rufen Sie dann die Werte aus den Benachrichtigungsschlüsseln userInfo ab.
- (void)keyboardWillShow:(NSNotification*)notification {
NSNumber *duration = [notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curve = [notification.userInfo objectForKey: UIKeyboardAnimationCurveUserInfoKey];
// Do stuff with these values.
}
Es gibt viel mehr dieser Schlüssel, und Sie können sie auch aus der UIKeyboardWillDismiss-Benachrichtigung erhalten.
Diese Funktionalität ist bereits ab iOS 3.0 verfügbar: D
Hier sind die Dokumente:
Lassen Sie mich wissen, wenn Sie Hilfe benötigen, damit es funktioniert.
Schnelle Version:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
func keyboardWillShow(aNotification: NSNotification) {
let duration = aNotification.userInfo.objectForKey(UIKeyboardAnimationDurationUserInfoKey) as NSNumber
let curve = aNotification.userInfo.objectForKey(UIKeyboardAnimationCurveUserInfoKey) as NSNumber
}
Die Antwort mit der variablen Dauer ist richtig und funktioniert von iOS 3 bis 8, aber mit der neuen Version von Swift funktioniert der Code für die Antwort nicht mehr .. Vielleicht ist es ein Fehler auf meiner Seite, aber ich muss schreiben:
let duration = aNotification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as Double
let curve = aNotification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as UInt
self.view.setNeedsLayout()
//baseConstraint.constant = 211
self.view.setNeedsUpdateConstraints()
UIView.animateWithDuration(duration, delay: 0.0, options: UIViewAnimationOptions(curve), animations: { _ in
//self.view.layoutIfNeeded()
}, completion: { aaa in
//(value: Bool) in println()
})
Sieht aus, als würde objectForKey nicht mehr funktionieren und die Konvertierung ist strenger.
Swift3
let duration = noti.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
let curve = noti.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber
self.view.setNeedsLayout()
UIView.animate(withDuration: TimeInterval(duration), delay: 0, options: [UIViewAnimationOptions(rawValue: UInt(curve))], animations: {
self.view.layoutIfNeeded()
}, completion: nil)
Swift 4-Update, iOS 11+
Registrieren Sie sich zuerst für die Benachrichtigung in der Lebenszyklusmethode einer Ansicht:
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
}
Dann in keyBoardWillShow
Methode:
@objc func keyBoardWillShow(notification: NSNotification) {
guard let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double else {return}
print(duration) // you got animation's duration safely unwraped as a double
}
Vergessen Sie nicht, Observer in der deinit
-Methode zu entfernen:
deinit {
NotificationCenter.default.removeObserver(self)
}
Erstens ist die ausgewählte Antwort der richtige Weg.
Mehr kann hier bereitgestellt werden, was die Animation wirklich ist. Wenn Sie alle CAAnimations im UIViewAnimation-Block ausdrucken, werden Sie feststellen, dass es ist eine CASpringAnimation /, wenn Sie die Animationskurve auf die in der Tastaturbenachrichtigung angegebene einstellen. Die Dauer beträgt 0,5 und andere Parameter sind:
let ani = CASpringAnimation(keyPath: someKey)
ani.damping = 500
ani.stiffness = 1000
ani.mass = 3
ani.duration = 0.5
Der obige Code kann die Animation präzise wiedergeben.
Sobald die Animationskurve auf die Tastaturkurve eingestellt ist, ignoriert die UIView-Animation die Dauer im Parameter. (Wenn Sie die Dauer wirklich ändern möchten, passen Sie den Wert für mass
an.)
// Zuerst deklarieren Sie einen Delegaten in Ihrer Klasse UITextFieldDelegate
// Platziere oben auf dem View Controller
// ****************** Keyboard Animation ***************
var animateDistance = CGFloat()
struct MoveKeyboard {
static let KEYBOARD_ANIMATION_DURATION : CGFloat = 0.3
static let MINIMUM_SCROLL_FRACTION : CGFloat = 0.2;
static let MAXIMUM_SCROLL_FRACTION : CGFloat = 0.8;
static let PORTRAIT_KEYBOARD_HEIGHT : CGFloat = 216;
static let LANDSCAPE_KEYBOARD_HEIGHT : CGFloat = 162;
}
//
// Kopiere und kopiere Textfeld-Methode in deiner Klasse
func textFieldDidBeginEditing(textField: UITextField) {
let textFieldRect : CGRect = self.view.window!.convertRect(textField.bounds, fromView: textField)
let viewRect : CGRect = self.view.window!.convertRect(self.view.bounds, fromView: self.view)
let midline : CGFloat = textFieldRect.Origin.y + 0.5 * textFieldRect.size.height
let numerator : CGFloat = midline - viewRect.Origin.y - MoveKeyboard.MINIMUM_SCROLL_FRACTION * viewRect.size.height
let denominator : CGFloat = (MoveKeyboard.MAXIMUM_SCROLL_FRACTION - MoveKeyboard.MINIMUM_SCROLL_FRACTION) * viewRect.size.height
var heightFraction : CGFloat = numerator / denominator
if heightFraction > 1.0 {
heightFraction = 1.0
}
let orientation : UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
if (orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown) {
animateDistance = floor(MoveKeyboard.PORTRAIT_KEYBOARD_HEIGHT * heightFraction)
} else {
animateDistance = floor(MoveKeyboard.LANDSCAPE_KEYBOARD_HEIGHT * heightFraction)
}
var viewFrame : CGRect = self.view.frame
viewFrame.Origin.y -= animateDistance
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(NSTimeInterval(MoveKeyboard.KEYBOARD_ANIMATION_DURATION))
self.view.frame = viewFrame
UIView.commitAnimations()
}
func textFieldDidEndEditing(textField: UITextField) {
var viewFrame : CGRect = self.view.frame
viewFrame.Origin.y += animateDistance
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(NSTimeInterval(MoveKeyboard.KEYBOARD_ANIMATION_DURATION))
self.view.frame = viewFrame
UIView.commitAnimations()
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
Swift 4
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
func keyboardWillShow(notification: NSNotification) {
let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey]
print("duration",duration)
}
//--------------------------------------------------------------
// MARK: -
// MARK: - UITextFieldDelegate
//--------------------------------------------------------------
//To trigger event when user types in fields
//right click in IB and choose EditingChanged >> textField_EditingChanged
//NOTE IF KEYBOARD NOT SHOWING IN SIMULATOR and no view appearing ITS TURNED OFF BY DEFAULT SO YOU CAN TYPE WITH YOUR MAC KEYBOARD - HIT CMD+K or Simulator > Menu > Toggle Software Keyboard...
@IBAction func textField_EditingChanged(textField: UITextField) {
//if more than one search
if(textField == self.textFieldAddSearch){
appDelegate.log.error("self.textFieldAddSearch: '\(self.textFieldAddSearch.text)'")
if textField.text == ""{
}else{
callJSONWebservices(textField.text)
}
}else{
appDelegate.log.error("textFieldDidBeginEditing: unhandled textfield")
}
}
//TWO WAYS TO HIDE THE VIEW
//textFieldShouldReturn
//buttonCancel_Action
//USER HIT RETURN BUTTON ON keyboard >> resignFirstResponder >> triggers keyboardWillHide
func textFieldShouldReturn(textField: UITextField)-> Bool{
//triggers keyboardWillHide: which also fades out view
self.textFieldAddSearch.resignFirstResponder()
return false
}
//--------------------------------------------------------------
// MARK: -
// MARK: - KEYBORAD
//--------------------------------------------------------------
private func subscribeToKeyboardNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
private func unsubscribeFromKeyboardNotifications() {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
func keyboardWillShow(notification: NSNotification) {
if let userInfo = notification.userInfo {
if let heightKeyboard = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().height {
if let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey]?.doubleValue {
self.viewAddNewSearchResults.alpha = 0.0
self.viewAddNewSearchResults.hidden = false
if let curve = userInfo[UIKeyboardAnimationDurationUserInfoKey]?.integerValue {
appDelegate.log.info("keyboardWillShow: duration:\(duration)")
UIView.animateWithDuration(duration, delay:0.0, options: .CurveEaseInOut,
animations: {
//self.view.frame = CGRectMake(0, 0, Geo.width(), Geo.height() - height)
self.viewAddNewSearchResults_BottomConstraint.constant = heightKeyboard;
self.viewAddNewSearchResults.alpha = 1.0
},
completion: nil)
}
}
}
}
}
func keyboardWillHide(notification: NSNotification) {
if let userInfo = notification.userInfo {
if let heightKeyboard = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().height {
if let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey]?.doubleValue {
if let curve = userInfo[UIKeyboardAnimationDurationUserInfoKey]?.integerValue {
appDelegate.log.info("keyboardWillHide: duration:\(duration)")
UIView.animateWithDuration(duration, delay:0.0, options: .CurveEaseInOut,
animations: {
self.viewAddNewSearchResults_BottomConstraint.constant = 0;
self.viewAddNewSearchResults.alpha = 0.0
},
completion: nil)
}
}
}
}
}
//Add button shows search result panel below search text fields
//just set focus in the textField
//then the keyboardWillShow will fade in the view and resize it to fit above the keyboard
//and match fade in duration to animation of keyboard moving up
@IBAction func buttonAdd_Action(sender: AnyObject) {
//triggers keyboardWillHide: which also fades out view
self.textFieldAddSearch.resignFirstResponder()
}
//TWO WAYS TO HIDE THE VIEW
//textFieldShouldReturn
//buttonCancel_Action
//Cancel on the search results - just resignFirstResponder >> triggers keyboardWillHide: which also fades out view
@IBAction func buttonCancel_Action(sender: AnyObject) {
//triggers keyboardWillHide: which also fades out view
self.textFieldAddSearch.resignFirstResponder()
}
Ich möchte auf etwas aufmerksam machen, das mich bei der Lösung dieses Problems in die Irre führte. Ich brauchte die size der Tastatur aufgrund der neuen "Quickype" -Ansicht und ihrer Fähigkeit zum Anzeigen/Ausblenden (nur iOS8). So habe ich es gelöst:
- (void)keyboardWillChangeFrame:(NSNotification *)notification {
NSValue *value = notification.userInfo[UIKeyboardFrameEndUserInfoKey];
self.keyboardFrame = [value CGRectValue];
NSTimeInterval duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration animations:^{
//ANIMATE VALUES HERE
}];
}