swift - 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
有人可以帮助我了解这里出了什么问题吗?
解决方案
推荐阅读
- java - NetBeans 中的调试器输出
- c# - EF Core:找不到实体类型属性的支持字段,并且该属性没有 getter
- reactjs - 使用 SVG 的自定义 Material-UI 按钮?
- python - 如何正确使用 Dataflow / Apache beam wait_until_finish 持续时间参数?
- flutter - 仅当 Firestore 字段没有值时才显示底页
- android - 为什么 DecorView 会变为 null?
- c# - 一次签署多个 PDF 文件 / 批处理 / iText7
- javascript - Jest 抛出关于缺少全局函数的错误(vue.prototype)
- android - 使用风味构建后的 apk 中的恶意软件
- continuous-integration - CircleCI 缓存键不匹配