Swift 3中如何编写键盘通知

25

我正在尝试将这段代码更新为Swift 3:

NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)

NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)`

到目前为止,我只尝试过编译器提供的自动更正。这会导致代码像这样:

let notificationCenter = NotificationCenter.default()
notificationCenter.addObserver(self, selector: Selector(("keyboardWillShow:")), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

notificationCenter.addObserver(self, selector: Selector(("keyboardWillHide:")), name: NSNotification.Name.UIKeyboardWillHide, object: nil)`

不幸的是,这不能帮我解决问题,反而会导致更多的错误。

请问有人解决了这个问题吗?

请注意,我只是尝试如何编写通知,我现在并没有试图修复通知功能。 谢谢。


3
可能是Swift 3 NSNotificationCenter Keyboardwillshow/hide的重复问题。 - LC 웃
有点不同 - 引用的问题是关于键盘显示/隐藏功能。这个问题是关于通知设置的。 - ICL1901
1
好的,请告诉我是否有帮助。 - LC 웃
谢谢Anish,我还在努力想弄清楚如何编写通知本身。 - ICL1901
12个回答

1

这是我找到的最佳解决方案(来自“Lets Build That App” YouTube频道)

class ChatVC: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {

// reference to your UIView with message TextField

    @IBOutlet weak var ChatView: UIView!   


// bottom constrain to your UIView (in my case ChatView)

    var bottomConstraint: NSLayoutConstraint?  

    override func viewDidLoad() {
        super.viewDidLoad()

// add some text in the placeholder if you want

        messageField.placeholder = "Type your message.." 

// here we add two notifications for showing and hiding the keyboard

        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: UIResponder.keyboardWillShowNotification, object: nil)

        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: UIResponder.keyboardWillHideNotification, object: nil)


// defines the start position for message textField that will be shown on the screen

        bottomConstraint = NSLayoutConstraint(item: ChatViewField!, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: -40)    
        view.addConstraint(bottomConstraint!)    
    }

// handles notifications for both cases when keyboard pops up and disappears  

  @objc func handleKeyboardNotification(notification: NSNotification){
        if let userInfo = notification.userInfo {

            let keyboardFrame =  (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
            print(keyboardFrame)

            let isKeyboardShowing = notification.name == UIResponder.keyboardWillShowNotification

            bottomConstraint?.constant = isKeyboardShowing ? -keyboardFrame.height : -40

// makes animation at the same time as the keyboard

UIView.animate(withDuration: 0, delay: 0, options: UIView.AnimationOptions.curveEaseOut, animations: {

                self.view.layoutIfNeeded()
            }) { (completed) in    
            }   
        }
    }

0
如果你和我一样是个白痴,喜欢使用Combine

UIViewController的简单扩展:

import UIKit
import Combine 

extension Notification {
    var keyboardHeight: CGFloat {
        return (userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height ?? 0
    }
}

enum KeyboardState {
    case willShow
    case willHide
}

struct KeyboardObject: Equatable {
    var state: KeyboardState
    var height: CGFloat
}

extension UIViewController {
    private var keyboardWillShowPublisher: AnyPublisher<KeyboardObject, Never> {
        NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification,object: nil)
        .compactMap {
            return KeyboardObject(state: .willShow, height: $0.keyboardHeight)
        }.eraseToAnyPublisher()
    }
    
    private var keyboardWillHidePublisher: AnyPublisher<KeyboardObject, Never> {
        NotificationCenter.default
            .publisher(for: UIResponder.keyboardWillHideNotification,object: nil)
            .compactMap { _ in
                return KeyboardObject(state: .willHide, height: 0.0)
            }.eraseToAnyPublisher()
    }
    
    func keyboardListener() -> AnyPublisher<KeyboardObject, Never> {
        Publishers.Merge(keyboardWillShowPublisher, keyboardWillHidePublisher)
            .removeDuplicates()
            .eraseToAnyPublisher()
    }
}

在你的UIViewController中:
import UIKit
import Combine

final class SomeVC: UIViewController {
    var keyboardPublisher: AnyCancellable?
    private var flowLayoutConstraint: NSLayoutConstraint!
    private let defaults = UserDefaults.standard
    override func viewWillAppear(_ animated: Bool) {
        keyboardPublisher = self.keyboardListener()
            .sink(receiveValue: { [unowned self] keyboard in
                switch keyboard.state {
                case .willShow:
                    manageKeyboardChange(value: keyboard.height)
                case .willHide:
                // I used a value saved in my userDefaults, but just set it back to the original constraint for that view without the keyboard
                    manageKeyboardChange(value: defaults.double(forKey: "opaqueHeight"))
                }
            })
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        keyboardPublisher?.cancel()
    }
    
    func manageKeyboardChange(value: CGFloat) {
        self.flowLayoutConstraint.constant = value
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations:  { [weak self] in
            self?.view.layoutIfNeeded()
        }, completion: nil)
        
        print("CHANGE")
    }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接