Commit 57fa5f79 ilCode

大数据研究列表页

1 个父辈 b4ff7130
正在显示 51 个修改的文件 包含 1429 行增加10 行删除
{
"images" : [
{
"filename" : "btn_back_black.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "btn_back_black@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "btn_back_black@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "btn_back_white.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "btn_back_white@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "btn_back_white@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "dsj.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "hadoop_match_filter.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "hadoop_match_filter@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "hadoop_match_filter@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "reasearch_icon.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "reasearch_icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "reasearch_icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "discover.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "discover@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "discover@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"filename" : "discover_selected.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "discover_selected@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "discover_selected@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
//
// DiscoverController.swift
// AoleiSports
//
// Created by ilCode on 2024/6/24.
//
import UIKit
class DiscoverController: BaseController {
private lazy var dataReasearchBtn: UIButton = {
let btn = UIButton(frame: CGRect(x: 30, y: kNavBarH + 20, width: 100, height: 60))
btn.setTitle("数据研究", for: .normal)
btn.setTitleColor(kMainTitleColor, for: .normal)
btn.titleLabel?.font = kFontSize(16)
btn.setImage(R.image.reasearch_icon()?.resize(to: CGSize(width: 40, height: 40)), for: .normal)
btn.adjustImage(position: .top, spacing: 5)
btn.rx.tap.subscribe(onNext: {
let hadoopVC = HadoopController()
self.navigationController?.pushViewController(hadoopVC, animated: true)
}).disposed(by: disposeBag)
return btn
}()
override func viewDidLoad() {
super.viewDidLoad()
gk_navTitle = "发现"
view.addSubview(dataReasearchBtn)
}
}
//
// HadoopController.swift
// AoleiSports
//
// Created by ilCode on 2024/6/24.
//
import UIKit
/// 大数据研究页面
class HadoopController: BaseController {
var provider: HadoopProvider<HadoopTarget>?
var matchCount = 0
private lazy var leftBtn: UIButton = {
let btn = UIButton()
btn.setTitle("大数据预测", for: .normal)
btn.setTitle("大数据预测", for: .selected)
btn.setTitleColor(.clear, for: .normal)
btn.setTitleColor(kMainTitleColor, for: .selected)
btn.titleLabel?.font = kBoldFontSize(16)
btn.setImage(R.image.btn_back_white(), for: .normal)
btn.setImage(R.image.btn_back_black(), for: .selected)
btn.rx.tap.subscribe(onNext: {
self.navigationController?.popViewController(animated: true)
}).disposed(by: disposeBag)
return btn
}()
private lazy var rightLab: UILabel = {
let lab = UILabel()
lab.text = "53.24万人使用"
lab.textColor = kSubTitleColor
lab.font = kFontSize(12)
lab.textAlignment = .center
lab.sizeToFit()
lab.size = CGSize(width: lab.width + 8, height: lab.height + 8)
lab.corners(radius: lab.height/2.0)
lab.border(borderColor: kSubTitleColor)
return lab
}()
private lazy var header: HadoopHeaderView = {
let view = HadoopHeaderView()
return view
}()
private lazy var matchListView: UITableView = {
let tv = UITableView(frame: CGRect(x: 0, y: 0, width: kScreenW, height: kScreenH), style: .plain)
tv.dataSource = self
tv.delegate = self
tv.tableHeaderView = header
tv.backgroundColor = kMainBgColor
tv.showsVerticalScrollIndicator = false
tv.contentInsetAdjustmentBehavior = .never
if #available(iOS 15.0, *) {
tv.sectionHeaderTopPadding = CGFloat.leastNormalMagnitude
}
tv.contentInset = UIEdgeInsets(top: kNavBarH, left: 0, bottom: kBottomSafeH, right: 0)
tv.register(HustleScoreCell.self, forCellReuseIdentifier: HustleScoreCell.reuseIdentifier)
tv.register(MatchFilterHeaderView.self, forHeaderFooterViewReuseIdentifier: MatchFilterHeaderView.reuseIdentifier)
return tv
}()
private lazy var filterView: HadoopMatchFilterView = {
let view = HadoopMatchFilterView()
view.dataSource = [
["赛事类型选择:": ["全部", "竞足", "北单", "欧洲杯"]],
["联赛选择:": ["全部", "欧洲杯", "日佳"]]
]
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
gk_navLeftBarButtonItem = UIBarButtonItem(customView: leftBtn)
gk_navRightBarButtonItem = UIBarButtonItem(customView: rightLab)
view.addSubview(matchListView)
initProvider()
handleRefresh()
}
private func initProvider() {
provider = HadoopProvider(vc: self, showErr: false)
provider?.bigDataList
.asObservable()
.subscribe(onNext: { tmpModels in
self.matchListView.reloadData()
if tmpModels.isEmpty {
self.matchListView.isHidden = true
self.showEmpty(type: .noData)
} else {
self.dismissEmpty()
self.matchListView.isHidden = false
}
self.matchListView.contentOffset.y = 0
})
.disposed(by: disposeBag)
provider?.predictData
.asObservable()
.subscribe(onNext: { tmpPredictData in
self.header.update(predictData: tmpPredictData)
})
.disposed(by: disposeBag)
provider?.matchTotalCount
.asObservable()
.subscribe(onNext: { tmpCount in
self.matchCount = tmpCount
// 确保tableView已经被添加到视图层次结构中并且可见
if self.matchListView.window != nil {
self.matchListView.reloadSections(IndexSet(integer: 0), with: .none)
} else {
DispatchQueue.main.async {
self.matchListView.reloadSections(IndexSet(integer: 0), with: .none)
}
}
})
.disposed(by: disposeBag)
provider?.comList
.asObservable()
.subscribe(onNext: { tmpComList in
self.filterView.update(comList: tmpComList)
})
.disposed(by: disposeBag)
}
override func handleRefresh() {
super.handleRefresh()
provider?.bigDataListRequest(completion: { logicResult in
if case .failure(let err) = logicResult {
if case AsError.netErr(let message) = err {
self.showEmpty(type: .netErr, message: message)
} else {
self.showEmpty(type: .other, message: err.localizedDescription)
}
self.emptyStateDeal()
}
})
}
private func emptyStateDeal(isShow: Bool = true) {
leftBtn.isSelected = isShow
rightLab.isHidden = (provider?.bigDataList.value.isEmpty ?? true)
gk_statusBarStyle = leftBtn.isSelected ? .darkContent : .lightContent
gk_navBarAlpha = leftBtn.isSelected ? 1 : 0
}
}
//MARK: - UITableViewDataSource && UITableViewDelegate
extension HadoopController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return provider?.bigDataList.value.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = provider?.bigDataList.value[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: HustleScoreCell.reuseIdentifier, for: indexPath) as! HustleScoreCell
cell.model = model
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: MatchFilterHeaderView.reuseIdentifier) as? MatchFilterHeaderView
header?.rightBtn.rx.tap.subscribe(onNext: {
self.filterView.showInView(self.view)
}).disposed(by: disposeBag)
header?.update(matchCount: matchCount)
return header
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
return UIView(frame: CGRect(x: 0, y: 0, width: 10, height: CGFloat.leastNormalMagnitude))
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
navigationController?.pushViewController(HadoopDetailController(), animated: true)
}
}
extension HadoopController: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if provider?.bigDataList.value.isEmpty ?? true {
emptyStateDeal()
} else {
var isShow = true
if scrollView.contentOffset.y > 0 {
isShow = true
} else if scrollView.contentOffset.y <= 0 {
scrollView.contentOffset.y = 0
isShow = false
}
emptyStateDeal(isShow: isShow)
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return gk_statusBarStyle
}
}
//
// HadoopDetailController.swift
// AoleiSports
//
// Created by ilCode on 2024/6/25.
//
import UIKit
class HadoopDetailController: BaseController {
private lazy var header: UIView = {
let view = UIView(frame: CGRect(x: 0, y: -30, width: kScreenW, height: kNavBarH + 90))
view.backgroundColor = UIColor.colorWith(hexString: "122063")
view.corners(radius: 30)
return view
}()
private lazy var teamView: UIView = {
let view = UIView(frame: CGRect(x: 10, y: kNavBarH, width: kScreenW - 20, height: 100))
view.backgroundColor = UIColor.colorWith(hexString: "ECECED")
view.corners(radius: 20)
let gradientLayer = CAGradientLayer()
gradientLayer.frame = view.bounds
gradientLayer.colors = [UIColor.colorWith(hexString: "DADADA").cgColor, UIColor.colorWith(hexString: "F4F4F4").cgColor, UIColor.colorWith(hexString: "DADADA").cgColor]
gradientLayer.locations = [0.0, 0.5, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
view.layer.insertSublayer(gradientLayer, at: 0)
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
gk_navTitle = "大数据研究"
gk_navBackgroundColor = .clear
gk_navTitleColor = kWhite
gk_backImage = R.image.btn_back_white()
view.addSubview(header)
view.addSubview(teamView)
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
class RadialGradientLayer: CALayer {
var colors: [CGColor]?
var locations: [CGFloat]?
override func draw(in ctx: CGContext) {
guard let colors = colors, let locations = locations else { return }
let colorSpace = CGColorSpaceCreateDeviceRGB()
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: locations)!
let center = CGPoint(x: bounds.size.width / 2, y: bounds.size.height / 2)
let radius = min(bounds.size.width, bounds.size.height) / 2
ctx.drawRadialGradient(
gradient,
startCenter: center, startRadius: 0,
endCenter: center, endRadius: radius,
options: .drawsAfterEndLocation
)
}
}
//
// HadoopHeaderView.swift
// AoleiSports
//
// Created by ilCode on 2024/6/25.
//
import UIKit
class HadoopHeaderView: UIView {
let disposeBag = DisposeBag()
private lazy var bigIcon: UIImageView = {
let icon = UIImageView.init(image: R.image.dsj())
return icon
}()
private lazy var titleLab: UILabel = {
let lab = UILabel()
lab.textColor = UIColor.colorWith(hexString: "8993cd")
lab.text = "大数据研究"
lab.sizeToFit()
lab.textAlignment = .center
lab.font = kBoldFontSize(16)
return lab
}()
private lazy var detailLab: UILabel = {
let lab = UILabel()
lab.textColor = UIColor.colorWith(hexString: "dddfff")
lab.text = "通过大数据生产,智能化分解对战的状态、战意、实力、赛事等,根据研究赛事的专业流程习惯,透视各项数据信息,花最短的时间让你知根知底,看透比赛。"
lab.numberOfLines = 0
lab.sizeToFit()
lab.font = kFontSize(14)
return lab
}()
private lazy var yesPreBtn: UIButton = {
let btn = UIButton()
btn.isEnabled = false
let color = UIColor.colorWith(hexString: "F7D54D")
btn.setTitleColor(color, for: .normal)
btn.titleLabel?.font = kFontSize(14)
btn.rx.tap.subscribe(onNext: {
print("马斯克算法...")
}).disposed(by: disposeBag)
btn.corners(radius: 13)
btn.border(borderColor: color)
return btn
}()
override init(frame: CGRect) {
super.init(frame: CGRect(x: 0, y: 0, width: kScreenW, height: 0))
backgroundColor = UIColor.colorWith(hexString: "122063")
addSubview(bigIcon)
addSubview(titleLab)
addSubview(detailLab)
addSubview(yesPreBtn)
bigIcon.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(kStatusBarH + 20)
make.size.equalTo(CGSize(width: 46, height: 46))
}
titleLab.snp.makeConstraints { make in
make.centerX.equalTo(bigIcon)
make.top.equalTo(bigIcon.snp.bottom).offset(15)
}
detailLab.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.right.equalToSuperview().offset(-20)
make.top.equalTo(titleLab.snp.bottom).offset(15)
}
yesPreBtn.snp.makeConstraints { make in
make.left.right.equalTo(detailLab)
make.top.equalTo(detailLab.snp.bottom).offset(15)
make.height.equalTo(26)
make.bottom.equalToSuperview().offset(-15).priority(.high)
}
// 获取动态高度
setNeedsLayout()
layoutIfNeeded()
self.height = systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension HadoopHeaderView {
func update(predictData: (Int, String) = (0, "")) {
let totalCount = predictData.0
let rate = predictData.1
yesPreBtn.setTitle(totalCount == 0 ? "暂无预测数据" : "马斯克算法预测昨日\(totalCount)场, 正确率达\(rate)", for: .normal)
yesPreBtn.isEnabled = totalCount > 0
}
}
//
// HadoopMatchFilterView.swift
// AoleiSports
//
// Created by ilCode on 2024/6/25.
//
import UIKit
// 大数据赛事筛选view
class HadoopMatchFilterView: UIView {
private var overlayView: UIView!
private var contentView: UIView!
private var titleLabel: UILabel!
private var lineView: UIView!
private var collectionView: UICollectionView!
private var confirmButton: UIButton!
var dataSource: [[String: [String]]] = []
var selectedItems: [IndexPath: String] = [:]
override init(frame: CGRect) {
super.init(frame: CGRect(x: 0, y: 0, width: kScreenW, height: kScreenH))
setupOverlayView()
setupContentView()
setupTitleLabel()
setupCollectionView()
setupConfirmButton()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupOverlayView() {
overlayView = UIView(frame: self.bounds)
overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.3)
overlayView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(dismiss)))
addSubview(overlayView)
}
private func setupContentView() {
contentView = UIView()
contentView.backgroundColor = kWhite
contentView.corners(radius: 8)
addSubview(contentView)
contentView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.right.equalToSuperview().offset(-20)
make.centerY.equalToSuperview()
make.height.equalTo(400)
}
}
private func setupTitleLabel() {
titleLabel = UILabel()
titleLabel.text = "赛事筛选"
titleLabel.textAlignment = .center
titleLabel.textColor = kMainTitleColor
titleLabel.font = kBoldFontSize(18)
contentView.addSubview(titleLabel)
lineView = UIView()
lineView.backgroundColor = kDividerColor
contentView.addSubview(lineView)
titleLabel.snp.makeConstraints { make in
make.top.equalToSuperview()
make.left.equalToSuperview().offset(10)
make.right.equalToSuperview().offset(-10)
make.height.equalTo(40)
}
lineView.snp.makeConstraints { make in
make.top.equalTo(titleLabel.snp.bottom)
make.left.right.equalToSuperview()
make.height.equalTo(1)
}
}
private func setupCollectionView() {
let layout = UICollectionViewFlowLayout()
layout.headerReferenceSize = CGSize(width: 100, height: 40)
layout.itemSize = CGSize(width: (kScreenW - 60 - 30)/4.0, height: 30)
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
layout.minimumLineSpacing = 5
layout.minimumInteritemSpacing = 5
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.backgroundColor = .white
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(HadoopFilterCell.self, forCellWithReuseIdentifier: HadoopFilterCell.reuseIdentifier)
collectionView.register(HadoopFilterHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: HadoopFilterHeaderView.reuseIdentifier)
contentView.addSubview(collectionView)
collectionView.border()
collectionView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(10)
make.right.equalToSuperview().offset(-10)
make.top.equalTo(titleLabel.snp.bottom)
}
}
private func setupConfirmButton() {
confirmButton = UIButton(type: .system)
confirmButton.setTitle("确定", for: .normal)
confirmButton.setTitleColor(kWhite, for: .normal)
confirmButton.titleLabel?.font = kBoldFontSize(16)
confirmButton.backgroundColor = UIColor.colorWith(hexString: "C49225")
confirmButton.corners(radius: 5)
confirmButton.addTarget(self, action: #selector(confirmButtonTapped), for: .touchUpInside)
contentView.addSubview(confirmButton)
confirmButton.snp.makeConstraints { make in
make.top.equalTo(collectionView.snp.bottom).offset(10)
make.left.equalToSuperview().offset(10)
make.right.equalToSuperview().offset(-10)
make.height.equalTo(32)
make.bottom.equalToSuperview().offset(-10)
}
}
func update(comList: [HadoopComModel]) {
}
// MARK: - Actions
@objc private func dismiss() {
UIView.animate(withDuration: 0.3, animations: {
self.alpha = 0
}) { _ in
self.removeFromSuperview()
}
}
@objc private func confirmButtonTapped() {
dismiss()
// 刷新选中的数据
// 可以在此处添加回调或通知外部调用者刷新数据
}
// MARK: - 显示弹框
func showInView(_ view: UIView) {
self.frame = view.bounds
view.addSubview(self)
self.alpha = 0
UIView.animate(withDuration: 0.3) {
self.alpha = 1
}
}
}
//MARK: - UICollectionViewDataSource && UICollectionViewDelegate
extension HadoopMatchFilterView: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return dataSource.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let sectionData = dataSource[section]
let values = sectionData.values.first
return values?.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: HadoopFilterCell.reuseIdentifier, for: indexPath) as? HadoopFilterCell else {
return UICollectionViewCell()
}
let sectionData = dataSource[indexPath.section]
let values = sectionData.values.first
let title = values?[indexPath.item] ?? ""
cell.configure(with: title, isSelected: selectedItems[indexPath] == title)
return cell
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: HadoopFilterHeaderView.reuseIdentifier, for: indexPath) as? HadoopFilterHeaderView else {
return UICollectionReusableView()
}
let sectionData = dataSource[indexPath.section]
let title = sectionData.keys.first ?? ""
header.configure(with: title)
return header
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let sectionData = dataSource[indexPath.section]
let values = sectionData.values.first
let selectedValue = values?[indexPath.item]
selectedItems[indexPath] = selectedValue
collectionView.reloadSections(IndexSet(integer: indexPath.section))
}
}
//MARK: - HadoopFilterHeaderView
class HadoopFilterHeaderView: UICollectionReusableView {
static let reuseIdentifier = "HadoopFilterHeaderView"
private let titleLabel: UILabel = {
let label = UILabel()
label.font = kFontSize(15)
label.textColor = kMidTitleColor
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}
private func setupView() {
addSubview(titleLabel)
titleLabel.snp.makeConstraints { make in
make.left.top.bottom.equalToSuperview()
make.right.equalToSuperview().offset(-10)
}
}
func configure(with title: String) {
titleLabel.text = title
}
}
//MARK: - HadoopFilterCell
class HadoopFilterCell: UICollectionViewCell {
static let reuseIdentifier = "HadoopFilterCell"
private let itemBtn: UIButton = {
let btn = UIButton()
btn.setTitleColor(kMidTitleColor, for: .normal)
btn.setTitleColor(kWhite, for: .selected)
btn.titleLabel?.font = kBoldFontSize(14)
btn.isUserInteractionEnabled = false
btn.corners(radius: 5)
return btn
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setupView()
}
private func setupView() {
contentView.addSubview(itemBtn)
itemBtn.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
func configure(with title: String, isSelected: Bool) {
itemBtn.setTitle(title, for: .normal)
itemBtn.backgroundColor = UIColor.colorWith(hexString: isSelected ? "C49225" : "F0F0F0")
itemBtn.isSelected = isSelected
}
}
//
// HadoopProvider.swift
// AoleiSports
//
// Created by ilCode on 2024/6/26.
//
import UIKit
enum HadoopTarget: TargetType {
case bigDataList
var task: Moya.Task {
let parameters = ["query": """
query{
\(APIs.kBigDataList)
}
"""]
return .requestParameters(parameters: parameters, encoding: JSONEncoding.default)
}
}
class HadoopProvider<Target: TargetType>: BaseMoyaProvider<Target> {
var bigDataList = BehaviorRelay<[HadoopMatchModel]>(value: [])
var predictData = BehaviorRelay<(Int, String)>(value: (0, "0"))
var matchTotalCount = BehaviorRelay<Int>(value: 0)
var comList = BehaviorRelay<[HadoopComModel]>(value: [])
func bigDataListRequest(completion: @escaping (Result<Bool, AsError>) -> Void) {
moyaPost(api: APIs.kBigDataList, target: HadoopTarget.bigDataList) { midResult in
// DDLogInfo("大数据研究列表接口数据:\(midResult)")
switch midResult {
case let .success(midSuccessResult):
let requestModel = HadoopRequestModel(JSON: midSuccessResult)
if let tmpReult = requestModel?.result, !tmpReult.isEmpty {
self.bigDataList.accept(tmpReult)
}
if let predictData = requestModel?.predictData,
let predictResult = predictData.predictResult,
let totalCount = predictResult["total_count"] as? Int,
let predict = predictResult["predict"] as? [String : Any],
let rate = predict["rate"] as? String {
self.predictData.accept((totalCount, rate))
}
if let total = requestModel?.total {
self.matchTotalCount.accept(total)
}
if let tmpComList = requestModel?.competitionList, !tmpComList.isEmpty {
self.comList.accept(tmpComList)
}
completion(.success(true))
case .failure(let err):
completion(.failure(err))
}
}
}
}
//
// HadoopRequestModel.swift
// AoleiSports
//
// Created by ilCode on 2024/6/26.
//
import Foundation
struct HadoopRequestModel: Mappable {
var predictData: PredictDataModel?
var total: Int?
var competitionList: [HadoopComModel]?
var result: [HadoopMatchModel]?
init?(map: ObjectMapper.Map) { }
mutating func mapping(map: ObjectMapper.Map) {
predictData <- map["predict_data"]
total <- map["total"]
competitionList <- map["competition_list"]
result <- map["result"]
}
}
struct PredictDataModel: Mappable {
var calculateDate: String?
var predictResult: [String : Any]?
var predictTopList: [PredictTopModel]?
var recentCount: Int?
init?(map: ObjectMapper.Map) { }
mutating func mapping(map: ObjectMapper.Map) {
calculateDate <- map["calculate_date"]
predictResult <- map["predict_result"]
predictTopList <- map["predict_top_rate"]
recentCount <- map["recent_count"]
}
}
struct PredictTopModel: Mappable {
var count: Int?
var title: String?
var comId: Int?
var comName: String?
init?(map: ObjectMapper.Map) { }
mutating func mapping(map: ObjectMapper.Map) {
count <- map["count"]
title <- map["title"]
comId <- map["competition_id"]
comName <- map["competition_name"]
}
}
struct HadoopComModel: Mappable {
var comId: Int?
var comName: String?
init?(map: ObjectMapper.Map) { }
mutating func mapping(map: ObjectMapper.Map) {
comId <- map["competition_id"]
comName <- map["competition_name"]
}
}
struct HadoopMatchModel: Mappable {
var matchTime: String?
var comId: Int?
var comName: String?
var hostName: String?
var awayName: String?
var issueNameJc: String?
var issueNameBd: String?
var homeData: SkillModel?
var awayData: SkillModel?
init?(map: ObjectMapper.Map) { }
mutating func mapping(map: ObjectMapper.Map) {
matchTime <- map["match_time"]
comId <- map["competition_id"]
comName <- map["competition_name"]
hostName <- map["home_name"]
awayName <- map["away_name"]
issueNameJc <- map["issue_name_jc"]
issueNameBd <- map["issue_name_bd"]
homeData <- map["home_data"]
awayData <- map["away_data"]
}
}
struct SkillModel: Mappable {
var attackTotal: Int?
var techScore: Int?
var statusScore: Int?
var defendTotal: Int?
init?(map: ObjectMapper.Map) { }
mutating func mapping(map: ObjectMapper.Map) {
attackTotal <- map["attack_total"]
techScore <- map["tech_score"]
statusScore <- map["status_score"]
defendTotal <- map["defend_total"]
}
}
//
// HustleScoreCell.swift
// AoleiSports
//
// Created by ilCode on 2024/6/24.
//
import UIKit
/// 球队技术统计cell
class HustleScoreCell: BaseTableViewCell {
static let reuseIdentifier = "HustleScoreCell"
private lazy var bgView: UIView = {
let view = UIView()
view.backgroundColor = kWhite
view.corners(radius: 8)
view.border(borderColor: UIColor.colorWith(hexString: "E9EAEF"), borderWidth: 1)
view.layer.shadowColor = UIColor.colorWith(hexString: "E9EAEF").cgColor
view.layer.shadowOffset = CGSize(width: 0, height: 0.5)
view.layer.shadowOpacity = 0.3
view.layer.shadowRadius = 8
view.layer.masksToBounds = false
return view
}()
private lazy var hostNameLab: UILabel = {
let lab = UILabel()
lab.textAlignment = .center
lab.font = kBoldFontSize(16)
lab.textColor = kMainTitleColor
lab.numberOfLines = 2
return lab
}()
private lazy var gameLab: UILabel = {
let lab = UILabel()
lab.textAlignment = .center
lab.font = kBoldFontSize(14)
lab.textColor = kMainTitleColor
return lab
}()
private lazy var guestNameLab: UILabel = {
let lab = UILabel()
lab.textAlignment = .center
lab.font = kBoldFontSize(16)
lab.textColor = kMainTitleColor
lab.numberOfLines = 2
return lab
}()
private lazy var teamGameStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [hostNameLab, gameLab, guestNameLab])
stackView.axis = .horizontal
stackView.alignment = .center
stackView.distribution = .fillEqually
stackView.spacing = 2
return stackView
}()
private lazy var matchTimeLab: UILabel = {
let lab = UILabel()
lab.textAlignment = .center
lab.font = kFontSize(14)
lab.textColor = kMidTitleColor
return lab
}()
private lazy var atackView: HostGuestSkillView = {
let aView = HostGuestSkillView(skillType: .attack)
return aView
}()
private lazy var statusView: HostGuestSkillView = {
let aView = HostGuestSkillView(skillType: .status)
return aView
}()
private lazy var techView: HostGuestSkillView = {
let aView = HostGuestSkillView(skillType: .tech)
return aView
}()
private lazy var freeLab: UILabel = {
let lab = UILabel()
lab.text = "免费查看"
lab.textAlignment = .center
lab.font = kFontSize(14)
lab.textColor = UIColor.colorWith(hexString: "D8B47A")
return lab
}()
var model: HadoopMatchModel? {
didSet {
hostNameLab.text = model?.hostName
gameLab.text = model?.comName
guestNameLab.text = model?.awayName
matchTimeLab.text = ScoreTools.getFormatMatchTime(time: model?.matchTime, format: "MM-dd HH:mm")
if let hostModel = model?.homeData, let guestModel = model?.awayData {
atackView.update(hostValue: hostModel.attackTotal, guestValue: guestModel.attackTotal)
statusView.update(hostValue: hostModel.statusScore, guestValue: guestModel.statusScore)
techView.update(hostValue: hostModel.techScore, guestValue: guestModel.techScore)
}
}
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
backgroundColor = kMainBgColor
contentView.addSubview(bgView)
bgView.addSubview(teamGameStackView)
bgView.addSubview(matchTimeLab)
bgView.addSubview(atackView)
bgView.addSubview(statusView)
bgView.addSubview(techView)
bgView.addSubview(freeLab)
bgView.snp.makeConstraints { make in
make.top.equalToSuperview()
make.left.equalToSuperview().offset(5)
make.right.equalToSuperview().offset(-5)
make.bottom.equalToSuperview().offset(-5)
}
teamGameStackView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(10)
make.left.right.equalToSuperview()
}
matchTimeLab.snp.makeConstraints { make in
make.top.equalTo(teamGameStackView.snp.bottom).offset(5)
make.left.equalToSuperview().offset(5)
make.right.equalToSuperview().offset(-5)
}
atackView.snp.makeConstraints { make in
make.top.equalTo(matchTimeLab.snp.bottom).offset(5)
make.left.equalToSuperview().offset(20)
make.right.equalToSuperview().offset(-20)
make.height.equalTo(20)
}
statusView.snp.makeConstraints { make in
make.top.equalTo(atackView.snp.bottom).offset(5)
make.left.right.height.equalTo(atackView)
}
techView.snp.makeConstraints { make in
make.top.equalTo(statusView.snp.bottom).offset(5)
make.left.right.height.equalTo(atackView)
}
freeLab.snp.makeConstraints { make in
make.top.equalTo(techView.snp.bottom).offset(5)
make.left.equalToSuperview().offset(5)
make.right.equalToSuperview().offset(-5)
make.bottom.equalToSuperview().offset(-10)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class HostGuestSkillView: UIStackView {
enum SkillType {
case attack
case status
case tech
}
private lazy var hostAttackLab: UILabel = {
let lab = UILabel()
lab.font = kFontSize(14)
lab.textColor = kMidTitleColor
return lab
}()
private lazy var hostProgressView: UIProgressView = {
let proView = UIProgressView()
proView.trackTintColor = .clear
proView.corners(radius: 2)
proView.transform = CGAffineTransform(rotationAngle: .pi)
return proView
}()
private lazy var hostStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [hostAttackLab, hostProgressView])
stackView.axis = .horizontal
stackView.alignment = .center
stackView.distribution = .fill
stackView.spacing = 10
return stackView
}()
private lazy var skillStatusLab: UILabel = {
let lab = UILabel()
lab.textAlignment = .center
lab.font = kFontSize(14)
lab.textColor = kMidTitleColor
return lab
}()
private lazy var guestProgressView: UIProgressView = {
let proView = UIProgressView()
proView.trackTintColor = .clear
proView.corners(radius: 2)
return proView
}()
private lazy var guestAttackLab: UILabel = {
let lab = UILabel()
lab.textAlignment = .right
lab.font = kFontSize(14)
lab.textColor = kMidTitleColor
return lab
}()
private lazy var guestStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [guestProgressView, guestAttackLab])
stackView.axis = .horizontal
stackView.alignment = .center
stackView.distribution = .fill
stackView.spacing = 10
return stackView
}()
private lazy var skillStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [hostStackView, skillStatusLab, guestStackView])
stackView.axis = .horizontal
stackView.alignment = .center
stackView.distribution = .fill
stackView.spacing = 20
return stackView
}()
init(skillType: SkillType) {
super.init(frame: .zero)
addSubview(skillStackView)
skillStackView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
skillStatusLab.snp.makeConstraints { make in
make.centerX.equalToSuperview()
}
hostProgressView.snp.makeConstraints { make in
make.height.equalTo(6)
}
guestProgressView.snp.makeConstraints { make in
make.height.equalTo(6)
}
var progressTintColor = UIColor.colorWith(hexString: "2FA3ED")
var skillStatus = "进攻"
if skillType == .status {
progressTintColor = UIColor.colorWith(hexString: "8BC8F5")
skillStatus = "状态"
} else if skillType == .tech {
progressTintColor = UIColor.colorWith(hexString: "C5E3F9")
skillStatus = "技术"
}
hostProgressView.progressTintColor = progressTintColor
guestProgressView.progressTintColor = progressTintColor
skillStatusLab.text = skillStatus
}
required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func update(hostValue: Int?, guestValue: Int?) {
hostAttackLab.text = "\(hostValue ?? 0)"
guestAttackLab.text = "\(guestValue ?? 0)"
hostProgressView.progress = Float(hostValue ?? 0) / Float(100)
guestProgressView.progress = Float(guestValue ?? 0) / Float(100)
}
}
//
// MatchFilterHeaderView.swift
// AoleiSports
//
// Created by ilCode on 2024/6/24.
//
import UIKit
class MatchFilterHeaderView: UITableViewHeaderFooterView {
static let reuseIdentifier = "MatchFilterHeaderView"
let disposeBag = DisposeBag()
private lazy var leftLabel: UILabel = {
let label = UILabel()
label.textColor = kMainTitleColor
label.font = kFontSize(14)
return label
}()
lazy var rightBtn: UIButton = {
let btn = UIButton()
btn.setTitle("筛选比赛", for: .normal)
btn.setTitleColor(kMainTitleColor, for: .normal)
btn.titleLabel?.font = kFontSize(14)
btn.setImage(R.image.hadoop_match_filter(), for: .normal)
btn.adjustImage(position: .left, spacing: 5)
btn.contentHorizontalAlignment = .right
return btn
}()
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
let bgView = UIView()
bgView.backgroundColor = kMainBgColor
backgroundView = bgView
contentView.addSubview(leftLabel)
contentView.addSubview(rightBtn)
leftLabel.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.left.equalToSuperview().offset(10)
}
rightBtn.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.right.equalToSuperview().offset(-10)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func update(matchCount: Int) {
leftLabel.text = "共\(matchCount)场比赛"
}
}
......@@ -73,7 +73,7 @@ class InfoDetailController: BaseController {
}
}
//MARK: - UITableViewDataSource
//MARK: - UITableViewDataSource && UITableViewDelegate
extension InfoDetailController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return groupDatas.count
......
......@@ -14,7 +14,6 @@ class JcInfoDetailHeaderView: UITableViewHeaderFooterView {
let label = UILabel()
label.textColor = kMainTitleColor
label.font = kBoldFontSize(18)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
......@@ -25,6 +24,10 @@ class JcInfoDetailHeaderView: UITableViewHeaderFooterView {
contentView.addSubview(titleLabel)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
......@@ -34,9 +37,5 @@ class JcInfoDetailHeaderView: UITableViewHeaderFooterView {
make.top.bottom.equalToSuperview()
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
......@@ -27,8 +27,9 @@ class RootController: UITabBarController {
// 自定义分割线
tabBar.addSubview(UIView.divider(frame: CGRect(x: 0, y: 0, width: kScreenW, height: 1)))
addController(rootVC: HomeController(), title: "赛事比分", image: R.image.home(), selectedImage: R.image.home_selected())
// addController(rootVC: HomeController(), title: "赛事比分", image: R.image.home(), selectedImage: R.image.home_selected())
addController(rootVC: InfoController(), title: "赛事情报", image: R.image.ssqb(), selectedImage: R.image.ssqb_selected())
addController(rootVC: DiscoverController(), title: "发现", image: R.image.discover(), selectedImage: R.image.discover_selected())
addController(rootVC: ProfileController(), title: "我的", image: R.image.profile(), selectedImage: R.image.profile_selected())
}
......
......@@ -11,7 +11,7 @@ class HomeController: BaseController {
let isHiddenRelay = BehaviorRelay<Bool>(value: false)
var provider: ScoreProvider<MatchListTarget>?
lazy var filterBtn: UIButton = {
private lazy var filterBtn: UIButton = {
let btn = UIButton()
btn.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
btn.rx.tap.subscribe(onNext: {
......@@ -30,7 +30,7 @@ class HomeController: BaseController {
return btn
}()
lazy var setItem: UIBarButtonItem = {
private lazy var setItem: UIBarButtonItem = {
let btn = UIButton()
btn.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
btn.setImage(R.image.match_setting(), for: .normal)
......
//
// ScoreTools.swift
// AoleiSports
//
// Created by ilCode on 2024/6/26.
//
import Foundation
struct ScoreTools {
static func getFormatMatchTime(time: String?, format: String = "HH:mm") -> String {
guard let oriTime = time else {
return ""
}
// 创建日期格式化器来解析输入日期字符串
let inputDateFormatter = DateFormatter()
inputDateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
guard let date = inputDateFormatter.date(from: oriTime) else {
return ""
}
// 创建日期格式化器来格式化日期为目标格式
let targetDateFormatter = DateFormatter()
targetDateFormatter.dateFormat = format
// 返回格式化后的日期字符串
return targetDateFormatter.string(from: date)
}
}
......@@ -21,6 +21,8 @@ let kWhite = UIColor.white
let kMasterColor = kHexColor("DA2323")
/// 主title颜色
let kMainTitleColor = kHexColor("333333")
/// 中tittle颜色
let kMidTitleColor = kHexColor("666666")
/// 子title颜色
let kSubTitleColor = kHexColor("AAAAAA")
/// 主背景色
......
......@@ -41,6 +41,9 @@ enum AsError: Swift.Error {
}
}
typealias NetworkRequestResult = Result<Data, Error>
typealias NetworkRequestCompletion = (NetworkRequestResult) -> Void
//MARK: - Response解析方式
enum ParseMethod {
case none // 系统默认
......
......@@ -27,5 +27,8 @@ struct APIs {
// 赛事情报列表
static let kLiveScore = "liveScore"
// 大数据列表
static let kBigDataList = "get_big_data_list"
}

1.5 KB | 宽: | 高:

1.1 KB | 宽: | 高:

AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black.png
  • 两方对比
  • 交换覆盖
  • 透明覆盖

2.4 KB | 宽: | 高:

1.5 KB | 宽: | 高:

AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black@2x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black@2x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black@2x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black@2x.png
  • 两方对比
  • 交换覆盖
  • 透明覆盖

897 字节 | 宽: | 高:

762 字节 | 宽: | 高:

AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black@3x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black@3x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black@3x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_black@3x.png
  • 两方对比
  • 交换覆盖
  • 透明覆盖

1.2 KB | 宽: | 高:

1.6 KB | 宽: | 高:

AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_white@2x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_white@2x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_white@2x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_white@2x.png
  • 两方对比
  • 交换覆盖
  • 透明覆盖

1.4 KB | 宽: | 高:

793 字节 | 宽: | 高:

AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_white@3x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_white@3x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_white@3x.png
AoleiSports/Src/Vendors/GKNavigationBarSwift/GKNavigationBarSwift.bundle/btn_back_white@3x.png
  • 两方对比
  • 交换覆盖
  • 透明覆盖
......@@ -103,19 +103,37 @@ struct _R {
var accentColor: RswiftResources.ColorResource { .init(name: "AccentColor", path: [], bundle: bundle) }
}
/// This `_R.image` struct is generated, and contains static references to 23 images.
/// This `_R.image` struct is generated, and contains static references to 30 images.
struct image {
let bundle: Foundation.Bundle
/// Image `apple_icon`.
var apple_icon: RswiftResources.ImageResource { .init(name: "apple_icon", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `btn_back_black`.
var btn_back_black: RswiftResources.ImageResource { .init(name: "btn_back_black", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `btn_back_white`.
var btn_back_white: RswiftResources.ImageResource { .init(name: "btn_back_white", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `default_user`.
var default_user: RswiftResources.ImageResource { .init(name: "default_user", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `discover`.
var discover: RswiftResources.ImageResource { .init(name: "discover", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `discover_selected`.
var discover_selected: RswiftResources.ImageResource { .init(name: "discover_selected", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `dsj`.
var dsj: RswiftResources.ImageResource { .init(name: "dsj", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `guest_icon`.
var guest_icon: RswiftResources.ImageResource { .init(name: "guest_icon", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `hadoop_match_filter`.
var hadoop_match_filter: RswiftResources.ImageResource { .init(name: "hadoop_match_filter", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `home`.
var home: RswiftResources.ImageResource { .init(name: "home", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
......@@ -164,6 +182,9 @@ struct _R {
/// Image `profile_selected`.
var profile_selected: RswiftResources.ImageResource { .init(name: "profile_selected", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `reasearch_icon`.
var reasearch_icon: RswiftResources.ImageResource { .init(name: "reasearch_icon", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
/// Image `refresh_icon`.
var refresh_icon: RswiftResources.ImageResource { .init(name: "refresh_icon", path: [], bundle: bundle, locale: nil, onDemandResourceTags: nil) }
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!