首页 > 解决方案 > NotificationCenter:多次切换键盘将 y 位置设置为奇怪的值

问题描述

我有一个带有 UITableView 的 UIViewController。我正在使用 NotificationCenter 设置视图的 y 坐标,以便在键盘再次显示和隐藏时进行调整。对于第一个显示+隐藏,一切看起来都很好。第二次这样做会弄乱屏幕上的东西。我在显示/隐藏操作中包含了打印语句以深入了解它 - 见下文。

class ChatDetailViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var UserLogo: UIImageView!
    @IBOutlet weak var UserName: UILabel!
    @IBOutlet weak var MessageList: UITableView!
    var conversation: Int = 0
    let apiService = APIService()
    var conversationDetails: ConversationDetails?



    override func viewDidLoad() {
        super.viewDidLoad()

        self.UserName.text = ""
        self.MessageList.separatorStyle = .none
        self.MessageList.delegate = self
        self.MessageList.dataSource = self

        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
// https://stackoverflow.com/questions/59773010/app-crashing-exception-unrecognised-selector-sent-to-instance

        // load messages:
        self.apiService.getChatMessages(conversation: self.conversation, completion: {result in
            switch result {
            case .success(let conversationDetails):
                DispatchQueue.main.async {
                    self.conversationDetails = conversationDetails
                    // prepare header section:
                    let URLstring = self.conversationDetails?.participants![0].profileimage
                    let imgURL = URL(string: URLstring ?? "www.foo.com") // TODO: insert placeholder image
                    self.UserLogo.sd_setImage(with: imgURL, placeholderImage: UIImage(named: "icon.turq.png"))
                    self.UserLogo.clipsToBounds = true
                    self.UserLogo.layer.cornerRadius = self.UserLogo.frame.size.width / 2
                    self.UserName.text = self.conversationDetails?.participants![0].username
                    self.MessageList.reloadData()
                }
            case .failure(let error):
                print("An error occured \(error.localizedDescription)")
            }
        })
    }



    @objc func keyboardWillShow(_ notification: Notification) {
        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            print(self.view)
            print("pre-show: ",view.frame.origin.y)
            self.view.frame.origin.y -= keyboardSize.height
            print("post-show:",view.frame.origin.y)
        }
    }

    @objc func keyboardWillHide(_ notification: Notification) {
        print("pre-hide: ",view.frame.origin.y)
        self.view.frame.origin.y = 0.0
        print("post-hide:",view.frame.origin.y)
    }

...

}

这是单个显示/隐藏迭代的控制台输出:

Optional(<UIView: 0x7fd6d6522d40; frame = (0 0; 375 758); autoresize = W+H; layer = <CALayer: 0x600000a900c0>>)
pre-show:  0.0
post-show: -278.0
Optional(<UIView: 0x7fd6d6522d40; frame = (0 -278; 375 758); autoresize = W+H; layer = <CALayer: 0x600000a900c0>>)
pre-show:  -278.0
post-show: -614.0
pre-hide:  -614.0
post-hide: 0.0

这是第二次迭代后显示的内容:

Optional(<UIView: 0x7fd6d6522d40; frame = (0 0; 375 758); autoresize = W+H; layer = <CALayer: 0x600000a900c0>>)
pre-show:  0.0
post-show: -69.0
Optional(<UIView: 0x7fd6d6522d40; frame = (0 -69; 375 758); autoresize = W+H; layer = <CALayer: 0x600000a900c0>>)
pre-show:  -69.0
post-show: -405.0
pre-hide:  -405.0
post-hide: 0.0

我不明白为什么 1) 根据控制台输出,当键盘再次向下滑动时,keyboardWillShow 似乎也会被调用 - 所以每个周期两次而不是 1 x 显示和 1 x 隐藏 2) post-show 具有不同的值在第二次迭代中 - 即 -69.0 而不是 -278.0

有人可以帮助我了解这里出了什么问题吗?

标签: swiftnotificationcenter

解决方案


推荐阅读