toolBarView.snp.makeConstraints { (make) in
make.left.equalTo(view.snp.left)
make.right.equalTo(view.snp.right)
make.height.equalTo(toolBarHeight)
make.bottom.equalTo(view.snp.bottom)
}
chatTableView.snp.makeConstraints { (make) in
make.left.equalTo(view.snp.left)
make.right.equalTo(view.snp.right)
make.bottom.equalTo(toolBarView.snp.top)
make.top.equalTo(view.snp.top).offset(64)
}
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
func keyBoardWillShow(notification: Notification) {
let userInfo = notification.userInfo! as Dictionary
let value = userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue
let keyBoardRect = value.cgRectValue
// 得到键盘高度
let keyBoardHeight = keyBoardRect.size.height
mKeyBoardHeight = keyBoardHeight
// 得到键盘弹出所需时间
let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
mKeyBoardAnimateDuration = duration.doubleValue
...
}
var animate: (()->Void) = {
let newFrame = CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: SCREEN_HEIGHT - mKeyBoardHeight)
self.toolBarView.frame = newFrame
}
UIView.animate(withDuration: mKeyBoardAnimateDuration,
delay: 0, options: options, animations: animate)
var animate: (()->Void) = {
self.toolBarView.snp.updateConstraints(closure: { (make) in
make.bottom.equalTo(self.view.snp_bottom).offset(-mKeyBoardHeight)
}
}
UIView.animate(withDuration: mKeyBoardAnimateDuration,
delay: 0, options: options, animations: animate)
var animate: (()->Void) = {
self.toolBarView.transform = CGAffineTransform(translationX: 0, y: -keyBoardHeight)
}
let options = UIViewAnimationOptions(rawValue: UInt((userInfo[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).intValue << 16))
UIView.animate(withDuration: mKeyBoardAnimateDuration, delay: 0, options: options, animations: animate)
enum AnimateType {
case animate1 // 键盘弹出的话不会遮挡消息
case animate2 // 键盘弹出的话会遮挡消息,但最后一条消息距离输入框有一段距离
case animate3 // 最后一条消息距离输入框在小范围内,这里设为 30
}
var animate: (()->Void) = {
self.toolBarView.transform = CGAffineTransform(translationX: 0, y: -keyBoardHeight)
}
let lastIndex = IndexPath(row: msgList.count - 1, section: 0) let rectCellView = chatTableView.rectForRow(at: lastIndex) let rect = chatTableView.convert(rectCellView, to: chatTableView.superview) let cellDistance = rect.origin.y + rect.height
let distance1 = SCREEN_HEIGHT - toolBarHeight - keyBoardHeight let distance2 = SCREEN_HEIGHT - toolBarHeight - 2 * fitBlank
let difY = cellDistance - distance1
if cellDistance <= distance1 {
animate = {
self.toolBarView.transform = CGAffineTransform(translationX: 0, y: -keyBoardHeight)
}
animateType = .animate1
} else if distance1 < cellDistance && cellDistance <= distance2 {
animate = {
self.toolBarView.transform = CGAffineTransform(translationX: 0, y: -keyBoardHeight)
self.chatTableView.transform = CGAffineTransform(translationX: 0, y: -difY)
self.lastDifY = difY //这里记录下最后一次滑动的dif值,以后有用
}
animateType = .animate2
} else {
animate = {
self.view.transform = CGAffineTransform(translationX: 0, y: -keyBoardHeight)
}
animateType = .animate3
}
// 返回 view 或 toolBarView 或 chatTableView 到原有状态
switch animateType {
case .animate1:
animate = {
self.toolBarView.transform = CGAffineTransform.identity
self.chatTableView.transform = CGAffineTransform.identity
}
case .animate2:
animate = {
self.toolBarView.transform = CGAffineTransform.identity
self.chatTableView.transform = CGAffineTransform.identity
}
case .animate3:
animate = {
self.view.transform = CGAffineTransform.identity
}
}
// 刷新列表
func reloadTableView() {
chatTableView.reloadData()
chatTableView.layoutIfNeeded()
// 得到最后一条消息在view中的位置
let lastIndex = IndexPath(row: msgList.count - 1, section: 0)
let rectCellView = chatTableView.rectForRow(at: lastIndex)
let rect = chatTableView.convert(rectCellView, to: chatTableView.superview)
let cellDistance = rect.origin.y + rect.height
let distance1 = SCREEN_HEIGHT - toolBarHeight - mKeyBoardHeight
// 计算键盘可能遮住的消息的长度
let difY = cellDistance - distance1
if animateType == .animate3 {
// 处于情况三时,由于之前的约束(聊天界面在输入栏上方),并且
// 是整个界面一起上滑,所以约束依旧成立,只需把聊天界面最后
// 一条消息滚动到聊天界面底部即可
scrollToBottom()
} else if (animateType == .animate1 || animateType == .animate2) && difY > 0{
// 在情况一和情况二中,如果聊天界面上滑的总距离小于键盘高度,则可以继续上滑
// 一旦聊天界面上滑的总距离 lastDifY + difY 将要超过键盘高度,则上滑总距离设为键盘高度
// 此时执行 trans 动画
// 一旦聊天界面上滑总距离为键盘高度,则变为情况三的情况,把聊天界面最后
// 一条消息滚动到聊天界面底部即可
if lastDifY + difY < mKeyBoardHeight {
lastDifY += difY
let animate: (()->Void) = {
self.chatTableView.transform = CGAffineTransform(translationX: 0, y: -self.lastDifY)
}
UIView.animate(withDuration: mKeyBoardAnimateDuration, delay: 0, options: animateOption, animations: animate)
} else if lastDifY + difY > mKeyBoardHeight {
if lastDifY != mKeyBoardHeight {
let animate: (()->Void) = {
self.chatTableView.transform = CGAffineTransform(translationX: 0, y: -self.mKeyBoardHeight)
}
UIView.animate(withDuration: mKeyBoardAnimateDuration, delay: 0, options: animateOption, animations: animate)
lastDifY = mKeyBoardHeight
}
scrollToBottom()
}
}
}
func scrollToBottom() {
if msgList.count > 0 {
chatTableView.scrollToRow(at: IndexPath(row: msgList.count - 1, section: 0), at: .bottom, animated: true)
}
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有