Я пытался добавить код, чтобы переместить мой взгляд вверх при появлении клавиатуры, однако у меня возникают проблемы с переводом примеров Objective-C в Swift. Я добился определенного прогресса, но застрял на одной линии.
Это два руководства / вопроса, которые я следил:
Как переместить содержимое UIViewController вверх по мере появления клавиатуры с помощью Swift http://www.ioscreator.com/tutorials/move-view-when-keyboard-appears
Вот код, который у меня сейчас есть:
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) {
//
}
На данный момент я получаю сообщение об ошибке в этой строке:
var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))
Если бы кто-то мог сообщить мне, какой должна быть эта строка кода, я бы сам смог разобраться в остальном.
источник
Для еще меньшего количества кода рассмотрите возможность просмотра ЭТО
Мне это очень помогло. Вам просто нужно включить ограничение представления в контроллер представления и использовать двух добавленных вами наблюдателей. Затем просто используйте следующие методы (здесь предполагается, что вы перемещаете 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() }) } } }
и
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() }) } } }
источник
Если вы используете раскадровку, а не манипулируете самим представлением, вы можете воспользоваться автоматическим макетом.
(Это очищенная версия ответа Николая)
Настройте центр уведомлений, чтобы уведомлять вас о появлении и исчезновении клавиатуры:
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) }
И убедитесь, что вы удалили наблюдателей, когда они вам больше не нужны:
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) }
Внутри раскадровки установите нижнее ограничение. Создайте выход этого ограничения:
и установите постоянное свойство ограничения, когда клавиатура отображается или скрыта:
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() }
Теперь, когда клавиатура появляется или исчезает, автоматическая раскладка позаботится обо всем.
источник
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 }
источник
Это помогло мне: 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()
источник
Вы можете использовать эту строку для своей строки
var keyboardSize:CGSize = userInfo.objectForKey(UIKeyboardFrameBeginUserInfoKey)!.CGRectValue().size
источник
Swift 3: ОБНОВЛЕНИЕ
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) }
источник
Swift - Высота клавиатуры от keyboardWillShowNotification
Вы можете увеличить или уменьшить ограничение или любое другое значение до размера клавиатуры, используя данные с клавиатуры. Будет / действительно ли отображать / скрывать уведомления.
С ограничением макета
Этот минимальный код регистрируется для уведомления о том, что клавиатура будет отображать, и обновляет ограничение в зависимости от его размера.
@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 } }
С помощью ScrollView
Таким же образом обновляется вкладка содержимого в представлении прокрутки в зависимости от размера клавиатуры.
@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 } }
источник
Детали
Решение
import UIKit protocol KeyboardNotificationsDelegate: class { func keyboardWillShow(notification: NSNotification) func keyboardWillHide(notification: NSNotification) func keyboardDidShow(notification: NSNotification) func keyboardDidHide(notification: NSNotification) } extension KeyboardNotificationsDelegate { func keyboardWillShow(notification: NSNotification) {} func keyboardWillHide(notification: NSNotification) {} func keyboardDidShow(notification: NSNotification) {} func keyboardDidHide(notification: NSNotification) {} } class KeyboardNotifications { fileprivate var _isEnabled: Bool fileprivate var notifications: [KeyboardNotificationsType] fileprivate weak 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(keyboardWillShow(notification:)) case .willHide: return #selector(keyboardWillHide(notification:)) case .didShow: return #selector(keyboardDidShow(notification:)) case .didHide: return #selector(keyboardDidHide(notification:)) } } var notificationName: NSNotification.Name { switch self { case .willShow: return UIResponder.keyboardWillShowNotification case .willHide: return UIResponder.keyboardWillHideNotification case .didShow: return UIResponder.keyboardDidShowNotification case .didHide: return UIResponder.keyboardDidHideNotification } } } } // MARK: - isEnabled extension KeyboardNotifications { private func addObserver(type: KeyboardNotificationsType) { NotificationCenter.default.addObserver(self, selector: type.selector, name: type.notificationName, object: nil) } var isEnabled: Bool { set { if newValue { for notificaton in notifications { addObserver(type: notificaton) } } else { NotificationCenter.default.removeObserver(self) } _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) } }
Применение
class ViewController: UIViewController { private lazy var keyboardNotifications: KeyboardNotifications! = { return 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") guard let userInfo = notification.userInfo as? [String: NSObject], let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } 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") } }
Полный образец
import UIKit class ViewController: UIViewController { private lazy var keyboardNotifications: KeyboardNotifications! = { return KeyboardNotifications(notifications: [.willShow, .willHide, .didShow, .didHide], delegate: self) }() override func viewDidLoad() { super.viewDidLoad() let textField = UITextField(frame: CGRect(x: 40, y: 40, width: 200, height: 30)) textField.borderStyle = .roundedRect view.addSubview(textField) let gesture = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))) view.addGestureRecognizer(gesture) } 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") guard let userInfo = notification.userInfo as? [String: NSObject], let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } 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") } }
Результат
Журнал
источник
Swift 3.0
Вот пример получения размера клавиатуры и его использования для анимации вида вверх. В моем случае я перемещаю UIView, содержащий мои UITextFields, вверх, когда пользователь начинает печатать, чтобы он мог заполнить форму и по-прежнему видеть кнопку отправки внизу.
Я добавил выход к ограничению нижнего пространства представления, которое хотел анимировать, и назвал его по имени
myViewsBottomSpaceConstraint
:@IBOutlet weak var myViewsBottomSpaceConstraint: NSLayoutConstraint!
Затем я добавил в свой быстрый класс следующий код:
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() }
источник
Для xamarin вы можете использовать С # 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 } }
с # 7
private void KeyboardWillChangeFrame(NSNotification notification) { if (!(notification.UserInfo.ValueForKey(UIKeyboard.FrameEndUserInfoKey) is NSValue keyboardSize)) return; var rect= keyboardSize.CGRectValue; }
источник
в Swift 4.2 вы можете использовать UIResponder.keyboardFrameEndUserInfoKey
guard let userInfo = notification.userInfo , let keyboardFrame:CGRect = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }```
источник