角色标签 列表数据调整
This commit is contained in:
parent
beb0d3518a
commit
626c4d6fb8
|
|
@ -109,7 +109,7 @@ class SessionController: CLBaseViewController {
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
setupUI()
|
setupUI()
|
||||||
setupData()
|
// setupData()
|
||||||
setupEvent()
|
setupEvent()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ struct RoleTagModel: Codable {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RoleTagItem: Codable {
|
struct RoleTagItem: Codable {
|
||||||
var id: Int = 0
|
var id: String = ""
|
||||||
var name: String = ""
|
var name: String = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,28 +15,33 @@ struct RoleListRequest: Codable {
|
||||||
var index = 1
|
var index = 1
|
||||||
var limit = 20
|
var limit = 20
|
||||||
var name: String = ""
|
var name: String = ""
|
||||||
var sourceId = 0
|
var sourceId: String = ""
|
||||||
var tagId: Int?
|
var tagId: [String]?
|
||||||
}
|
}
|
||||||
|
|
||||||
// model
|
// model
|
||||||
struct RoleListModel: Codable {
|
struct RoleListModel: Codable {
|
||||||
var total: Int = 0
|
var total: Int = 0
|
||||||
var index: Int = -1
|
var index: Int = -1
|
||||||
|
var limit: Int = 0
|
||||||
var rows: [RoleItem] = []
|
var rows: [RoleItem] = []
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RoleItem: Codable {
|
struct RoleItem: Codable {
|
||||||
var id: Int = 0
|
var id: String = ""
|
||||||
var name: String = ""
|
var name: String = ""
|
||||||
var coverImage: String = ""
|
var coverImage: String = ""
|
||||||
|
var score: Double?
|
||||||
|
var description: String = ""
|
||||||
var updateTime: String = ""
|
var updateTime: String = ""
|
||||||
var sourceId: Int = 0
|
var sourceId: String = ""
|
||||||
|
var sourceType: Int = 0
|
||||||
|
var commonCount: Int?
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChatRoleViewModel {
|
class ChatRoleViewModel {
|
||||||
|
|
||||||
func loadRoles(index: Int, limit: Int = 20, name: String = "", sourceId: Int = -1, tagId: Int? = nil, completion: ((_ datas: RoleListModel?) -> Void)?) {
|
func loadRoles(index: Int, limit: Int = 10, name: String = "", sourceId: String = "", tagId: [String]? = nil, completion: ((_ datas: RoleListModel?) -> Void)?) {
|
||||||
var req = RoleListRequest()
|
var req = RoleListRequest()
|
||||||
req.index = index
|
req.index = index
|
||||||
req.limit = limit
|
req.limit = limit
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import Foundation
|
||||||
|
|
||||||
struct CLRoleTagsModel: Codable {
|
struct CLRoleTagsModel: Codable {
|
||||||
var name: String = ""
|
var name: String = ""
|
||||||
var id: Int = 0
|
var id: String = ""
|
||||||
var isSelected: Bool = false
|
var isSelected: Bool = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class RolesRootPageController: CLTabRootController<RolesRootPageView> {
|
||||||
var page: Int = 1
|
var page: Int = 1
|
||||||
var viewModel: ChatRoleViewModel = ChatRoleViewModel()
|
var viewModel: ChatRoleViewModel = ChatRoleViewModel()
|
||||||
var tagViewModel: ChatRoleTagViewModel = ChatRoleTagViewModel()
|
var tagViewModel: ChatRoleTagViewModel = ChatRoleTagViewModel()
|
||||||
|
var currentTagIds: [String]? = nil // 当前选中的标签ID数组,nil表示全部
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
@ -31,7 +32,30 @@ class RolesRootPageController: CLTabRootController<RolesRootPageView> {
|
||||||
setupViews()
|
setupViews()
|
||||||
setupEvent()
|
setupEvent()
|
||||||
|
|
||||||
loadRoles(page: 1)
|
// 设置刷新和加载回调
|
||||||
|
container.onRefresh = { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.page = 1
|
||||||
|
self.loadRoles(page: 1, tagIds: self.currentTagIds)
|
||||||
|
}
|
||||||
|
|
||||||
|
container.onLoadMore = { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
// 上拉加载时,先增加 page,然后加载数据
|
||||||
|
// 如果返回的数据为空,page 会在 loadRoles 中回退
|
||||||
|
let nextPage = self.page + 1
|
||||||
|
self.loadRoles(page: nextPage, tagIds: self.currentTagIds, isLoadMore: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置标签选择回调
|
||||||
|
container.tagsView.onTagSelected = { [weak self] tagIds in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.currentTagIds = tagIds
|
||||||
|
self.page = 1
|
||||||
|
self.loadRoles(page: 1, tagIds: tagIds)
|
||||||
|
}
|
||||||
|
|
||||||
|
loadRoles(page: 1, tagIds: nil)
|
||||||
loadTags()
|
loadTags()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,14 +78,42 @@ class RolesRootPageController: CLTabRootController<RolesRootPageView> {
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadRoles(page: Int) {
|
func loadRoles(page: Int, name: String = "", tagIds: [String]? = nil, isLoadMore: Bool = false) {
|
||||||
viewModel.loadRoles(index: page) { [weak self] datas in
|
viewModel.loadRoles(index: page, name: name, tagId: tagIds) { [weak self] datas in
|
||||||
self?.container.config(datas?.rows, isFirstPage: page == 1)
|
guard let self = self else { return }
|
||||||
|
|
||||||
|
// 确保在主线程更新 UI
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
let isFirstPage = page == 1
|
||||||
|
let rows = datas?.rows ?? []
|
||||||
|
let hasData = !rows.isEmpty
|
||||||
|
|
||||||
|
if isLoadMore {
|
||||||
|
// 上拉加载:只有当返回数据时才更新 page,否则保持原值
|
||||||
|
if hasData {
|
||||||
|
// 有数据,更新 page
|
||||||
|
self.page = page
|
||||||
|
// 追加数据
|
||||||
|
self.container.config(rows, isFirstPage: false)
|
||||||
|
} else {
|
||||||
|
// 没有数据,page 保持不变,显示"没有更多数据"
|
||||||
|
self.container.collectionView.mj_footer?.endRefreshingWithNoMoreData()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 下拉刷新或首次加载:直接更新 page
|
||||||
|
self.page = page
|
||||||
|
self.container.config(rows, isFirstPage: isFirstPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 结束刷新动画
|
||||||
|
self.container.endRefreshing()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadTags() {
|
func loadTags() {
|
||||||
tagViewModel.loadRoleTags(name: "") { datas in
|
tagViewModel.loadRoleTags(name: "") { [weak self] datas in
|
||||||
|
guard let self = self else { return }
|
||||||
self.container.configureTags(datas?.rows)
|
self.container.configureTags(datas?.rows)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ import UIKit
|
||||||
class CLRoleTagsView: UIView {
|
class CLRoleTagsView: UIView {
|
||||||
|
|
||||||
// let tags = ["#浪漫", "#温柔", "#多愁善感", "#深情", "#this is good", "#沙瓦迪", "#科技哈", "#等好a", "#a"]
|
// let tags = ["#浪漫", "#温柔", "#多愁善感", "#深情", "#this is good", "#沙瓦迪", "#科技哈", "#等好a", "#a"]
|
||||||
|
// 防止死循环的标志位
|
||||||
|
private var isUpdatingTagModels = false
|
||||||
|
|
||||||
var tagModels: [CLRoleTagsModel] = [
|
var tagModels: [CLRoleTagsModel] = [
|
||||||
// CLRoleTagsModel(name: "#浪漫浪漫浪漫浪漫浪漫浪漫浪漫浪漫浪漫漫浪漫浪漫浪漫漫浪漫浪漫浪漫漫浪漫浪漫浪漫", isSelected: false),
|
// CLRoleTagsModel(name: "#浪漫浪漫浪漫浪漫浪漫浪漫浪漫浪漫浪漫漫浪漫浪漫浪漫漫浪漫浪漫浪漫漫浪漫浪漫浪漫", isSelected: false),
|
||||||
// CLRoleTagsModel(name: "#温柔", isSelected: false),
|
// CLRoleTagsModel(name: "#温柔", isSelected: false),
|
||||||
|
|
@ -22,10 +25,47 @@ class CLRoleTagsView: UIView {
|
||||||
// CLRoleTagsModel(name: "#浪漫", isSelected: false),
|
// CLRoleTagsModel(name: "#浪漫", isSelected: false),
|
||||||
] {
|
] {
|
||||||
didSet {
|
didSet {
|
||||||
|
// 防止死循环:如果正在更新,不执行
|
||||||
|
guard !isUpdatingTagModels else { return }
|
||||||
|
|
||||||
|
// 确保第0个位置是"全部"标签
|
||||||
|
ensureAllTagAtFirst()
|
||||||
self.collectionView.reloadData()
|
self.collectionView.reloadData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 标签选择回调:返回选中的标签ID数组,nil表示全部标签
|
||||||
|
var onTagSelected: (([String]?) -> Void)?
|
||||||
|
|
||||||
|
// 确保第0个位置是"全部"标签
|
||||||
|
private func ensureAllTagAtFirst() {
|
||||||
|
// 如果 tagModels 为空,添加"全部"标签
|
||||||
|
if tagModels.isEmpty {
|
||||||
|
isUpdatingTagModels = true
|
||||||
|
tagModels = [CLRoleTagsModel(name: "All", id: "0", isSelected: true)]
|
||||||
|
isUpdatingTagModels = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查第0个位置是否是"全部"标签
|
||||||
|
let allTagName = "All"
|
||||||
|
if tagModels.first?.name != allTagName {
|
||||||
|
// 如果第0个位置不是"全部"标签,插入到第0个位置
|
||||||
|
let allTag = CLRoleTagsModel(name: allTagName, id: "0", isSelected: true)
|
||||||
|
isUpdatingTagModels = true
|
||||||
|
tagModels.insert(allTag, at: 0)
|
||||||
|
isUpdatingTagModels = false
|
||||||
|
} else {
|
||||||
|
// 如果第0个位置是"全部"标签,确保它是选中状态(如果没有其他标签选中)
|
||||||
|
let hasOtherSelected = tagModels.dropFirst().contains { $0.isSelected }
|
||||||
|
if !hasOtherSelected && !tagModels[0].isSelected {
|
||||||
|
isUpdatingTagModels = true
|
||||||
|
tagModels[0].isSelected = true
|
||||||
|
isUpdatingTagModels = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lazy var collectionView: AutoHeightCollectionView = {
|
lazy var collectionView: AutoHeightCollectionView = {
|
||||||
let layout = TagFlowLayout()
|
let layout = TagFlowLayout()
|
||||||
layout.interItemSpacing = 10 // 横向间距
|
layout.interItemSpacing = 10 // 横向间距
|
||||||
|
|
@ -86,11 +126,55 @@ extension CLRoleTagsView: UICollectionViewDataSource, UICollectionViewDelegate,
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
print("点击了标签:\(tagModels[indexPath.item].name)")
|
let selectedModel = tagModels[indexPath.item]
|
||||||
tagModels[indexPath.item].isSelected.toggle()
|
print("点击了标签:\(selectedModel.name)")
|
||||||
// collectionView.reloadItems(at: [indexPath])
|
|
||||||
collectionView.reloadData()
|
|
||||||
|
|
||||||
|
// 如果点击的是"全部"标签(第0个位置)
|
||||||
|
if indexPath.item == 0 {
|
||||||
|
// 如果"全部"标签已选中,不做任何操作
|
||||||
|
if selectedModel.isSelected {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 取消所有其他标签的选中状态
|
||||||
|
for i in 1..<tagModels.count {
|
||||||
|
tagModels[i].isSelected = false
|
||||||
|
}
|
||||||
|
// 选中"全部"标签
|
||||||
|
tagModels[0].isSelected = true
|
||||||
|
collectionView.reloadData()
|
||||||
|
// 通知外部,选中全部标签(tagId 为 nil)
|
||||||
|
onTagSelected?(nil)
|
||||||
|
} else {
|
||||||
|
// 点击的是其他标签,支持多选
|
||||||
|
tagModels[indexPath.item].isSelected.toggle()
|
||||||
|
|
||||||
|
if tagModels[indexPath.item].isSelected {
|
||||||
|
// 选中了其他标签,取消"全部"标签的选中状态
|
||||||
|
tagModels[0].isSelected = false
|
||||||
|
|
||||||
|
// 获取所有选中的非 All 标签的 ID
|
||||||
|
let selectedIds = tagModels.dropFirst().filter { $0.isSelected }.map { $0.id }
|
||||||
|
collectionView.reloadData()
|
||||||
|
// 通知外部,传递选中的标签ID数组
|
||||||
|
onTagSelected?(selectedIds.isEmpty ? nil : selectedIds)
|
||||||
|
} else {
|
||||||
|
// 取消选中其他标签
|
||||||
|
// 获取所有选中的非 All 标签的 ID
|
||||||
|
let selectedIds = tagModels.dropFirst().filter { $0.isSelected }.map { $0.id }
|
||||||
|
|
||||||
|
if selectedIds.isEmpty {
|
||||||
|
// 如果没有其他标签选中,默认选中"全部"标签
|
||||||
|
tagModels[0].isSelected = true
|
||||||
|
collectionView.reloadData()
|
||||||
|
// 通知外部,选中全部标签(tagId 为 nil)
|
||||||
|
onTagSelected?(nil)
|
||||||
|
} else {
|
||||||
|
collectionView.reloadData()
|
||||||
|
// 通知外部,传递剩余的选中标签ID数组
|
||||||
|
onTagSelected?(selectedIds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据文字计算 size
|
// 根据文字计算 size
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,19 @@ final class CLWaterfallLayout: UICollectionViewLayout {
|
||||||
|
|
||||||
override func prepare() {
|
override func prepare() {
|
||||||
super.prepare()
|
super.prepare()
|
||||||
guard cache.isEmpty, let cv = collectionView else { return }
|
guard let cv = collectionView else { return }
|
||||||
|
|
||||||
|
// 如果缓存不为空,且 item 数量没有变化,则不需要重新计算
|
||||||
|
let itemCount = cv.numberOfItems(inSection: 0)
|
||||||
|
if !cache.isEmpty && cache.count == itemCount {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除旧缓存,重新计算布局
|
||||||
|
cache.removeAll()
|
||||||
contentHeight = sectionInset.top
|
contentHeight = sectionInset.top
|
||||||
colHeight = .init(repeating: sectionInset.top, count: columnCount)
|
colHeight = .init(repeating: sectionInset.top, count: columnCount)
|
||||||
|
|
||||||
let itemCount = cv.numberOfItems(inSection: 0)
|
|
||||||
let totalWidth = cv.bounds.width - sectionInset.left - sectionInset.right
|
let totalWidth = cv.bounds.width - sectionInset.left - sectionInset.right
|
||||||
let cellWidth = (totalWidth - CGFloat(columnCount - 1) * columnSpacing) / CGFloat(columnCount)
|
let cellWidth = (totalWidth - CGFloat(columnCount - 1) * columnSpacing) / CGFloat(columnCount)
|
||||||
|
|
||||||
|
|
@ -56,6 +63,14 @@ final class CLWaterfallLayout: UICollectionViewLayout {
|
||||||
contentHeight = colHeight.max()! + sectionInset.bottom
|
contentHeight = colHeight.max()! + sectionInset.bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func invalidateLayout() {
|
||||||
|
super.invalidateLayout()
|
||||||
|
// 清除缓存,强制重新计算布局
|
||||||
|
cache.removeAll()
|
||||||
|
contentHeight = 0
|
||||||
|
colHeight.removeAll()
|
||||||
|
}
|
||||||
|
|
||||||
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
||||||
cache.filter { $0.frame.intersects(rect) }
|
cache.filter { $0.frame.intersects(rect) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,12 @@ class RolesRootPageView: CLContainer {
|
||||||
// private lazy var pagingView = JXPagingListRefreshView(delegate: self)
|
// private lazy var pagingView = JXPagingListRefreshView(delegate: self)
|
||||||
// lazy var headerView:
|
// lazy var headerView:
|
||||||
|
|
||||||
|
// 刷新和加载回调
|
||||||
|
var onRefresh: (() -> Void)?
|
||||||
|
var onLoadMore: (() -> Void)?
|
||||||
|
|
||||||
var data: [RoleItem] = []
|
var data: [RoleItem] = []
|
||||||
|
var hasMoreData: Bool = true // 是否还有更多数据
|
||||||
|
|
||||||
let remind: [String] = [
|
let remind: [String] = [
|
||||||
"[The Lsat Oracle of Kael]",
|
"[The Lsat Oracle of Kael]",
|
||||||
|
|
@ -73,7 +77,7 @@ class RolesRootPageView: CLContainer {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
|
||||||
setupViews()
|
setupViews()
|
||||||
setupDatas()
|
setupRefresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
|
|
@ -102,19 +106,54 @@ class RolesRootPageView: CLContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupDatas() {
|
// 设置下拉刷新和上拉加载
|
||||||
|
private func setupRefresh() {
|
||||||
|
// 下拉刷新
|
||||||
|
let header = RefreshHeaderAnimator(refreshingBlock: { [weak self] in
|
||||||
|
self?.onRefresh?()
|
||||||
|
})
|
||||||
|
// 设置忽略的 contentInset,确保下拉刷新动画正常显示
|
||||||
|
// header.ignoredScrollViewContentInsetTop = collectionView.contentInset.top
|
||||||
|
collectionView.mj_header = header
|
||||||
|
|
||||||
|
// 上拉加载
|
||||||
|
let footer = RefreshFooterAnimator(refreshingBlock: { [weak self] in
|
||||||
|
self?.onLoadMore?()
|
||||||
|
})
|
||||||
|
collectionView.mj_footer = footer
|
||||||
}
|
}
|
||||||
|
|
||||||
func config(_ data: [RoleItem]?, isFirstPage: Bool){
|
func config(_ data: [RoleItem]?, isFirstPage: Bool){
|
||||||
|
let rows = data ?? []
|
||||||
|
|
||||||
if isFirstPage {
|
if isFirstPage {
|
||||||
self.data = data ?? []
|
// 下拉刷新或首次加载:重置数据
|
||||||
|
self.data = rows
|
||||||
|
// 重置上拉加载状态
|
||||||
|
collectionView.mj_footer?.resetNoMoreData()
|
||||||
} else {
|
} else {
|
||||||
self.data.append(contentsOf: data ?? [])
|
// 上拉加载:追加数据
|
||||||
|
if !rows.isEmpty {
|
||||||
|
self.data.append(contentsOf: rows)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否还有更多数据
|
||||||
|
// 如果返回的数据为空,或者数据量小于每页数量(10),说明没有更多数据了
|
||||||
|
if rows.isEmpty || rows.count < 10 {
|
||||||
|
hasMoreData = false
|
||||||
|
} else {
|
||||||
|
hasMoreData = true
|
||||||
}
|
}
|
||||||
self.collectionView.reloadData()
|
self.collectionView.reloadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 结束刷新动画
|
||||||
|
func endRefreshing() {
|
||||||
|
collectionView.mj_header?.endRefreshing()
|
||||||
|
collectionView.mj_footer?.endRefreshing()
|
||||||
|
}
|
||||||
|
|
||||||
func configureTags(_ data: [RoleTagItem]?) {
|
func configureTags(_ data: [RoleTagItem]?) {
|
||||||
guard let tags = data else {
|
guard let tags = data else {
|
||||||
self.tagsView.tagModels = []
|
self.tagsView.tagModels = []
|
||||||
|
|
@ -132,19 +171,31 @@ extension RolesRootPageView: UICollectionViewDelegate, UICollectionViewDataSourc
|
||||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
let cell: CLRoleCollectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "CLRoleCollectionCell", for: indexPath) as! CLRoleCollectionCell
|
let cell: CLRoleCollectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "CLRoleCollectionCell", for: indexPath) as! CLRoleCollectionCell
|
||||||
|
|
||||||
|
// 使用 indexPath.item 而不是 indexPath.row(UICollectionView 应该使用 item)
|
||||||
|
guard indexPath.item < data.count else {
|
||||||
|
return cell
|
||||||
|
}
|
||||||
cell.setupData(item: data[indexPath.item])
|
cell.setupData(item: data[indexPath.item])
|
||||||
|
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
|
if data.count > indexPath.item {
|
||||||
|
let item = data[indexPath.item]
|
||||||
let sessionId = "439217670979585@r@t"
|
let sessionId = "439217670979585@r@t"
|
||||||
AppRouter.goChatVC(conversationId: sessionId, title: "Character · 18", complete: nil)
|
AppRouter.goChatVC(conversationId: sessionId, title: item.name, complete: nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView,
|
func collectionView(_ collectionView: UICollectionView,
|
||||||
layout: CLWaterfallLayout,
|
layout: CLWaterfallLayout,
|
||||||
heightForItemAt indexPath: IndexPath) -> CGFloat {
|
heightForItemAt indexPath: IndexPath) -> CGFloat {
|
||||||
|
// 防止数组越界
|
||||||
|
guard indexPath.item < data.count else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
let model = data[indexPath.item]
|
let model = data[indexPath.item]
|
||||||
|
|
||||||
let coverH = itemWidth * (4.0 / 3.0)
|
let coverH = itemWidth * (4.0 / 3.0)
|
||||||
|
|
@ -164,7 +215,10 @@ extension RolesRootPageView: UICollectionViewDelegate, UICollectionViewDataSourc
|
||||||
// 取最小值,保证不足 3 行时按实际算,超过 3 行时截断在 3 行高
|
// 取最小值,保证不足 3 行时按实际算,超过 3 行时截断在 3 行高
|
||||||
let textH = min(textSize.height, maxHeight)
|
let textH = min(textSize.height, maxHeight)
|
||||||
|
|
||||||
let remindH = remind[indexPath.item].boundingRect(
|
// 防止 remind 数组越界,使用模运算或默认值
|
||||||
|
let remindIndex = indexPath.item % remind.count
|
||||||
|
let remindText = remind[remindIndex]
|
||||||
|
let remindH = remindText.boundingRect(
|
||||||
with: CGSize(width: itemWidth - 20.0, height: .greatestFiniteMagnitude),
|
with: CGSize(width: itemWidth - 20.0, height: .greatestFiniteMagnitude),
|
||||||
options: .usesLineFragmentOrigin,
|
options: .usesLineFragmentOrigin,
|
||||||
attributes: [.font: UIFont.boldSystemFont(ofSize: 10)],
|
attributes: [.font: UIFont.boldSystemFont(ofSize: 10)],
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ extension AppRouter{
|
||||||
}
|
}
|
||||||
|
|
||||||
static func goChatVC(conversationId: String?, title: String? = nil, complete: (() -> Void)? = nil) {
|
static func goChatVC(conversationId: String?, title: String? = nil, complete: (() -> Void)? = nil) {
|
||||||
guard UserCore.shared.checkUserLoginIfNotPushUserToLogin() else{return}
|
// guard UserCore.shared.checkUserLoginIfNotPushUserToLogin() else{return}
|
||||||
|
|
||||||
guard let sessionId = conversationId else{return}
|
guard let sessionId = conversationId else{return}
|
||||||
let vc = SessionController(conversationId: sessionId, title: title)
|
let vc = SessionController(conversationId: sessionId, title: title)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue