J'ai essayé d'ajouter du code pour que ma vue soit visible lorsque le clavier apparaît, cependant, je ne parviens pas à traduire les exemples Objective-C en Swift. J'ai fait des progrès, mais je suis bloqué sur une ligne en particulier.
Voici les deux tutoriels/questions que j'ai suivis:
Comment déplacer le contenu de UIViewController vers le haut lorsque Keypad s'affiche à l'aide de Swifthttp://www.ioscreator.com/tutorials/move-view-when-keyboard-appears
Voici le code que j'ai actuellement:
override func viewWillAppear(animated: Bool) {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
func keyboardWillShow(notification: NSNotification) {
var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))
UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
let frame = self.budgetEntryView.frame
frame.Origin.y = frame.Origin.y - keyboardSize
self.budgetEntryView.frame = frame
}
func keyboardWillHide(notification: NSNotification) {
//
}
Pour le moment, je reçois une erreur sur cette ligne:
var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))
Si quelqu'un pouvait me dire ce que cette ligne de code devrait être, je devrais arriver à trouver le reste moi-même.
Il y a quelques problèmes dans votre ligne
var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))
notification.userInfo
renvoie un optional dictionary [NSObject : AnyObject]?
, Il doit donc être décompressé avant d’accéder à ses valeurs.NSDictionary
est mappée sur un dictionnaire natif Swift. Vous devez donc utiliser la syntaxe d'indice de dictionnaire (dict[key]
) pour accéder aux valeurs.NSValue
pour que vous puissiez appeler CGRectValue
dessus.Tout cela peut être réalisé avec une combinaison d’affectation optionnelle, de chaînage optionnel et de conversions optionnelles :
if let userInfo = notification.userInfo {
if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
// ...
} else {
// no UIKeyboardFrameBeginUserInfoKey entry in userInfo
}
} else {
// no userInfo dictionary in notification
}
ou en une étape:
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
// ...
}
Mise à jour pour Swift 3.0.1 (Xcode 8.1):
if let userInfo = notification.userInfo {
if let keyboardSize = userInfo[UIKeyboardFrameBeginUserInfoKey] as? CGRect {
let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
// ...
} else {
// no UIKeyboardFrameBeginUserInfoKey entry in userInfo
}
} else {
// no userInfo dictionary in notification
}
ou en une étape:
if let keyboardSize = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? CGRect {
let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
// ...
}
Pour encore moins de code, envisagez de regarder THIS
Cela m’a vraiment été utile… .. Vous devez simplement inclure la contrainte de vue dans le contrôleur de vue et utiliser les deux observateurs que vous avez ajoutés. Ensuite, utilisez simplement les méthodes suivantes (on suppose ici que vous déplacez une tableView)
func keyboardWillShow(sender: NSNotification) {
if let userInfo = sender.userInfo {
if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().size.height {
tableViewBottomConstraint.constant = keyboardHeight
UIView.animateWithDuration(0.25, animations: { () -> Void in
self.view.layoutIfNeeded()
})
}
}
}
et
func keyboardWillHide(sender: NSNotification) {
if let userInfo = sender.userInfo {
if let keyboardHeight = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().size.height {
tableViewBottomConstraint.constant = 0.0
UIView.animateWithDuration(0.25, animations: { () -> Void in self.view.layoutIfNeeded() })
}
} }
Si vous utilisez le storyboard, plutôt que de manipuler la vue elle-même, vous pouvez tirer parti de la mise en page automatique.
(Ceci est une version épurée de la réponse de Nicholas)
Configurez le centre de notification pour vous informer de l'apparition et de la disparition du clavier:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)
}
Et assurez-vous de supprimer les observateurs lorsque vous n'en avez plus besoin:
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: self.view.window)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: self.view.window)
}
Dans le storyboard, définissez la contrainte inférieure. Créez un exutoire de cette contrainte:
et définissez la propriété constante de la contrainte lorsque le clavier est affiché ou masqué:
func keyboardWillShow(notification: NSNotification) {
guard let keyboardHeight = (notification.userInfo! as NSDictionary).objectForKey(UIKeyboardFrameBeginUserInfoKey)?.CGRectValue.size.height else {
return
}
nameOfOutlet.constant = keyboardHeight
view.layoutIfNeeded()
}
func keyboardWillHide(notification: NSNotification) {
nameOfOutlet.constant = 0.0
view.layoutIfNeeded()
}
Maintenant, chaque fois que le clavier apparaît ou disparaît, l'autolayout s'occupe de tout.
Swift 2
func keyboardWasShown(notification:NSNotification) {
guard let info:[NSObject:AnyObject] = notification.userInfo,
let keyboardSize:CGSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size else { return }
let insets:UIEdgeInsets = UIEdgeInsetsMake(self.scrollView.contentInset.top, 0.0, keyboardSize.height, 0.0)
self.scrollView.contentInset = insets
self.scrollView.scrollIndicatorInsets = insets
}
Swift 3
func keyboardWasShown(notification:NSNotification) {
guard let info:[AnyHashable:Any] = notification.userInfo,
let keyboardSize:CGSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size else { return }
let insets:UIEdgeInsets = UIEdgeInsets(top: self.scrollView.contentInset.top, left: 0.0, bottom: keyboardSize.height, right: 0.0)
self.scrollView.contentInset = insets
self.scrollView.scrollIndicatorInsets = insets
}
Cela m'a aidé: https://developer.Apple.com/library/ios/samplecode/UICatalog/Listings/Swift_UICatalog_TextViewController_Swift.html
let userInfo = notification.userInfo!
let animationDuration: NSTimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as NSNumber).doubleValue
let keyboardScreenBeginFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as NSValue).CGRectValue()
let keyboardScreenEndFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as NSValue).CGRectValue()
Swift 3: MISE À JOUR
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: self.view.window)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: self.view.window)
}
Vous pouvez augmenter ou réduire une contrainte, ou toute autre valeur, à la taille du clavier à l'aide des données du clavier Afficher/masquer les notifications.
Ce code minimal enregistre pour notifier que le clavier va afficher et met à jour une contrainte en fonction de sa taille.
@IBOutlet weak var keyboardConstraint: NSLayoutConstraint!
let keyboardConstraintMargin:CGFloat = 20
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: nil) { (notification) in
if let keyboardSize = notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? CGRect {
self.keyboardConstraint.constant = keyboardSize.height + self.keyboardConstraintMargin
}
}
NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidHideNotification, object: nil, queue: nil) { (notification) in
self.keyboardConstraint.constant = self.keyboardConstraintMargin
}
}
De la même manière, cela met à jour le contenu d'un encadré de défilement en fonction de la taille du clavier.
@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: nil) { (notification) in
if let keyboardSize = notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? CGRect {
let insets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
self.scrollView.contentInset = insets
self.scrollView.scrollIndicatorInsets = insets
}
}
NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidHideNotification, object: nil, queue: nil) { (notification) in
let insets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
self.scrollView.contentInset = insets
self.scrollView.scrollIndicatorInsets = insets
}
}
Vous pouvez utiliser cette ligne pour votre ligne
var keyboardSize:CGSize = userInfo.objectForKey(UIKeyboardFrameBeginUserInfoKey)!.CGRectValue().size
Pour le xamarin, vous pouvez utiliser C # 6
private void KeyboardWillChangeFrame(NSNotification notification)
{
var keyboardSize = notification.UserInfo.ValueForKey(UIKeyboard.FrameEndUserInfoKey) as NSValue;
if (keyboardSize != null)
{
var rect= keyboardSize.CGRectValue;
//do your stuff here
}
}
c # 7
private void KeyboardWillChangeFrame(NSNotification notification)
{
if (!(notification.UserInfo.ValueForKey(UIKeyboard.FrameEndUserInfoKey) is NSValue keyboardSize)) return;
var rect= keyboardSize.CGRectValue;
}
Swift 3.0
Voici un exemple de récupération de la taille du clavier et de son utilisation pour animer une vue vers le haut. Dans mon cas, je déplace un UIView contenant mes UITextFields vers le haut lorsqu'un utilisateur commence à taper pour pouvoir remplir un formulaire et voir le bouton d'envoi en bas.
J'ai ajouté un point de vente à la contrainte d'espace bottom de la vue que je voulais animer et l'ai nommée myViewsBottomSpaceConstraint
:
@IBOutlet weak var myViewsBottomSpaceConstraint: NSLayoutConstraint!
J'ai ensuite ajouté le code suivant à ma classe Swift:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
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 userInfo = notification.userInfo as! [String: NSObject] as NSDictionary
let keyboardFrame = userInfo.value(forKey: UIKeyboardFrameEndUserInfoKey) as! CGRect
let keyboardHeight = keyboardFrame.height
myViewsBottomSpaceConstraint.constant = keyboardHeight
view.layoutIfNeeded()
}
func keyboardWillHide(notification: NSNotification) {
myViewsBottomSpaceConstraint.constant = 0.0
view.layoutIfNeeded()
}
xCode 8.2.1, Swift 3
ClavierNotifications
import Foundation
class KeyboardNotifications {
fileprivate var _isEnabled: Bool
fileprivate var notifications: [KeyboardNotificationsType]
fileprivate var delegate: KeyboardNotificationsDelegate
init(notifications: [KeyboardNotificationsType], delegate: KeyboardNotificationsDelegate) {
_isEnabled = false
self.notifications = notifications
self.delegate = delegate
}
deinit {
if isEnabled {
isEnabled = false
}
}
}
// MARK: - enums
extension KeyboardNotifications {
enum KeyboardNotificationsType {
case willShow, willHide, didShow, didHide
var selector: Selector {
switch self {
case .willShow:
return #selector(KeyboardNotifications.keyboardWillShow(notification:))
case .willHide:
return #selector(KeyboardNotifications.keyboardWillHide(notification:))
case .didShow:
return #selector(KeyboardNotifications.keyboardDidShow(notification:))
case .didHide:
return #selector(KeyboardNotifications.keyboardDidHide(notification:))
}
}
var notificationName: NSNotification.Name {
switch self {
case .willShow:
return .UIKeyboardWillShow
case .willHide:
return .UIKeyboardWillHide
case .didShow:
return .UIKeyboardDidShow
case .didHide:
return .UIKeyboardDidHide
}
}
}
}
// MARK: - isEnabled
extension KeyboardNotifications {
private func addObserver(type: KeyboardNotificationsType) {
NotificationCenter.default.addObserver(self, selector: type.selector, name: type.notificationName, object: nil)
print("\(type.notificationName.rawValue) inited")
}
var isEnabled: Bool {
set {
if newValue {
for notificaton in notifications {
addObserver(type: notificaton)
}
} else {
NotificationCenter.default.removeObserver(self)
print("Keyboard notifications deinited")
}
_isEnabled = newValue
}
get {
return _isEnabled
}
}
}
// MARK: - Notification functions
extension KeyboardNotifications {
@objc
func keyboardWillShow(notification: NSNotification) {
delegate.keyboardWillShow?(notification: notification)
}
@objc
func keyboardWillHide(notification: NSNotification) {
delegate.keyboardWillHide?(notification: notification)
}
@objc
func keyboardDidShow(notification: NSNotification) {
delegate.keyboardDidShow?(notification: notification)
}
@objc
func keyboardDidHide(notification: NSNotification) {
delegate.keyboardDidHide?(notification: notification)
}
}
KeyboardNotificationsDelegate
import Foundation
@objc
protocol KeyboardNotificationsDelegate {
@objc optional func keyboardWillShow(notification: NSNotification)
@objc optional func keyboardWillHide(notification: NSNotification)
@objc optional func keyboardDidShow(notification: NSNotification)
@objc optional func keyboardDidHide(notification: NSNotification)
}
class ViewController: UIViewController {
private var keyboardNotifications: KeyboardNotifications!
override func viewDidLoad() {
super.viewDidLoad()
...
keyboardNotifications = KeyboardNotifications(notifications: [.willShow, .willHide, .didShow, .didHide], delegate: self)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
keyboardNotifications.isEnabled = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
keyboardNotifications.isEnabled = false
}
}
extension ViewController: KeyboardNotificationsDelegate {
// If you don't need this func you can remove it
func keyboardWillShow(notification: NSNotification) {
...
}
// If you don't need this func you can remove it
func keyboardWillHide(notification: NSNotification) {
...
}
// If you don't need this func you can remove it
func keyboardDidShow(notification: NSNotification) {
...
}
// If you don't need this func you can remove it
func keyboardDidHide(notification: NSNotification) {
...
}
}
import UIKit
class ViewController: UIViewController {
private var keyboardNotifications: KeyboardNotifications!
private var textField = UITextField(frame: CGRect(x: 40, y: 40, width: 200, height: 30))
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(textField)
// when you will tap on view (background) the keyboard will hide
// read about view.disableKeybordWhenTapped here: http://stackoverflow.com/a/42187286/4488252
view.disableKeybordWhenTapped = true
keyboardNotifications = KeyboardNotifications(notifications: [.willShow, .willHide, .didShow, .didHide], delegate: self)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
keyboardNotifications.isEnabled = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
keyboardNotifications.isEnabled = false
}
}
extension ViewController: KeyboardNotificationsDelegate {
// If you don't need this func you can remove it
func keyboardWillShow(notification: NSNotification) {
print("keyboardWillShow")
let userInfo = notification.userInfo as! [String: NSObject]
let keyboardFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as! CGRect
print("keyboardFrame: \(keyboardFrame)")
}
// If you don't need this func you can remove it
func keyboardWillHide(notification: NSNotification) {
print("keyboardWillHide")
}
// If you don't need this func you can remove it
func keyboardDidShow(notification: NSNotification) {
print("keyboardDidShow")
}
// If you don't need this func you can remove it
func keyboardDidHide(notification: NSNotification) {
print("keyboardDidHide")
}
}
dans Swift 4.2 vous pouvez utiliser UIResponder.keyboardFrameEndUserInfoKey
guard let userInfo = notification.userInfo , let keyboardFrame:CGRect = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }```