角色设置处理sound中的数据切换保存问题
This commit is contained in:
parent
8b1727fcaa
commit
2d4c80e084
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
|
|
@ -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以更新头像
|
||||
|
|
|
|||
Loading…
Reference in New Issue