role聊天快捷滚动到底部

This commit is contained in:
mh 2025-12-08 14:07:44 +08:00
parent 696ec2c0ec
commit 8559a6c35a
4 changed files with 62 additions and 5 deletions

View File

@ -88,6 +88,7 @@ extension SessionController {
DispatchQueue.main.async {[weak self] in DispatchQueue.main.async {[weak self] in
self?.scrollToBottom(self?.tableView) self?.scrollToBottom(self?.tableView)
self?.updateScrToBottomButtonVisibility()
} }
} }
@ -99,7 +100,7 @@ extension SessionController {
let delaySeconds = delay ?? 0 let delaySeconds = delay ?? 0
// let y = max(table.contentSize.height - table.bounds.size.height, 0) // let y = max(table.contentSize.height - table.bounds.size.height, 0)
// table.setContentOffset(CGPoint(x: 0, y: y), animated: animated) // table.setContentOffset(CGPoint(x: 0, y: y), animated: animated)
DispatchQueue.main.asyncAfter(deadline: .now() + delaySeconds) {[weak self] in DispatchQueue.main.asyncAfter(deadline: .now() + delaySeconds) {[weak self] in
if self?.isStreamChatMode == true { if self?.isStreamChatMode == true {
let count = self?.streamMessages.count ?? 0 let count = self?.streamMessages.count ?? 0
if count > 0 { if count > 0 {
@ -111,6 +112,10 @@ extension SessionController {
table.scrollToRow(at: IndexPath(row: count - 1, section: 1), at: .bottom, animated: animated) table.scrollToRow(at: IndexPath(row: count - 1, section: 1), at: .bottom, animated: animated)
} }
} }
//
DispatchQueue.main.asyncAfter(deadline: .now() + (animated ? 0.3 : 0.1)) {
self?.updateScrToBottomButtonVisibility()
}
// Initial state // Initial state
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
if table.alpha == 0{ if table.alpha == 0{
@ -295,7 +300,7 @@ extension SessionController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {} func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}
func scrollViewDidScroll(_ scrollView: UIScrollView) { func scrollViewDidScroll(_ scrollView: UIScrollView) {
//... updateScrToBottomButtonVisibility()
} }
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
@ -350,6 +355,48 @@ extension SessionController: UITableViewDelegate {
UIPasteboard.general.string = text UIPasteboard.general.string = text
Hud.toast(str: "复制成功") Hud.toast(str: "复制成功")
} }
/// /
func updateScrToBottomButtonVisibility() {
guard let tableView = tableView, let scrToBottomBtn = scrToBottomBtn else { return }
//
let hasContent: Bool
if isStreamChatMode {
hasContent = streamMessages.count > 0
} else {
hasContent = util.cellModels.count > 0
}
guard hasContent else {
scrToBottomBtn.isHidden = true
return
}
//
let contentHeight = tableView.contentSize.height
let tableViewHeight = tableView.bounds.height
let offsetY = tableView.contentOffset.y
let contentInsetTop = tableView.contentInset.top
let contentInsetBottom = tableView.contentInset.bottom
// inset
let actualContentHeight = contentHeight - contentInsetTop - contentInsetBottom
let actualTableViewHeight = tableViewHeight - contentInsetTop - contentInsetBottom
// tableView
guard actualContentHeight > actualTableViewHeight else {
scrToBottomBtn.isHidden = true
return
}
//
let distanceFromBottom = actualContentHeight - (offsetY - contentInsetTop) - actualTableViewHeight
// 50pt
//
scrToBottomBtn.isHidden = distanceFromBottom <= 50
}
} }

View File

@ -51,6 +51,10 @@ extension SessionController {
let scrToBottomBtn = UIButton(type: .custom) let scrToBottomBtn = UIButton(type: .custom)
scrToBottomBtn.setImage(UIImage(named: "chat_scr_bottom"), for: .normal) scrToBottomBtn.setImage(UIImage(named: "chat_scr_bottom"), for: .normal)
scrToBottomBtn.addTarget(self, action: #selector(scrToBottomBtnTap), for: .touchUpInside) scrToBottomBtn.addTarget(self, action: #selector(scrToBottomBtnTap), for: .touchUpInside)
scrToBottomBtn.isHidden = true //
//
self.scrToBottomBtn = scrToBottomBtn
let stackView = UIStackView(arrangedSubviews: [scrToBottomBtn, exchangeBtn]) let stackView = UIStackView(arrangedSubviews: [scrToBottomBtn, exchangeBtn])
stackView.spacing = 10.0 stackView.spacing = 10.0

View File

@ -31,6 +31,7 @@ class SessionController: CLBaseViewController {
// MARK: BottomViews // MARK: BottomViews
var bottomViewsStackV : InputStackView! var bottomViewsStackV : InputStackView!
var toolView: UIView! var toolView: UIView!
var scrToBottomBtn: UIButton!
var inputEntrance: SessionInputOperateView! var inputEntrance: SessionInputOperateView!
var inputBar: SessionInputView! var inputBar: SessionInputView!
var moreView: IMMoreItemView! var moreView: IMMoreItemView!
@ -251,7 +252,7 @@ extension SessionController {
} }
return v return v
}() }()
// bgImageView.image = UIImage(named: "egpic")?.cropImageTop(with: 1 / UIScreen.aspectRatio) bgImageView.image = UIImage(named: "egpic")?.cropImageTop(with: 1 / UIScreen.aspectRatio)
overlay = { overlay = {
let v = GradientView(colors: [UIColor.c.cbn.withAlphaComponent(1), UIColor.c.cbn.withAlphaComponent(0), UIColor.c.cbn.withAlphaComponent(0), UIColor.c.cbn.withAlphaComponent(1)], gradientType: .topToBottom) let v = GradientView(colors: [UIColor.c.cbn.withAlphaComponent(1), UIColor.c.cbn.withAlphaComponent(0), UIColor.c.cbn.withAlphaComponent(0), UIColor.c.cbn.withAlphaComponent(1)], gradientType: .topToBottom)
@ -274,7 +275,8 @@ extension SessionController {
swipeBgView = { swipeBgView = {
let bgView = UIView() let bgView = UIView()
bgView.alpha = 0.0 bgView.alpha = 0.0
bgView.backgroundColor = UIColor.init(white: 0.0, alpha: 0.8) // bgView.backgroundColor = UIColor.init(white: 0.0, alpha: 0.8)
bgView.backgroundColor = .clear
view.addSubview(bgView) view.addSubview(bgView)
bgView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(bgViewTap))) bgView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(bgViewTap)))
bgView.snp.makeConstraints { make in bgView.snp.makeConstraints { make in
@ -655,6 +657,7 @@ extension SessionController {
self.startDisplayLinkIfNeeded() self.startDisplayLinkIfNeeded()
self.smoothScrollToLatest() self.smoothScrollToLatest()
self.updateScrToBottomButtonVisibility()
} }
} }
@ -672,6 +675,7 @@ extension SessionController {
tableView.endUpdates() tableView.endUpdates()
} }
smoothScrollToLatest() smoothScrollToLatest()
updateScrToBottomButtonVisibility()
} }
private func finalizeStreamingMessage() { private func finalizeStreamingMessage() {
@ -695,6 +699,7 @@ extension SessionController {
self.startDisplayLinkIfNeeded() self.startDisplayLinkIfNeeded()
} }
self.updateScrToBottomButtonVisibility()
IMSSEManager.shared.disconnect() IMSSEManager.shared.disconnect()
} }
} }
@ -835,6 +840,7 @@ extension SessionController {
tableView.endUpdates() tableView.endUpdates()
} }
smoothScrollToLatest() smoothScrollToLatest()
updateScrToBottomButtonVisibility()
} }
cleanupTypingState() cleanupTypingState()
} }

View File

@ -174,7 +174,7 @@ class SessionNavigationView: UIView {
make.leading.equalToSuperview() make.leading.equalToSuperview()
make.trailing.equalToSuperview() make.trailing.equalToSuperview()
make.height.equalTo(UIWindow.navBarTotalHeight) make.height.equalTo(UIWindow.navBarTotalHeight)
make.bottom.equalToSuperview().offset(-40) make.bottom.equalToSuperview().offset(0)
} }
} }