Làm cách nào để phát hiện khi bàn phím được hiển thị và ẩn khỏi ứng dụng của tôi?
Làm cách nào để phát hiện khi bàn phím được hiển thị và ẩn khỏi ứng dụng của tôi?
Câu trả lời:
Trong phương thức ViewDidLoad của lớp bạn được thiết lập để lắng nghe thông báo về bàn phím:
// Listen for keyboard appearances and disappearances
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
Sau đó, trong các phương thức bạn chỉ định (trong trường hợp này keyboardDidShow
và keyboardDidHide
), bạn có thể làm gì đó với nó:
- (void)keyboardDidShow: (NSNotification *) notif{
// Do something here
}
- (void)keyboardDidHide: (NSNotification *) notif{
// Do something here
}
UITextFieldDelegat
e, sau đó triển khai textFieldShouldReturn:
phương thức. Bạn sẽ nhận được đối số textField
vừa nhập dưới dạng đối số, bạn có thể so sánh với Trường văn bản của riêng mình và cuộn scrollView
để Trường văn bản thích hợp hiển thị.
Bạn có thể chỉ cần addObserver
vào viewDidLoad
. Nhưng có addObserver
ở viewWillAppear
và removeObserver
trong viewWillDisappear
ngăn ngừa tai nạn hiếm xảy ra khi bạn đang thay đổi quan điểm của bạn.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear), name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillAppear), name: UIResponder.keyboardWillShowNotification, object: nil)
}
@objc func keyboardWillAppear() {
//Do something here
}
@objc func keyboardWillDisappear() {
//Do something here
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear), name: Notification.Name.UIKeyboardWillHide, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillAppear), name: Notification.Name.UIKeyboardWillShow, object: nil)
}
@objc func keyboardWillAppear() {
//Do something here
}
@objc func keyboardWillDisappear() {
//Do something here
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
NSNotificationCenter.defaultCenter().addObserver(self, selector:"keyboardWillAppear:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector:"keyboardWillDisappear:", name: UIKeyboardWillHideNotification, object: nil)
}
func keyboardWillAppear(notification: NSNotification){
// Do something here
}
func keyboardWillDisappear(notification: NSNotification){
// Do something here
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self)
}
deinit
như thế này:deinit { NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil) }
deinit { NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil) }
Swift 3:
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)
func keyboardWillShow(_ notification: NSNotification){
// Do something here
}
func keyboardWillHide(_ notification: NSNotification){
// Do something here
}
Swift 4:
NotificationCenter.default.addObserver( self, selector: #selector(ControllerClassName.keyboardWillShow(_:)),
name: Notification.Name.UIKeyboardWillShow,
object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ControllerClassName.keyboardWillHide(_:)),
name: Notification.Name.UIKeyboardWillHide,
object: nil)
Tiếp theo, thêm phương thức ngừng nghe thông báo khi vòng đời của đối tượng kết thúc: -
Then add the promised methods from above to the view controller:
deinit {
NotificationCenter.default.removeObserver(self)
}
func adjustKeyboardShow(_ open: Bool, notification: Notification) {
let userInfo = notification.userInfo ?? [:]
let keyboardFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let height = (keyboardFrame.height + 20) * (open ? 1 : -1)
scrollView.contentInset.bottom += height
scrollView.scrollIndicatorInsets.bottom += height
}
@objc func keyboardWillShow(_ notification: Notification) {
adjustKeyboardShow(true, notification: notification)
}
@objc func keyboardWillHide(_ notification: Notification) {
adjustKeyboardShow(false, notification: notification)
}
+=
dường như làm cho insets có được lớn hơn và lớn hơn.
UIResponder.keyboardWillShowNotification
và UIResponder.keyboardWillHideNotification
, và phím thông tin bàn phím là UIResponder.keyboardFrameBeginUserInfoKey
.
Swift - 4
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
addKeyBoardListener()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self) //remove observer
}
func addKeyBoardListener() {
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);
}
@objc func keyboardWillShow(_ notification: Notification) {
}
@objc func keyboardWillHide(_ notification: Notification) {
}
Hãy xem phần Quản lý Bàn phím của "Hướng dẫn Lập trình Văn bản, Web và Chỉnh sửa" để biết thông tin về cách theo dõi bàn phím được hiển thị hoặc ẩn và cách hiển thị / loại bỏ bàn phím theo cách thủ công.
Bạn sẽ muốn tự mình đăng ký 2 thông báo bàn phím:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name: UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (keyboardDidHide:) name: UIKeyboardDidHideNotification object:nil];
Bài đăng tuyệt vời về cách điều chỉnh TextField của bạn thành bàn phím - http://iosdevelopertips.com/user-interface/adjust-textfield-hiested-by-keyboard.html
Trong Swift 4.2, tên thông báo đã chuyển sang một vùng tên khác. Vì vậy, bây giờ nó
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
addKeyboardListeners()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
func addKeyboardListeners() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
}
@objc private extension WhateverTheClassNameIs {
func keyboardWillShow(_ notification: Notification) {
// Do something here.
}
func keyboardWillHide(_ notification: Notification) {
// Do something here.
}
}
Có câu trả lời ở trên là chính xác. Mặc dù tôi muốn tạo một người trợ giúp để kết thúc notification's observers
.
extension KeyboardHelper {
enum Animation {
case keyboardWillShow
case keyboardWillHide
}
typealias HandleBlock = (_ animation: Animation, _ keyboardFrame: CGRect, _ duration: TimeInterval) -> Void
}
final class KeyboardHelper {
private let handleBlock: HandleBlock
init(handleBlock: @escaping HandleBlock) {
self.handleBlock = handleBlock
setupNotification()
}
deinit {
NotificationCenter.default.removeObserver(self)
}
private func setupNotification() {
_ = NotificationCenter.default
.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { [weak self] notification in
self?.handle(animation: .keyboardWillShow, notification: notification)
}
_ = NotificationCenter.default
.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { [weak self] notification in
self?.handle(animation: .keyboardWillHide, notification: notification)
}
}
private func handle(animation: Animation, notification: Notification) {
guard let userInfo = notification.userInfo,
let keyboardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double
else { return }
handleBlock(animation, keyboardFrame, duration)
}
}
private var keyboardHelper: KeyboardHelper?
...
override func viewDidLoad() {
...
keyboardHelper = KeyboardHelper { [unowned self] animation, keyboardFrame, duration in
switch animation {
case .keyboardWillShow:
print("keyboard will show")
case .keyboardWillHide:
print("keyboard will hide")
}
}
}
Swift 4 -dd 20 october 2017
override func viewDidLoad() {
[..]
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear(_:)), name: Notification.Name.UIKeyboardWillHide, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillAppear(_:)), name: Notification.Name.UIKeyboardWillShow, object: nil)
}
@objc func keyboardWillAppear(_ notification: NSNotification) {
if let userInfo = notification.userInfo,
let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue).cgRectValue {
let inset = keyboardFrame.height // if scrollView is not aligned to bottom of screen, subtract offset
scrollView.contentInset.bottom = inset
scrollView.scrollIndicatorInsets.bottom = inset
}
}
@objc func keyboardWillDisappear(_ notification: NSNotification) {
scrollView.contentInset.bottom = 0
scrollView.scrollIndicatorInsets.bottom = 0
}
deinit {
NotificationCenter.default.removeObserver(self)
}
Nếu bạn có nhiều hơn một UITextField
phím và bạn cần phải làm gì đó khi (hoặc trước) bàn phím xuất hiện hoặc biến mất, bạn có thể thực hiện phương pháp này.
Thêm UITextFieldDelegate
vào lớp học của bạn. Gán bộ đếm số nguyên, giả sử:
NSInteger editCounter;
Đặt bộ đếm này thành 0 ở đâu đó trong viewDidLoad
. Sau đó, thực hiện textFieldShouldBeginEditing
và textFieldShouldEndEditing
ủy quyền các phương thức.
Trong phần đầu tiên, hãy thêm 1 vào editCounter. Nếu giá trị của editCounter trở thành 1 - điều này có nghĩa là bàn phím đó sẽ xuất hiện (trong trường hợp nếu bạn trả về YES). Nếu editCounter> 1 - điều này có nghĩa là bàn phím đó đã hiển thị và một UITextField khác giữ tiêu điểm.
Trong textFieldShouldEndEditing
trừ 1 từ editCounter. Nếu bạn nhận được số 0 - bàn phím sẽ bị loại bỏ, nếu không bàn phím sẽ vẫn còn trên màn hình.
Bạn có thể sử dụng thư viện KBKeyboardObserver . Nó chứa một số ví dụ và cung cấp giao diện đơn giản.
Có một CocoaPods để tạo điều kiện thuận lợi cho việc quan sát về NSNotificationCentr
khả năng hiển thị của bàn phím tại đây: https://github.com/levantAJ/Keyhi
pod 'Keyhi'
Vì vậy, đây là câu trả lời thực sự bây giờ.
import Combine
class MrEnvironmentObject {
/// Bind into yr SwiftUI views
@Published public var isKeyboardShowing: Bool = false
/// Keep 'em from deallocatin'
var subscribers: [AnyCancellable]? = nil
/// Adds certain Combine subscribers that will handle updating the
/// `isKeyboardShowing` property
///
/// - Parameter host: the UIHostingController of your views.
func setupSubscribers<V: View>(
host: inout UIHostingController<V>
) {
subscribers = [
NotificationCenter
.default
.publisher(for: UIResponder.keyboardWillShowNotification)
.sink { [weak self] _ in
self?.isKeyboardShowing = true
},
NotificationCenter
.default
.publisher(for: UIResponder.keyboardWillHideNotification)
.sink { [weak self, weak host] _ in
self?.isKeyboardShowing = false
// Hidden gem, ask me how I know:
UIAccessibility.post(
notification: .layoutChanged,
argument: host
)
},
// ...
Profit
.sink { [weak self] profit in profit() },
]
}
}