修复折叠推送点击复制只会复制第一条的问题

This commit is contained in:
Fin 2024-12-30 10:37:40 +08:00
parent 2f554e9e92
commit eb77151fdc
6 changed files with 128 additions and 64 deletions

View File

@ -115,6 +115,7 @@
068EC15827ED99C900D5D11E /* ServerListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068EC15727ED99C900D5D11E /* ServerListViewController.swift */; };
068EC15A27ED99E700D5D11E /* ServerListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068EC15927ED99E700D5D11E /* ServerListViewModel.swift */; };
068F66B3247BD84C00DAD25A /* MessageListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068F66B2247BD84C00DAD25A /* MessageListViewController.swift */; };
0699473D2D223094008D5E40 /* CustomTapTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0699473C2D223094008D5E40 /* CustomTapTextView.swift */; };
06AE3118266F4E2E00B39FBB /* GroupFilterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06AE3117266F4E2E00B39FBB /* GroupFilterViewController.swift */; };
06AE311A266F4E6600B39FBB /* GroupFilterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06AE3119266F4E6600B39FBB /* GroupFilterViewModel.swift */; };
06AE311C266F54A500B39FBB /* GroupTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06AE311B266F54A500B39FBB /* GroupTableViewCell.swift */; };
@ -357,6 +358,7 @@
068EC15727ED99C900D5D11E /* ServerListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerListViewController.swift; sourceTree = "<group>"; };
068EC15927ED99E700D5D11E /* ServerListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerListViewModel.swift; sourceTree = "<group>"; };
068F66B2247BD84C00DAD25A /* MessageListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageListViewController.swift; sourceTree = "<group>"; };
0699473C2D223094008D5E40 /* CustomTapTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTapTextView.swift; sourceTree = "<group>"; };
06AE3117266F4E2E00B39FBB /* GroupFilterViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupFilterViewController.swift; sourceTree = "<group>"; };
06AE3119266F4E6600B39FBB /* GroupFilterViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupFilterViewModel.swift; sourceTree = "<group>"; };
06AE311B266F54A500B39FBB /* GroupTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupTableViewCell.swift; sourceTree = "<group>"; };
@ -681,6 +683,7 @@
066890092D19495400E106F2 /* MessageList */ = {
isa = PBXGroup;
children = (
0699473C2D223094008D5E40 /* CustomTapTextView.swift */,
066890072D1946D500E106F2 /* MessageItemView.swift */,
0667D191247D162C005DE2ED /* MessageTableViewCell.swift */,
0668900A2D19525400E106F2 /* ShowLessAndClearView.swift */,
@ -1238,6 +1241,7 @@
0642B55C27EB149900453D91 /* MutableTextCellViewModel.swift in Sources */,
062B98C8251B27AE004562E7 /* UINavigationItem+Extension.swift in Sources */,
060481EE250F404500BC9799 /* SoundsViewController.swift in Sources */,
0699473D2D223094008D5E40 /* CustomTapTextView.swift in Sources */,
06EEF333291CCFF400CA228A /* CryptoSettingController.swift in Sources */,
0603706D20E23EC000F4CA05 /* BarkSFSafariViewController.swift in Sources */,
06AE311A266F4E6600B39FBB /* GroupFilterViewModel.swift in Sources */,

View File

@ -104,6 +104,23 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
.subscribe(onNext: { [weak self] _ in
self?.tableView.refreshControl?.sendActions(for: .valueChanged)
}).disposed(by: rx.disposeBag)
//
tableView.rx.itemSelected.subscribe(onNext: { [weak self] indexPath in
guard let self else { return }
if let cell = self.tableView.cellForRow(at: indexPath) as? MessageGroupTableViewCell {
if !cell.isExpanded {
UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.2) {
self.tableView.performBatchUpdates {
cell.isExpanded = true
}
}
if let groupName = cell.cellData?.groupName {
self.expandedGroup.insert(groupName)
}
}
}
}).disposed(by: rx.disposeBag)
}
// tableView
@ -120,6 +137,10 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "\(MessageTableViewCell.self)") as? MessageTableViewCell else {
return UITableViewCell()
}
cell.tapAction = { [weak self, weak cell] message, sourceView in
guard let self else { return }
self.alertMessage(message: message.attributedText?.string ?? "", sourceView: sourceView)
}
cell.message = message
return cell
case .messageGroup(let title, let totalCount, let messages):
@ -146,6 +167,10 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
guard let self, let cell, let indexPath = self.tableView.indexPath(for: cell) else { return }
self.tableView.dataSource?.tableView?(self.tableView, commit: .delete, forRowAt: indexPath)
}
cell.tapAction = { [weak self, weak cell] message, sourceView in
guard let self else { return }
self.alertMessage(message: message.attributedText?.string ?? "", sourceView: sourceView)
}
cell.cellData = (title, max(0, totalCount - messages.count), messages)
cell.isExpanded = self.expandedGroup.contains(title)
return cell
@ -161,31 +186,11 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
return
}
let itemSelected = tableView.rx.itemSelected.asDriver().compactMap { [weak self] indexPath -> Int? in
guard let self else { return nil }
if let cell = self.tableView.cellForRow(at: indexPath) as? MessageGroupTableViewCell {
if !cell.isExpanded {
UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.2) {
self.tableView.performBatchUpdates {
cell.isExpanded = true
}
}
if let groupName = cell.cellData?.groupName {
self.expandedGroup.insert(groupName)
}
return nil
}
}
return indexPath.row
}
let output = viewModel.transform(
input: MessageListViewModel.Input(
refresh: tableView.refreshControl!.rx.controlEvent(.valueChanged).asDriver(),
loadMore: tableView.mj_footer!.rx.refresh.asDriver(),
itemDelete: tableView.rx.modelDeleted(MessageListCellItem.self).asDriver(),
itemSelected: itemSelected,
delete: getBatchDeleteDriver(),
groupToggleTap: groupBtn.rx.tap.asDriver(),
searchText: navigationItem.searchController!.searchBar.rx.text.asObservable()
@ -200,11 +205,6 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
.drive(tableView.rx.items(dataSource: dataSource))
.disposed(by: rx.disposeBag)
// messagealert
output.alertMessage.drive(onNext: { [weak self] message in
self?.alertMessage(message: message.0, indexPath: IndexPath(row: message.1, section: 0))
}).disposed(by: rx.disposeBag)
//
output.type
.drive(onNext: { [weak self] type in
@ -266,7 +266,7 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
.asDriver(onErrorDriveWith: .empty())
}
private func alertMessage(message: String, indexPath: IndexPath) {
private func alertMessage(message: String, sourceView: UIView) {
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let copyAction = UIAlertAction(title: NSLocalizedString("CopyAll"), style: .default, handler: { [weak self]
(_: UIAlertAction) in
@ -279,11 +279,9 @@ class MessageListViewController: BaseViewController<MessageListViewModel> {
alertController.addAction(copyAction)
alertController.addAction(cancelAction)
if UIDevice.current.userInterfaceIdiom == .pad {
if let cell = self.tableView.cellForRow(at: indexPath) {
alertController.popoverPresentationController?.sourceView = self.tableView
alertController.popoverPresentationController?.sourceRect = cell.frame
alertController.modalPresentationStyle = .popover
}
alertController.popoverPresentationController?.sourceView = sourceView.superview
alertController.popoverPresentationController?.sourceRect = sourceView.frame
alertController.modalPresentationStyle = .popover
}
self.navigationController?.present(alertController, animated: true, completion: nil)

View File

@ -34,8 +34,6 @@ class MessageListViewModel: ViewModel, ViewModelType {
var loadMore: Driver<Void>
///
var itemDelete: Driver<MessageListCellItem>
///
var itemSelected: Driver<Int>
///
var delete: Driver<MessageDeleteType>
///
@ -49,8 +47,6 @@ class MessageListViewModel: ViewModel, ViewModelType {
var messages: Driver<[MessageSection]>
///
var refreshAction: Driver<MJRefreshAction>
///
var alertMessage: Driver<(String, Int)>
///
var type: Driver<MessageListType>
///
@ -189,26 +185,6 @@ class MessageListViewModel: ViewModel, ViewModelType {
}
func transform(input: Input) -> Output {
let alertMessage = input.itemSelected.map { [weak self] index in
guard let results = self?.results else {
return ("", 0)
}
let message = results[index]
var copyContent: String = ""
if let title = message.title {
copyContent += "\(title)\n"
}
if let body = message.body {
copyContent += "\(body)\n"
}
if let url = message.url {
copyContent += "\(url)\n"
}
copyContent = String(copyContent.prefix(copyContent.count - 1))
return (copyContent, index)
}
//
let titleRelay = BehaviorRelay<String>(value: NSLocalizedString("historyMessage"))
//
@ -384,7 +360,6 @@ class MessageListViewModel: ViewModel, ViewModelType {
return Output(
messages: messagesRelay.asDriver(onErrorJustReturn: []),
refreshAction: refreshAction.asDriver(),
alertMessage: alertMessage,
type: Driver.merge(messageTypeChanged.asDriver(), Driver.just(self.type)),
title: titleRelay.asDriver(),
groupToggleButtonHidden: Driver.just(groupToggleButtonHidden)

View File

@ -0,0 +1,65 @@
//
// CustomTapTextView.swift
// Bark
//
// Created by huangfeng on 12/30/24.
// Copyright © 2024 Fin. All rights reserved.
//
import UIKit
/// UITextView UITextView
/// TextView
class CustomTapTextView: UITextView, UIGestureRecognizerDelegate {
///
private lazy var tapGesture = UITapGestureRecognizer(target: self, action: #selector(tap))
/// tapGesture
private let doubleTapGesture = UITapGestureRecognizer()
///
var customTapAction: (() -> Void)?
init() {
super.init(frame: .zero, textContainer: nil)
self.backgroundColor = UIColor.clear
self.isEditable = false
self.dataDetectorTypes = [.phoneNumber, .link]
self.isScrollEnabled = false
self.textContainerInset = .zero
self.textContainer.lineFragmentPadding = 0
tapGesture.delegate = self
tapGesture.require(toFail: doubleTapGesture)
self.addGestureRecognizer(tapGesture)
doubleTapGesture.numberOfTapsRequired = 2
doubleTapGesture.delegate = self
self.addGestureRecognizer(doubleTapGesture)
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func tap() {
self.customTapAction?()
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == doubleTapGesture {
return true
}
return false
}
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == tapGesture {
if self.selectedRange.length > 0 {
return false
}
}
return super.gestureRecognizerShouldBegin(gestureRecognizer)
}
}

View File

@ -25,14 +25,8 @@ class MessageItemView: UIView {
return view
}()
let bodyLabel: UITextView = {
let label = UITextView()
label.backgroundColor = UIColor.clear
label.isEditable = false
label.dataDetectorTypes = [.phoneNumber, .link]
label.isScrollEnabled = false
label.textContainerInset = .zero
label.textContainer.lineFragmentPadding = 0
let bodyLabel: CustomTapTextView = {
let label = CustomTapTextView()
label.font = UIFont.preferredFont(ofSize: 14)
label.adjustsFontForContentSizeCategory = true
label.textColor = BKColor.grey.darken4
@ -73,6 +67,8 @@ class MessageItemView: UIView {
}
}
var tapAction: ((_ message: MessageItemModel, _ sourceView: UIView) -> Void)?
init() {
super.init(frame: .zero)
self.backgroundColor = BKColor.background.primary
@ -93,6 +89,13 @@ class MessageItemView: UIView {
}
self.dateLabel.text = self.message?.dateText
}).disposed(by: rx.disposeBag)
self.bodyLabel.customTapAction = { [weak self] in
guard let self, let message = self.message else { return }
self.tapAction?(message, self)
}
panel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tap)))
}
@available(*, unavailable)
@ -122,6 +125,11 @@ class MessageItemView: UIView {
make.edges.equalTo(panel)
}
}
@objc func tap() {
guard let message else { return }
self.tapAction?(message, self)
}
}
extension MessageItemView {

View File

@ -23,6 +23,12 @@ class MessageTableViewCell: UITableViewCell {
}
}
var tapAction: ((_ message: MessageItemModel, _ sourceView: UIView) -> Void)? {
didSet {
messageView.tapAction = tapAction
}
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.selectionStyle = .none
@ -136,6 +142,8 @@ class MessageGroupTableViewCell: UITableViewCell {
groupHeader.clearAction = newValue
}
}
var tapAction: ((_ message: MessageItemModel, _ sourceView: UIView) -> Void)? = nil
///
var showGroupMessageAction: ((_ group: String?) -> Void)? = nil
@ -170,6 +178,12 @@ class MessageGroupTableViewCell: UITableViewCell {
moreView.gestureRecognizers?.first?.rx.event.subscribe(onNext: { [weak self] _ in
self?.showGroupMessageAction?(self?.messages.first?.group)
}).disposed(by: self.rx.disposeBag)
for view in messageViews {
view.tapAction = { [weak self] message, sourceView in
self?.tapAction?(message, sourceView)
}
}
refreshViewState()
}