From beb0d3518acd07f829b621b2dd4257ddfbacbf7c Mon Sep 17 00:00:00 2001 From: mh <729263080@qq.com> Date: Fri, 7 Nov 2025 16:03:08 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=92=E8=89=B2=E5=88=97=E8=A1=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=AE=8C=E5=96=84=20+=20=E8=A1=A8=E6=83=85=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../role_type_play.imageset/Contents.json | 22 ++++++ .../role_type_play@2x.png | Bin 0 -> 951 bytes .../role_type_play@3x.png | Bin 0 -> 1898 bytes .../role_type_read.imageset/Contents.json | 22 ++++++ .../role_type_read@2x.png | Bin 0 -> 1025 bytes .../role_type_read@3x.png | Bin 0 -> 1854 bytes Visual_Novel_iOS/Src/API/RoleTagApi.swift | 67 ++++++++++++++++++ .../Setting/Model/ChatRoleTagViewModel.swift | 49 +++++++++++++ .../Setting/Model/ChatRoleViewModel.swift | 6 +- .../Modules/Home/HomePageRootController.swift | 8 +-- .../Modules/Roles/Model/CLRoleTagsModel.swift | 9 +++ .../Roles/RolesRootPageController.swift | 25 ++++--- .../Roles/View/CLRoleCollectionCell.swift | 52 ++++++++++++-- .../Modules/Roles/View/CLRoleTagsView.swift | 24 ++++--- .../Roles/View/RolesRootPageView.swift | 54 +++++++++----- 15 files changed, 287 insertions(+), 51 deletions(-) create mode 100644 Visual_Novel_iOS/Assets.xcassets/Role/role_type_play.imageset/Contents.json create mode 100644 Visual_Novel_iOS/Assets.xcassets/Role/role_type_play.imageset/role_type_play@2x.png create mode 100644 Visual_Novel_iOS/Assets.xcassets/Role/role_type_play.imageset/role_type_play@3x.png create mode 100644 Visual_Novel_iOS/Assets.xcassets/Role/role_type_read.imageset/Contents.json create mode 100644 Visual_Novel_iOS/Assets.xcassets/Role/role_type_read.imageset/role_type_read@2x.png create mode 100644 Visual_Novel_iOS/Assets.xcassets/Role/role_type_read.imageset/role_type_read@3x.png create mode 100644 Visual_Novel_iOS/Src/API/RoleTagApi.swift create mode 100644 Visual_Novel_iOS/Src/Modules/Chat/Setting/Model/ChatRoleTagViewModel.swift diff --git a/Visual_Novel_iOS/Assets.xcassets/Role/role_type_play.imageset/Contents.json b/Visual_Novel_iOS/Assets.xcassets/Role/role_type_play.imageset/Contents.json new file mode 100644 index 0000000..8bb8318 --- /dev/null +++ b/Visual_Novel_iOS/Assets.xcassets/Role/role_type_play.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "role_type_play@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "role_type_play@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Visual_Novel_iOS/Assets.xcassets/Role/role_type_play.imageset/role_type_play@2x.png b/Visual_Novel_iOS/Assets.xcassets/Role/role_type_play.imageset/role_type_play@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f93bb8556b802dc304c5fd381af3f21b26b79f0e GIT binary patch literal 951 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 literal 0 HcmV?d00001 diff --git a/Visual_Novel_iOS/Assets.xcassets/Role/role_type_read.imageset/Contents.json b/Visual_Novel_iOS/Assets.xcassets/Role/role_type_read.imageset/Contents.json new file mode 100644 index 0000000..8555513 --- /dev/null +++ b/Visual_Novel_iOS/Assets.xcassets/Role/role_type_read.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "role_type_read@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "role_type_read@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Visual_Novel_iOS/Assets.xcassets/Role/role_type_read.imageset/role_type_read@2x.png b/Visual_Novel_iOS/Assets.xcassets/Role/role_type_read.imageset/role_type_read@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..961f3b0579fbb2ee2d086d858476cfb98a591fdb GIT binary patch literal 1025 zcmV+c1pfPpP)pnrUiAqo|o7Ea`WVt|FsV77@7!L)!!quB=T_xhV+x+eMp7`U6*z z5~NMFu|Wt;B+79RLD7x2sfI#)uXEm;H@tV}&N!n!ICJkk_dDNr&$;Kl5h&^jmjl~l z9z+@hqSpl?4+Nr*E#vu)R^9`mdyAqY&;r8Yaw4o3D8D7(X*HnLQA{PE(Ls=TcrIeR zM`RZTBDXmPsPJb1%7L&-KgzJZjs=PEI9x(l;L-dXBj9ZXA~pHIN?|&2gAPvvN)m+h zXnp~$nYo~NgzWPm+H6=QmA4kPW-bqQG|Ry*VGlKr0pu-@99-<$fT&?^C*C0(sWFx@ zQ>O^eE$$dMCoho^uAuusz3FlMoNYW28vge7`0w;^)4Y+qz&1Ai@pMn`v%@y*$bTVgiG9t8|)RDLyK347qJ1vFRtx3#szoy(l z!rhr&C?;P9I?u8xwp^}Ic%$;3DPtGTT!g|w71-P>^=I>@K%R2LNXulqtE2f!BtsWm z2ZI|_Nu()bV^)q11U4v7DdUP+$6}G3&emZ}2pw8dCLrM@ceKs9-oH+j#3W^`f3-pO zI5YEe&YmxIOe6+!DoS7K5fc783F)3+zwDZ-tf*~2xc}s9*%}*LyW{b`Y?V4Ydxy`R zyWAz?c+DKW@A_ulhv%zJ4w3LwT89>QZvxX(Gyet$zyFer4|VM5`A_}*L*w!HeaX|O zE+t;Qcrz{Ic+DI#FKK;d9|`mD=YyOzdkb0Zp));AO;-|yFu8l2t;dYX2y@nYcP_B7 zN0m{b2p#AGewd}t2s3;vPHmo3a^6`Ev$#`cw#?@c=4GlwgJ#|Vua?VnlQY%fY;_pIcnXc9|hZ*aD7Xn)N^i)N v1H)Wy`wsvB|Npc8z`Fnd00v1!K~w_(AVESKFCxdx00000NkvXXu0mjfnnB&^ literal 0 HcmV?d00001 diff --git a/Visual_Novel_iOS/Assets.xcassets/Role/role_type_read.imageset/role_type_read@3x.png b/Visual_Novel_iOS/Assets.xcassets/Role/role_type_read.imageset/role_type_read@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..316abccf321c026e0a58961f9c1636fc1b092c00 GIT binary patch literal 1854 zcmV-E2f_G>P))E79C0ReSmz_Ph+r>pnz-qL!%*z0pSnCxDi5(NCH;T zC>TX$Q{$c(>Jo_}Bt~(?Ka3l6p;~QB(25pyY&-AyJJUXVW!{^GZr+?T_ug~PJ?HoC zJNMi-8YkZr5G?}gDu9}^fyh-FwRdPl?$xM${2z{N;P`gxuN$xv`}zqCYmiThP6jlC z)zle?EY#>-qG8>pVce*pE+m35ph_{MsUW8j>dzgp6Z=0G8wf81!V&5Wa#p0XvPNY{ zBfMBcFR`F52Gmplh2(5V?9Z~G=h4qn`dbP5&Bj57pr-`5GnZ@RuLkrCKotW}7+#b0 zC4jEe@ZFh%@H`;Gd3vWAfDT7AUq5$dE}(KTI?ZQ7EznTc52j4YC_05!@yTavsKtP; zrJX?@MM`W)bRb^MxeVkPPgCheTrg#phPoO^93+fgQ$Y>mDqzY?##H1a(n*qppr%11 z_Zk2`@_3L>C*nu`2bbmoT5?#=r|ozFX6OVFI4*U|@e@EtN;CxUSf@k+q|1+_ioT4g z5^yTDbCLt=9Ke!8=M)baH~fFP|CU=9S8sf9^;z3@ZkQqb@TN8OtJf@#ELb>alFyev z#HY+fE_$&Odtq5Gei|DafsFq>V#Rf{7cIJShVZiG*UnnAX8CzfJ$?VYPY%2ysRg^qT;!q`JFyp*_2TD+mo{DW z-u{>7F1)0%%wBUsZ&*-`a9lt(XhS29mBRhtO`Td@_~>J6&!0X$diunPfue$f{5*rr zc5WD2=jZ3;1_C98(P(YCEtg*AA{V{biA>mF6FqQbIMO66n9%cmkv zeicqFBIuZu6Q+lkEl@c*lwt?G*JY~-g-%Tq$Esv?V_8Ojh|W_zA^d^jF}Y~`B}Mtf zl8T74pP$DAd6LQy6&0s?=6lM8St|YhOg1OCTJxWWXVtJ{1_H$e_BfM%LQw(J4k#-N zX7wpMX;LsvdPwCktLR*%yO9tG_z7oai;4=zl%lO48)C`jI) zSOlaOP6Pel5Ohu#jsGCKQob)Q$5k;(!W`DU6t0Ogr%OQp%8!svFT>57pZ>b1 z=l4Io^dl+n?d|Jpx_8UxDSRFVd`AiTtKSvSN<)jBMEl}eNz9&E2x$~7DdjIM*hwT{Vk3bvK1IKT~xQX7^3A}Ik&Ve1$kLw zgg^R-5#RIdp#PmV+$CH@Hnte_bdQ=s|PIachSO zgLNFElrB=%%(qPRZ3U8Zco4|(E(6eFE2sD1ZWFO4z?7R)PO~MNVKCQQJtj=1;a}?s zmQ}0cXeRzL1Z}(O>@v~z5Cc7KLhYvXOLD631*(&X_SQiY)*B|wCkS@C^WsRdb`fL= zI^lu2C$I3(YbFY|5&T9T*sUfk=07AShx~n`Txu=LsI_OnPSHM(U|X4P?ef;>FX1=i spT7YB0RR6u<7=k?000I_L_t&o0E0U$+}Grdn*aa+07*qoM6N<$f&y})O8@`> literal 0 HcmV?d00001 diff --git a/Visual_Novel_iOS/Src/API/RoleTagApi.swift b/Visual_Novel_iOS/Src/API/RoleTagApi.swift new file mode 100644 index 0000000..1bfd365 --- /dev/null +++ b/Visual_Novel_iOS/Src/API/RoleTagApi.swift @@ -0,0 +1,67 @@ +// +// RoleTagApi.swift +// Visual_Novel_iOS +// +// Created by mh on 2025/11/7. +// + +import Moya + +let RoleTagProvider = APIConfig.useMock && UserAPI.useMock +? MoyaProvider(endpointClosure: myEndpointClosure, stubClosure: { target in + let data = target.sampleData + if(data.count > 0){ + return .delayed(seconds: 0.5) + }else{ + return .never + } +}) +: MoyaProvider(requestClosure: myRequestClosure) + +enum RoleTagApi { + static let useMock: Bool = false + + case tagList(params: [String: Any]) +} + +extension RoleTagApi: TargetType { + var baseURL: URL { + // 确保 URL 格式正确,避免强制解包导致的崩溃 + guard let url = URL(string: APIConfig.role) else { + fatalError("Invalid baseURL: \(APIConfig.role)") + } + return url + } + + var path: String { + switch self { + case .tagList: + return "/tag/list" + } + } + + var method: Moya.Method { + return .post + } + + var task: Task { + var mParams = [String: Any]() + switch self { + case .tagList(let params): + // 将传入的参数赋值给 mParams + mParams = params + } + return .requestParameters(parameters: mParams, encoding: JSONEncoding.default) + } + + var headers: [String : String]? { + return APIConfig.apiHeaders() + } + + var sampleData: Data { + switch self { + case .tagList: + return Data() + } + } +} diff --git a/Visual_Novel_iOS/Src/Modules/Chat/Setting/Model/ChatRoleTagViewModel.swift b/Visual_Novel_iOS/Src/Modules/Chat/Setting/Model/ChatRoleTagViewModel.swift new file mode 100644 index 0000000..701c5ac --- /dev/null +++ b/Visual_Novel_iOS/Src/Modules/Chat/Setting/Model/ChatRoleTagViewModel.swift @@ -0,0 +1,49 @@ +// +// ChatRoleTagViewModel.swift +// Visual_Novel_iOS +// +// Created by mh on 2025/11/7. +// + +import Foundation + +struct RoleTagRequest: Codable { + var limit = 20 + var name: String = "" +} + +struct RoleTagModel: Codable { + var total: Int = 0 + var rows: [RoleTagItem] = [] +} + +struct RoleTagItem: Codable { + var id: Int = 0 + var name: String = "" +} + +class ChatRoleTagViewModel { + + func loadRoleTags(name: String, limit: Int = 20, completion: ((_ datas: RoleTagModel?) -> Void)?) { + var req = RoleTagRequest() + req.limit = limit + req.name = name + + let params = req.toNonNilDictionary() + + RoleTagProvider.request(.tagList(params: params), modelType: RoleTagModel.self) { result in + switch result { + case .success(let model): + // 如果返回的是单个 RoleListModel,将其包装成数组 + if let model = model { + completion?(model) + } else { + completion?(nil) + } + case .failure(let failure): + dlog("⛔️ 加载角色标签失败: \(failure)") + completion?(nil) + } + } + } +} diff --git a/Visual_Novel_iOS/Src/Modules/Chat/Setting/Model/ChatRoleViewModel.swift b/Visual_Novel_iOS/Src/Modules/Chat/Setting/Model/ChatRoleViewModel.swift index 92fe652..4a3cc54 100644 --- a/Visual_Novel_iOS/Src/Modules/Chat/Setting/Model/ChatRoleViewModel.swift +++ b/Visual_Novel_iOS/Src/Modules/Chat/Setting/Model/ChatRoleViewModel.swift @@ -8,6 +8,8 @@ import Foundation import CodableWrappers +// 角色列表相关 + // request struct RoleListRequest: Codable { var index = 1 @@ -34,7 +36,7 @@ struct RoleItem: Codable { 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 = 20, name: String = "", sourceId: Int = -1, tagId: Int? = nil, completion: ((_ datas: RoleListModel?) -> Void)?) { var req = RoleListRequest() req.index = index req.limit = limit @@ -51,7 +53,7 @@ class ChatRoleViewModel { case .success(let model): // 如果返回的是单个 RoleListModel,将其包装成数组 if let model = model { - completion?([model]) + completion?(model) } else { completion?(nil) } diff --git a/Visual_Novel_iOS/Src/Modules/Home/HomePageRootController.swift b/Visual_Novel_iOS/Src/Modules/Home/HomePageRootController.swift index cf415f2..230c8f2 100644 --- a/Visual_Novel_iOS/Src/Modules/Home/HomePageRootController.swift +++ b/Visual_Novel_iOS/Src/Modules/Home/HomePageRootController.swift @@ -94,10 +94,10 @@ class HomePageRootController: CLTabRootController { } private func setupDatas() { - setupOrResetFilterModel() - - // viewModel.loadCards() - loadFirstCards() +// setupOrResetFilterModel() +// +// // viewModel.loadCards() +// loadFirstCards() } private func setupOrResetFilterModel(loadNewData: Bool = false){ diff --git a/Visual_Novel_iOS/Src/Modules/Roles/Model/CLRoleTagsModel.swift b/Visual_Novel_iOS/Src/Modules/Roles/Model/CLRoleTagsModel.swift index 44e6634..e9311a9 100644 --- a/Visual_Novel_iOS/Src/Modules/Roles/Model/CLRoleTagsModel.swift +++ b/Visual_Novel_iOS/Src/Modules/Roles/Model/CLRoleTagsModel.swift @@ -9,5 +9,14 @@ import Foundation struct CLRoleTagsModel: Codable { var name: String = "" + var id: Int = 0 var isSelected: Bool = false } + +extension CLRoleTagsModel { + init(_ item: RoleTagItem) { + self.id = item.id + self.name = item.name + self.isSelected = false + } +} diff --git a/Visual_Novel_iOS/Src/Modules/Roles/RolesRootPageController.swift b/Visual_Novel_iOS/Src/Modules/Roles/RolesRootPageController.swift index 544b194..a38a480 100644 --- a/Visual_Novel_iOS/Src/Modules/Roles/RolesRootPageController.swift +++ b/Visual_Novel_iOS/Src/Modules/Roles/RolesRootPageController.swift @@ -14,7 +14,8 @@ class RolesRootPageController: CLTabRootController { private var cancellables = Set() var page: Int = 1 var viewModel: ChatRoleViewModel = ChatRoleViewModel() - + var tagViewModel: ChatRoleTagViewModel = ChatRoleTagViewModel() + override func viewDidLoad() { super.viewDidLoad() @@ -29,11 +30,13 @@ class RolesRootPageController: CLTabRootController { setupViews() setupEvent() + + loadRoles(page: 1) + loadTags() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - loadData() } private func setupViews() { @@ -51,15 +54,15 @@ class RolesRootPageController: CLTabRootController { .store(in: &cancellables) } - func loadData() { -// if page == 1{ -//// loadedAiIds.removeAll() -// } - - viewModel.loadRoles(index: page) { datas in - print(datas) - print("11111") - + func loadRoles(page: Int) { + viewModel.loadRoles(index: page) { [weak self] datas in + self?.container.config(datas?.rows, isFirstPage: page == 1) + } + } + + func loadTags() { + tagViewModel.loadRoleTags(name: "") { datas in + self.container.configureTags(datas?.rows) } } diff --git a/Visual_Novel_iOS/Src/Modules/Roles/View/CLRoleCollectionCell.swift b/Visual_Novel_iOS/Src/Modules/Roles/View/CLRoleCollectionCell.swift index 3e09780..2d4f85c 100644 --- a/Visual_Novel_iOS/Src/Modules/Roles/View/CLRoleCollectionCell.swift +++ b/Visual_Novel_iOS/Src/Modules/Roles/View/CLRoleCollectionCell.swift @@ -6,6 +6,7 @@ // import UIKit +import SDWebImage class CLRoleCollectionCell: UICollectionViewCell { @@ -17,12 +18,38 @@ class CLRoleCollectionCell: UICollectionViewCell { return imgView }() + lazy var bookImgView: UIImageView = { + let imgView = UIImageView() + imgView.backgroundColor = .blue + imgView.cornerRadius = 7 + return imgView + }() + lazy var fromImgView: UIImageView = { let imgView = UIImageView(image: UIImage(named: "role_from")) imgView.contentMode = .scaleAspectFill return imgView }() + lazy var playImgView: UIImageView = { + let imgView = UIImageView(image: UIImage(named: "role_type_play")) + imgView.isHidden = true + return imgView + }() + + lazy var readImgView: UIImageView = { + let imgView = UIImageView(image: UIImage(named: "role_type_read")) + return imgView + }() + + lazy var typeStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [playImgView, readImgView]) + stackView.spacing = 0 + stackView.distribution = .fill + stackView.alignment = .fill + return stackView + }() + lazy var coverImgView: UIImageView = { let imgView = UIImageView() imgView.contentMode = .scaleAspectFill @@ -105,8 +132,11 @@ class CLRoleCollectionCell: UICollectionViewCell { } // MARK: data - func setupData(desc: String) { - descLab.text = desc + func setupData(item: RoleItem) { + descLab.text = item.name + nameLab.text = item.name + coverImgView.sd_setImage(with: URL(string: item.coverImage), placeholderImage: nil) +// coverImgView. } // MARK: subviews @@ -117,7 +147,9 @@ class CLRoleCollectionCell: UICollectionViewCell { contentView.addSubview(bottomShadowImgView) contentView.addSubview(bookBgImgView) - contentView.addSubview(fromImgView) + bookBgImgView.addSubview(bookImgView) +// contentView.addSubview(fromImgView) + bookImgView.addSubview(typeStackView) contentView.addSubview(starImgView) contentView.addSubview(sourceLab) @@ -148,9 +180,19 @@ class CLRoleCollectionCell: UICollectionViewCell { bookBgImgView.snp.makeConstraints { make in make.top.left.equalToSuperview() } +// +// fromImgView.snp.makeConstraints { make in +// make.top.left.equalToSuperview() +// } - fromImgView.snp.makeConstraints { make in - make.top.left.equalToSuperview() + bookImgView.snp.makeConstraints { make in + make.left.top.equalToSuperview().inset(3) + make.right.equalToSuperview().inset(4) + make.bottom.equalToSuperview().inset(10) + } + + typeStackView.snp.makeConstraints { make in + make.bottom.right.equalToSuperview().inset(0) } sourceLab.snp.makeConstraints { make in diff --git a/Visual_Novel_iOS/Src/Modules/Roles/View/CLRoleTagsView.swift b/Visual_Novel_iOS/Src/Modules/Roles/View/CLRoleTagsView.swift index 109e942..9a48b5d 100644 --- a/Visual_Novel_iOS/Src/Modules/Roles/View/CLRoleTagsView.swift +++ b/Visual_Novel_iOS/Src/Modules/Roles/View/CLRoleTagsView.swift @@ -11,16 +11,20 @@ class CLRoleTagsView: UIView { // let tags = ["#浪漫", "#温柔", "#多愁善感", "#深情", "#this is good", "#沙瓦迪", "#科技哈", "#等好a", "#a"] var tagModels: [CLRoleTagsModel] = [ - CLRoleTagsModel(name: "#浪漫浪漫浪漫浪漫浪漫浪漫浪漫浪漫浪漫漫浪漫浪漫浪漫漫浪漫浪漫浪漫漫浪漫浪漫浪漫", isSelected: false), - CLRoleTagsModel(name: "#温柔", isSelected: false), - CLRoleTagsModel(name: "#多愁善感", isSelected: false), - CLRoleTagsModel(name: "#this is good", isSelected: false), - CLRoleTagsModel(name: "#沙瓦迪", isSelected: false), - CLRoleTagsModel(name: "#科技哈", isSelected: false), - CLRoleTagsModel(name: "#等好a", isSelected: false), - CLRoleTagsModel(name: "#a", isSelected: false), - CLRoleTagsModel(name: "#浪漫", isSelected: false), - ] +// CLRoleTagsModel(name: "#浪漫浪漫浪漫浪漫浪漫浪漫浪漫浪漫浪漫漫浪漫浪漫浪漫漫浪漫浪漫浪漫漫浪漫浪漫浪漫", isSelected: false), +// CLRoleTagsModel(name: "#温柔", isSelected: false), +// CLRoleTagsModel(name: "#多愁善感", isSelected: false), +// CLRoleTagsModel(name: "#this is good", isSelected: false), +// CLRoleTagsModel(name: "#沙瓦迪", isSelected: false), +// CLRoleTagsModel(name: "#科技哈", isSelected: false), +// CLRoleTagsModel(name: "#等好a", isSelected: false), +// CLRoleTagsModel(name: "#a", isSelected: false), +// CLRoleTagsModel(name: "#浪漫", isSelected: false), + ] { + didSet { + self.collectionView.reloadData() + } + } lazy var collectionView: AutoHeightCollectionView = { let layout = TagFlowLayout() diff --git a/Visual_Novel_iOS/Src/Modules/Roles/View/RolesRootPageView.swift b/Visual_Novel_iOS/Src/Modules/Roles/View/RolesRootPageView.swift index 29a22a7..85167a1 100644 --- a/Visual_Novel_iOS/Src/Modules/Roles/View/RolesRootPageView.swift +++ b/Visual_Novel_iOS/Src/Modules/Roles/View/RolesRootPageView.swift @@ -15,24 +15,23 @@ class RolesRootPageView: CLContainer { let itemWidth: CGFloat = (UIScreen.width - 30.0) / 2.0 var jumpPublisher: AnyPublisher { topView.jumpPublisher } -// private lazy var pagingView = JXPagingListRefreshView(delegate: self) -// lazy var headerView: - - - let data: [String] = [ - "Once a prodigy, Lin Feng had his cultivation shattered and was cast out Once a prodigy, Lin Feng had his cultivation shattered and was cast", - "Once a prodigy, Lin Feng had his cultivation", - "Once a prodigy, Lin Feng had his cultivation shattered and was cast out Once a prodigy", - "Once a prodigy", - "Once a prodigy, Lin Feng had his cultivation shattered and was cast out Once a prodigy, Lin Feng had his cultivation shattered and was cast Once a prodigy, Lin Feng had his cultivation shattered and was cast out Once a prodigy, Lin Feng had his cultivation shattered and was cast", - "Once a prodigy, Lin Feng had his cultivation shattered and was cast out Once a prodigy", - "Once a prodigy, Lin Feng had his cultivation shattered and was cast out Once a prodigy", - "Once a prodigy", - "Once a prodigy, Lin Feng had his cultivation shattered and was cast out Once a prodigy, Lin Feng had his cultivation shattered and was cast", - "Once a prodigy" - ] + // private lazy var pagingView = JXPagingListRefreshView(delegate: self) + // lazy var headerView: + + + var data: [RoleItem] = [] let remind: [String] = [ + "[The Lsat Oracle of Kael]", + "[The Lsat Oracle of Kael]", + "[The Lsat Oracle of Kael]", + "[The Lsat Oracle of Kael]", + "[The Lsat Oracle of Kael]", + "[The Lsat Oracle of Kael]", + "[The Lsat Oracle of Kael]", + "[The Lsat Oracle of Kael]", + "[The Lsat Oracle of Kael]", + "[The Lsat Oracle of Kael]", "[The Lsat Oracle of Kael]", "[The Lsat Oracle of Kael]", "[The Lsat Oracle of Kael]", @@ -83,7 +82,7 @@ class RolesRootPageView: CLContainer { private func setupViews() { addSubview(self.topView) -// addSubview(tagsChooseView) + // addSubview(tagsChooseView) addSubview(tagsView) addSubview(collectionView) @@ -106,6 +105,23 @@ class RolesRootPageView: CLContainer { private func setupDatas() { } + + func config(_ data: [RoleItem]?, isFirstPage: Bool){ + if isFirstPage { + self.data = data ?? [] + } else { + self.data.append(contentsOf: data ?? []) + } + self.collectionView.reloadData() + } + + func configureTags(_ data: [RoleTagItem]?) { + guard let tags = data else { + self.tagsView.tagModels = [] + return + } + self.tagsView.tagModels = tags.map(CLRoleTagsModel.init) + } } extension RolesRootPageView: UICollectionViewDelegate, UICollectionViewDataSource, WaterfallLayoutDelegate { @@ -116,7 +132,7 @@ extension RolesRootPageView: UICollectionViewDelegate, UICollectionViewDataSourc func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell: CLRoleCollectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "CLRoleCollectionCell", for: indexPath) as! CLRoleCollectionCell - cell.setupData(desc: data[indexPath.item]) + cell.setupData(item: data[indexPath.item]) return cell } @@ -139,7 +155,7 @@ extension RolesRootPageView: UICollectionViewDelegate, UICollectionViewDataSourc let maxHeight = lineHeight * CGFloat(maxLines) // 真实文本高度(不会超过 maxHeight) - let textSize = model.boundingRect( + let textSize = model.name.boundingRect( with: CGSize(width: itemWidth - 20, height: maxHeight), // 高度封顶 options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: [.font: font],