角色设置处理sound中的数据切换保存问题

This commit is contained in:
mh 2025-11-06 15:53:46 +08:00
parent 8b1727fcaa
commit 2d4c80e084
2 changed files with 97 additions and 13 deletions

View File

@ -39,13 +39,19 @@ class VoiceActorContainerCell: UITableViewCell, CellConfigurable {
private var filteredItems: [VoiceActorItem] = []
private var selectedItemId: String?
private var tableViewHeightConstraint: Constraint?
private var currentFilterType: VoiceActorFilterView.FilterType = .all
var selectedItemChanged: ((VoiceActorItem) -> Void)? //
var filterTypeChanged: ((VoiceActorFilterView.FilterType) -> Void)? //
// MARK: -
private lazy var filterView: VoiceActorFilterView = {
let view = VoiceActorFilterView()
view.filterChanged = { [weak self] filterType in
self?.filterItems(by: filterType)
guard let self = self else { return }
self.currentFilterType = filterType
self.filterItems(by: filterType)
//
self.filterTypeChanged?(filterType)
}
return view
}()
@ -89,7 +95,7 @@ class VoiceActorContainerCell: UITableViewCell, CellConfigurable {
filterView.snp.makeConstraints { make in
make.left.right.equalToSuperview().inset(20)
make.top.equalToSuperview().offset(2.5)
make.height.equalTo(50)
make.height.equalTo(50).priority(.required) //
}
tableView.snp.makeConstraints { make in
@ -109,7 +115,24 @@ class VoiceActorContainerCell: UITableViewCell, CellConfigurable {
selectedItemId = selected.id
}
filterItems(by: .all)
// 使 .all
// filterView restoreFilterType
filterItems(by: currentFilterType)
}
//
func restoreFilterType(_ filterType: VoiceActorFilterView.FilterType) {
currentFilterType = filterType
// UI
filterView.selectedFilter = filterType
filterView.updateButtonStates()
// items
filterItems(by: filterType)
}
//
func getCurrentFilterType() -> VoiceActorFilterView.FilterType {
return currentFilterType
}
private func filterItems(by filterType: VoiceActorFilterView.FilterType) {
@ -138,7 +161,7 @@ class VoiceActorContainerCell: UITableViewCell, CellConfigurable {
private func updateTableViewHeight() {
let rowHeight: CGFloat = 80
let maxRows: CGFloat = 5.5
let displayCount = min(CGFloat(filteredItems.count), maxRows)
let displayCount = min(CGFloat(allItems.count), maxRows)
let height = displayCount * rowHeight
tableViewHeightConstraint?.update(offset: height)
@ -176,8 +199,10 @@ extension VoiceActorContainerCell: UITableViewDataSource, UITableViewDelegate {
tableView.reloadData()
//
selectedItemChanged?(item)
// item
if let updatedItem = allItems.first(where: { $0.id == item.id }) {
selectedItemChanged?(updatedItem)
}
}
// func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
@ -333,7 +358,7 @@ class VoiceActorFilterView: UIView {
filterChanged?(selectedFilter)
}
private func updateButtonStates() {
func updateButtonStates() {
let buttons = [allButton, maleButton, femaleButton]
let filters: [FilterType] = [.all, .male, .female]

View File

@ -18,6 +18,9 @@ class ChatSettingSwipeView: CLContainer {
// section -> rowIndex -> isExpanded
private var expandedStates: [Int: [Int: Bool]] = [:]
// Voice Actor section -> rowIndex -> (items, filterType)
private var voiceActorStates: [Int: [Int: (items: [VoiceActorItem], filterType: VoiceActorFilterView.FilterType)]] = [:]
override init(frame: CGRect) {
super.init(frame: frame)
@ -203,17 +206,43 @@ extension ChatSettingSwipeView: UITableViewDelegate, UITableViewDataSource {
expandedStates[indexPath.section, default: [:]][indexPath.row] = !isExpanded
if !isExpanded {
// VoiceActorRow
let actorRow = VoiceActorRow(items: voiceActorItems)
// 使使
let savedState = voiceActorStates[indexPath.section]?[indexPath.row]
let itemsToUse = savedState?.items ?? voiceActorItems
let filterTypeToUse = savedState?.filterType ?? .all
//
if savedState == nil {
voiceActorStates[indexPath.section, default: [:]][indexPath.row] = (items: voiceActorItems, filterType: .all)
}
let actorRow = VoiceActorRow(items: itemsToUse)
rows[indexPath.section].insert(actorRow, at: indexPath.row + 1)
let insertIndexPath = IndexPath(row: indexPath.row + 1, section: indexPath.section)
tableView.performBatchUpdates({
tableView.insertRows(at: [insertIndexPath], with: .fade)
tableView.reloadRows(at: [indexPath], with: .none)
}, completion: nil)
}, completion: { [weak self] _ in
// cell
DispatchQueue.main.async {
if let cell = self?.tableView.cellForRow(at: insertIndexPath) as? VoiceActorContainerCell {
cell.restoreFilterType(filterTypeToUse)
}
}
})
} else {
//
//
if indexPath.row + 1 < rows[indexPath.section].count,
let actorRow = rows[indexPath.section][indexPath.row + 1] as? VoiceActorRow,
let cell = tableView.cellForRow(at: IndexPath(row: indexPath.row + 1, section: indexPath.section)) as? VoiceActorContainerCell {
//
let currentFilterType = cell.getCurrentFilterType()
//
voiceActorStates[indexPath.section, default: [:]][indexPath.row] = (items: actorRow.items, filterType: currentFilterType)
}
//
if indexPath.row + 1 < rows[indexPath.section].count,
rows[indexPath.section][indexPath.row + 1] is VoiceActorRow {
rows[indexPath.section].remove(at: indexPath.row + 1)
@ -347,9 +376,33 @@ extension ChatSettingSwipeView: UITableViewDelegate, UITableViewDataSource {
let cell = tableView.dequeueReusableCell(withIdentifier: "VoiceActorContainerCell", for: indexPath) as! VoiceActorContainerCell
cell.selectionStyle = .none
// cell
// cell
cell.selectedItemChanged = { [weak self] item in
self?.updateVoiceActorAvatar(item, at: indexPath.section, rowIndex: indexPath.row - 1)
guard let self = self else { return }
self.updateVoiceActorAvatar(item, at: indexPath.section, rowIndex: indexPath.row - 1)
//
if var savedState = self.voiceActorStates[indexPath.section]?[indexPath.row - 1] {
savedState.items = savedState.items.map { var i = $0; i.isSelected = (i.id == item.id); return i }
self.voiceActorStates[indexPath.section]?[indexPath.row - 1] = savedState
}
// VoiceActorRow items
if var actorRow = self.rows[indexPath.section][indexPath.row] as? VoiceActorRow {
actorRow = VoiceActorRow(items: actorRow.items.map { var i = $0; i.isSelected = (i.id == item.id); return i })
self.rows[indexPath.section][indexPath.row] = actorRow
}
}
//
cell.filterTypeChanged = { [weak self] filterType in
guard let self = self else { return }
// VoiceActorRow items
if let actorRow = self.rows[indexPath.section][indexPath.row] as? VoiceActorRow {
//
var savedState = self.voiceActorStates[indexPath.section]?[indexPath.row - 1] ?? (items: actorRow.items, filterType: .all)
savedState.filterType = filterType
savedState.items = actorRow.items // items
self.voiceActorStates[indexPath.section, default: [:]][indexPath.row - 1] = savedState
}
}
cell.configure(with: actorRow)
@ -467,6 +520,12 @@ extension ChatSettingSwipeView: UITableViewDelegate, UITableViewDataSource {
voiceActorItems: voiceActorItems
)
rows[section][rowIndex] = updatedRow
//
if var savedState = voiceActorStates[section]?[rowIndex] {
savedState.items = voiceActorItems
voiceActorStates[section]?[rowIndex] = savedState
}
}
// cell