问题
I've got a UIViewController with a UITableView. I'm using NotificationCenter to set the y-coordinates for the view to adjust when the keyboard shows and hides again. For the first show + hide, everything looks fine. Doing it a second time messes up things on the screen. I've included print statements in the show / hide actions to get to the bottom of it - see below.
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)
}
...
}
This is the console output for a single show / hide iteration:
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
And this is what is shown after the second iteration:
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
I don't understand why 1) according to the console output, keyboardWillShow seems to also get called when the keyboard slides down again - so twice per single cycle instead of 1 x show and 1 x hide 2) post-show has a different value in the second iteration - i.e. -69.0 instead of -278.0
Can someone help me to understand what's going wrong here?
来源:https://stackoverflow.com/questions/59789728/notificationcenter-toggling-keyboard-multiple-times-sets-y-position-to-weird-va