From: liangzhenying <867174124@qq.com> Date: Mon, 26 Jan 2026 06:12:24 +0000 (+0800) Subject: 个人信息页新增身高体重 X-Git-Tag: RaisoundVad~2 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=0509c1064d6690e659a650d7b5677c863a8d8555;p=mirrors%2FShenYin.git 个人信息页新增身高体重 --- diff --git a/ShenYin/ShenYin/Launch/SceneDelegate.swift b/ShenYin/ShenYin/Launch/SceneDelegate.swift index 13273e9..fa4c4d0 100644 --- a/ShenYin/ShenYin/Launch/SceneDelegate.swift +++ b/ShenYin/ShenYin/Launch/SceneDelegate.swift @@ -19,8 +19,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { App.shared.window = window // window?.rootViewController = BaseTC() // MapManager.shared.setupSdk() -// window?.rootViewController = UINavigationController(rootViewController: ReadyVC()) - AppLaunch.start() + window?.rootViewController = UINavigationController(rootViewController: SportSetVC()) +// AppLaunch.start() } func sceneDidDisconnect(_ scene: UIScene) { diff --git a/ShenYin/ShenYin/UI/Mine/AboutVC.swift b/ShenYin/ShenYin/UI/Mine/AboutVC.swift index 4f8bca7..1db3c4e 100644 --- a/ShenYin/ShenYin/UI/Mine/AboutVC.swift +++ b/ShenYin/ShenYin/UI/Mine/AboutVC.swift @@ -23,7 +23,7 @@ class AboutVC: BaseVC{ v.rowHeight = 52 v.sectionHeaderHeight = 52 v.separatorStyle = .none - v.register(CustomCell1.self, forCellReuseIdentifier: CustomCell1.reuseID) + v.register(CustomCell.self, forCellReuseIdentifier: CustomCell.reuseID) v.register(CustomSectionHeader.self, forHeaderFooterViewReuseIdentifier: CustomSectionHeader.reuseID) v.tableHeaderView = AboutHeaderView(frame: CGRect(x: 0, y: 0, width: kScreenWid, height: 175)) } @@ -48,7 +48,7 @@ extension AboutVC:UITableViewDelegate,UITableViewDataSource { } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = CustomCell1.cell(withTableView: tableView, indexPath: indexPath) + let cell = CustomCell.cell(withTableView: tableView, indexPath: indexPath) cell.type = list[indexPath.section][indexPath.row] let rect = CGRect(x: 0, y: 0, width: kScreenWid - 36, height: 52) if indexPath.row == 0 { diff --git a/ShenYin/ShenYin/UI/Mine/AccountSetVC.swift b/ShenYin/ShenYin/UI/Mine/AccountSetVC.swift index 5ca7cf7..1809ed8 100644 --- a/ShenYin/ShenYin/UI/Mine/AccountSetVC.swift +++ b/ShenYin/ShenYin/UI/Mine/AccountSetVC.swift @@ -24,7 +24,7 @@ class AccountSetVC: BaseVC{ v.rowHeight = 52 v.sectionHeaderHeight = 52 v.separatorStyle = .none - v.register(CustomCell1.self, forCellReuseIdentifier: CustomCell1.reuseID) + v.register(CustomCell.self, forCellReuseIdentifier: CustomCell.reuseID) v.register(CustomSectionHeader.self, forHeaderFooterViewReuseIdentifier: CustomSectionHeader.reuseID) v.tableHeaderView = header } @@ -59,7 +59,7 @@ extension AccountSetVC:UITableViewDelegate,UITableViewDataSource { return view } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = CustomCell1.cell(withTableView: tableView, indexPath: indexPath) + let cell = CustomCell.cell(withTableView: tableView, indexPath: indexPath) let list = list[indexPath.section].list cell.type = list[indexPath.row] let rect = CGRect(x: 0, y: 0, width: kScreenWid - 36, height: 52) diff --git a/ShenYin/ShenYin/UI/Mine/Instructions/InstructionsVC.swift b/ShenYin/ShenYin/UI/Mine/Instructions/InstructionsVC.swift index b974a77..e553155 100644 --- a/ShenYin/ShenYin/UI/Mine/Instructions/InstructionsVC.swift +++ b/ShenYin/ShenYin/UI/Mine/Instructions/InstructionsVC.swift @@ -30,7 +30,7 @@ class InstructionsVC: BaseVC{ v.rowHeight = 52 v.sectionHeaderHeight = 52 v.separatorStyle = .none - v.register(CustomCell1.self, forCellReuseIdentifier: CustomCell1.reuseID) + v.register(CustomCell.self, forCellReuseIdentifier: CustomCell.reuseID) // v.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: kScreenHei, height: 20)) } @@ -65,7 +65,7 @@ extension InstructionsVC:UITableViewDelegate,UITableViewDataSource { return searchList.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = CustomCell1.cell(withTableView: tableView, indexPath: indexPath) + let cell = CustomCell.cell(withTableView: tableView, indexPath: indexPath) cell.titleLabel.text = searchList[indexPath.row].name let rect = CGRect(x: 0, y: 0, width: kScreenWid - 36, height: 52) if indexPath.row == 0 { diff --git a/ShenYin/ShenYin/UI/Mine/MoreSetVC.swift b/ShenYin/ShenYin/UI/Mine/MoreSetVC.swift index f40599f..d74f9c9 100644 --- a/ShenYin/ShenYin/UI/Mine/MoreSetVC.swift +++ b/ShenYin/ShenYin/UI/Mine/MoreSetVC.swift @@ -28,7 +28,7 @@ class MoreSetVC: BaseVC{ v.rowHeight = 52 v.sectionHeaderHeight = 52 v.separatorStyle = .none - v.register(CustomCell1.self, forCellReuseIdentifier: CustomCell1.reuseID) + v.register(CustomCell.self, forCellReuseIdentifier: CustomCell.reuseID) v.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: kScreenHei, height: 20)) v.bounces = false } @@ -106,7 +106,7 @@ extension MoreSetVC:UITableViewDelegate,UITableViewDataSource { return list.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = CustomCell1.cell(withTableView: tableView, indexPath: indexPath) + let cell = CustomCell.cell(withTableView: tableView, indexPath: indexPath) cell.type = list[indexPath.row] let rect = CGRect(x: 0, y: 0, width: kScreenWid - 36, height: 52) if indexPath.row == 0 { diff --git a/ShenYin/ShenYin/UI/Mine/UserInfo/CustomCell1.swift b/ShenYin/ShenYin/UI/Mine/UserInfo/CustomCell.swift similarity index 57% rename from ShenYin/ShenYin/UI/Mine/UserInfo/CustomCell1.swift rename to ShenYin/ShenYin/UI/Mine/UserInfo/CustomCell.swift index b6b2506..092b53c 100644 --- a/ShenYin/ShenYin/UI/Mine/UserInfo/CustomCell1.swift +++ b/ShenYin/ShenYin/UI/Mine/UserInfo/CustomCell.swift @@ -1,5 +1,5 @@ // -// CustomCell1.swift +// CustomCell.swift // ShenYin // // Created by liangshi on 2025/8/25. @@ -8,9 +8,12 @@ public enum CustomCellType: Int { case avatar case nickName case gender + case birthday + case height + case weight + case hobbies case area - - + case account case phone case email @@ -29,6 +32,19 @@ public enum CustomCellType: Int { case deregister + case light + case voiceReport + case lcReport + case xlfdReport + case guideReport + case metronome + case metronomeRate + case metronomeAudio + case background + case permisson + case realData + + var title:String{ switch self { case .avatar: @@ -37,6 +53,14 @@ public enum CustomCellType: Int { return "昵称".l10n case .gender: return "性别".l10n + case .birthday: + return "生日".l10n + case .height: + return "身高".l10n + case .weight: + return "体重".l10n + case .hobbies: + return "运动偏好".l10n case .area: return "国家与地区".l10n @@ -71,13 +95,35 @@ public enum CustomCellType: Int { case .deregister: return "注销账号".l10n + + case .light: + return "灯带设置".l10n + case .voiceReport: + return "语音播报".l10n + case .lcReport: + return "里程播报".l10n + case .xlfdReport: + return "训练分段播报".l10n + case .guideReport: + return "指导播报".l10n + case .metronome: + return "节拍器".l10n + case .metronomeRate: + return "节拍器频率".l10n + case .metronomeAudio: + return "节拍器声音".l10n + case .background: + return "后台保护".l10n + case .permisson: + return "运动权限".l10n + case .realData: + return "运动实况".l10n } } - } -class CustomCell1: BaseTableViewCell { +class CustomCell: BaseTableViewCell { let bgView = UIView() let titleLabel = UILabel() let nextIcon = UIImageView() @@ -89,7 +135,6 @@ class CustomCell1: BaseTableViewCell { titleLabel.text = type.title valueIcon.isHidden = type != .avatar - if type == .nickName || type == .gender || type == .area { valueLabel.isHidden = false } @@ -180,6 +225,83 @@ class CustomCell1: BaseTableViewCell { m.left.equalToSuperview().inset(90) } } - +} + + +class SwitchCell: BaseTableViewCell { + let bgView = UIView() + let titleLabel = UILabel() + let detailLabel = UILabel() + let iSwitch = UISwitch() + var hasDetail:Bool = true{ + didSet{ + detailLabel.isHidden = !hasDetail + if hasDetail { + titleLabel.snp.makeConstraints { (m) in + m.top.equalToSuperview().inset(16) + m.left.equalToSuperview().offset(16) + } + } + else{ + titleLabel.snp.makeConstraints { (m) in + m.centerY.equalToSuperview() + m.left.equalToSuperview().offset(16) + } + + } + } + } + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + override func setupViews() { + contentView.addSubview(bgView) + bgView.addSubviews([titleLabel,detailLabel,iSwitch]) + + backgroundColor = .color(.bgColor) + contentView.backgroundColor = .clear + selectionStyle = .none + bgView.do { v in + v.backgroundColor = .color(.cellBg) + } + titleLabel.do { (v) in + v.textColor = .color(.first) + v.font = .bold(14) + v.textAlignment = .left + } + detailLabel.do { (v) in + v.textColor = .color(.secondary) + v.font = .regular(10) + v.textAlignment = .left + v.isHidden = !hasDetail + } + } + + override func setupLayout() { + bgView.snp.makeConstraints { (m) in + m.left.right.equalToSuperview().inset(18) + m.top.equalToSuperview() + m.bottom.equalToSuperview() + } + titleLabel.snp.makeConstraints { (m) in + m.top.equalToSuperview().inset(16) + m.left.equalToSuperview().offset(16) + } + detailLabel.snp.makeConstraints { (m) in + m.bottom.equalToSuperview().inset(16) + m.left.equalToSuperview().offset(16) + } + iSwitch.snp.makeConstraints { (m) in + m.width.equalTo(50) + m.height.equalToSuperview() + m.right.equalToSuperview().inset(15) + m.centerY.equalToSuperview() + } + } } diff --git a/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoVC.swift b/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoVC.swift index b7d72a4..c0742e0 100644 --- a/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoVC.swift +++ b/ShenYin/ShenYin/UI/Mine/UserInfo/UserInfoVC.swift @@ -8,7 +8,7 @@ import UIKit class UserInfoVC: BaseVC{ let tableView = UITableView(frame: .zero, style: .plain) - let list:[CustomCellType] = [.avatar,.nickName,.gender,.area] + let list:[CustomCellType] = [.avatar,.nickName,.gender,.birthday,.height,.weight,.hobbies,.area] let imgPicker = ImagePickerManager() override func viewDidLoad() { @@ -24,7 +24,7 @@ class UserInfoVC: BaseVC{ v.rowHeight = 52 v.sectionHeaderHeight = 52 v.separatorStyle = .none - v.register(CustomCell1.self, forCellReuseIdentifier: CustomCell1.reuseID) + v.register(CustomCell.self, forCellReuseIdentifier: CustomCell.reuseID) } view.addSubview(tableView) } @@ -47,7 +47,7 @@ class UserInfoVC: BaseVC{ } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = CustomCell1.cell(withTableView: tableView, indexPath: indexPath) + let cell = CustomCell.cell(withTableView: tableView, indexPath: indexPath) cell.type = list[indexPath.row] let rect = CGRect(x: 0, y: 0, width: kScreenWid - 36, height: 52) if indexPath.row == 0 { @@ -73,6 +73,18 @@ class UserInfoVC: BaseVC{ case .area: areaAction() break + case .birthday: + birthdayAction() + break + case .height: + heightAction() + break + case .weight: + weightAction() + break + case .hobbies: + hobiesAction() + break default: break } @@ -81,6 +93,45 @@ class UserInfoVC: BaseVC{ extension UserInfoVC{ + func birthdayAction(){ + let v = CustomPicker3(title: "日期".l10n) +// v.selectedIndex = 50 + v.show() + v.didSelected = {[weak self] (date) in + guard let self = self else { return } + + } + } + func heightAction(){ + let list = Array(stride(from: 100, to: 250, by: 1)).map { String($0) + "cm" } + let v = CustomPicker2(title: "身高".l10n, list:list ) + v.selectedIndex = 50 + v.show() + v.didSelected = {[weak self] (index,value) in + guard let self = self else { return } + + } + } + func weightAction(){ + let list = Array(stride(from: 20, to: 200, by: 1)).map { String($0) + "kg" } + let v = CustomPicker2(title: "身高".l10n, list:list ) + v.selectedIndex = 0 + v.show() + v.didSelected = {[weak self] (index,value) in + guard let self = self else { return } + + } + } + func hobiesAction(){ + let list = ["入门".l10n,"规律运动".l10n,"资深达人".l10n] + let v = CustomPicker2(title: "运动偏好".l10n, list:list ) + v.selectedIndex = 0 + v.show() + v.didSelected = {[weak self] (index,value) in + guard let self = self else { return } + + } + } func genderAction(){ let vc = GenderVC() vc.didSelected = {[weak self] model in diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Set/SportSetVC.swift b/ShenYin/ShenYin/UI/Sport/Sport/Set/SportSetVC.swift new file mode 100644 index 0000000..49c1ad1 --- /dev/null +++ b/ShenYin/ShenYin/UI/Sport/Sport/Set/SportSetVC.swift @@ -0,0 +1,93 @@ +// +// SportSetVC.swift +// ShenYin +// +// Created by liangshi on 2026/1/23. +//,, + + +import UIKit +class SportSetVC: BaseVC{ + let tableView = UITableView(frame: .zero, style: .plain) + let list:[(title:String,list:[CustomCellType])] = [("".l10n,[.light,.voiceReport,.lcReport,.xlfdReport,.guideReport,.metronome,.metronomeRate,.metronomeAudio,.background,.permisson]),("组队设置".l10n,[.realData]),] + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + override func setupViews() { + self.navBar.title = "设置".l10n + tableView.do { v in + v.backgroundColor = .color(.bgColor) + v.delegate = self + v.dataSource = self + v.rowHeight = 52 + v.sectionHeaderHeight = 52 + v.separatorStyle = .none + v.register(CustomCell.self, forCellReuseIdentifier: CustomCell.reuseID) + } + + view.addSubview(tableView) + } + override func setupLayout() { + tableView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.top.equalTo(kNavBtm) + } + } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) +// CacheManager.shared.user.tokenIsValid(){[weak self] sucess in +// self?.header.updateUI() +// } + } +} + +extension SportSetVC:UITableViewDelegate,UITableViewDataSource { + func numberOfSections(in tableView: UITableView) -> Int { + return list.count + } + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return list[section].list.count + } + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + let view = CustomSectionHeader.header(withTableView: tableView) + view.titleLabel.text = list[section].title + view.titleLabel.textColor = .color(.secondary) + return view + } + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + if list[section].title.isEmpty { + return 0 + } + else{ + return 52 + } + } + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = CustomCell.cell(withTableView: tableView, indexPath: indexPath) + let list = list[indexPath.section].list + cell.type = list[indexPath.row] + let rect = CGRect(x: 0, y: 0, width: kScreenWid - 36, height: 52) + if indexPath.row == 0 { + cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 12, height: 12)) + } + else if indexPath.row == list.count - 1{ + cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.bottomLeft,.bottomRight], cornerRadii: CGSize(width: 12, height: 12)) + } + else{ + cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.allCorners], cornerRadii: CGSize(width: 0, height: 0)) + } + if list.count == 1 { + cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.allCorners], cornerRadii: CGSize(width: 12, height: 12)) + } + return cell + } + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let data = list[indexPath.section].list[indexPath.row] + switch data { + default: + break + } + } +} diff --git a/ShenYin/ShenYin/UI/Sport/Sport/Set/SwitchCell.swift b/ShenYin/ShenYin/UI/Sport/Sport/Set/SwitchCell.swift new file mode 100644 index 0000000..b0501b7 --- /dev/null +++ b/ShenYin/ShenYin/UI/Sport/Sport/Set/SwitchCell.swift @@ -0,0 +1,8 @@ +// +// Untitled.swift +// ShenYin +// +// Created by liangshi on 2026/1/23. +// + + diff --git a/ShenYin/ShenYin/UI/common/CustomButton.swift b/ShenYin/ShenYin/UI/common/CustomButton.swift index 91c3c9f..a56ca70 100644 --- a/ShenYin/ShenYin/UI/common/CustomButton.swift +++ b/ShenYin/ShenYin/UI/common/CustomButton.swift @@ -20,7 +20,7 @@ class CustomButton: UIButton { if CCDevice.isJoy{ setTitle(title, for: .normal) addTarget(target, action: action, for: .touchUpInside) - layer.cornerRadius = 23 + layer.cornerRadius = 12 layer.masksToBounds = true titleLabel?.font = font diff --git a/ShenYin/ShenYin/UI/common/pop/CustomPicker2.swift b/ShenYin/ShenYin/UI/common/pop/CustomPicker2.swift new file mode 100644 index 0000000..c8e46f2 --- /dev/null +++ b/ShenYin/ShenYin/UI/common/pop/CustomPicker2.swift @@ -0,0 +1,132 @@ +// +// Untitled.swift +// ShenYin +// +// Created by liangshi on 2026/1/23. +// + +import UIKit + +class CustomPicker2: BasePresentView { + private let titleLabel = UILabel() + private let btn = UIButton(type: .custom) + private let okBtn = CustomButton() + private let pickerView = UIPickerView() + var list: [String] = [] + var disableTitle: String = "" { + didSet { + pickerView.reloadAllComponents() + } + } + var selectedIndex = 0 { + didSet { + // 选中当前索引对应的行 + pickerView.selectRow(selectedIndex, inComponent: 0, animated: true) + } + } + var didSelected: ((Int, String) -> Void)? + private var title: String = "" + + init(title: String, list: [String]) { + self.title = title + self.list = list + let h = CGFloat(50 + 220 + kSafeBtm) + super.init(contentHeight: h) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func setupSubView() { + super.setupSubView() + contentView.addSubviews([titleLabel, btn,okBtn, pickerView]) + } + + override func setupLayout() { + super.setupLayout() + titleLabel.snp.makeConstraints { (m) in + m.top.equalToSuperview() + m.left.right.equalToSuperview().inset(60) + m.height.equalTo(50) + } + btn.snp.makeConstraints { (m) in + m.centerY.equalTo(titleLabel) + m.right.equalToSuperview() + m.size.equalTo(60) + } + okBtn.snp.makeConstraints { make in + make.bottom.equalToSuperview().inset(32) + make.left.right.equalToSuperview().inset(51) + make.height.equalTo(46) + } + pickerView.snp.makeConstraints { make in + make.left.right.equalToSuperview() + make.top.equalToSuperview().inset(50) + make.bottom.equalTo(okBtn.snp.top).offset(-10) + } + + } + + override func setupStyle() { + super.setupStyle() + contentView.backgroundColor = .color(.cellBg) + titleLabel.do { (v) in + v.textColor = .color(.secondary) + v.font = .semiBold(16) + v.textAlignment = .center + v.text = title + } + btn.do { v in + v.setImage(UIImage(named: "close_icon"), for: .normal) + v.addTarget(self, action: #selector(closeAction), for: .touchUpInside) + } + pickerView.do { v in + v.backgroundColor = .color(.cellBg) + v.delegate = self + v.dataSource = self + } + okBtn.set(title: "确定".l10n,style: .theme1, target: self, action: #selector(okAction)) + } + + @objc func closeAction() { + hide() + } + @objc func okAction(){ + didSelected?(selectedIndex, list[selectedIndex]) + hide() + } +} + +extension CustomPicker2: UIPickerViewDelegate, UIPickerViewDataSource { + func numberOfComponents(in pickerView: UIPickerView) -> Int { + return 1 + } + + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + return list.count + } + func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat { + return 50 + } + + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + let item = list[row] + // 如果是禁用项,则显示不同样式(这里通过返回带删除线的文本表示) + if item == disableTitle { + return "❌\(item)" + } + return item + } + + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + if list[row] == disableTitle { + // 如果选择的是禁用项,则恢复到之前的选择 + pickerView.selectRow(selectedIndex, inComponent: 0, animated: true) + return + } + selectedIndex = row + didSelected?(selectedIndex, list[selectedIndex]) +// hide() + } +} diff --git a/ShenYin/ShenYin/UI/common/pop/CustomPicker3.swift b/ShenYin/ShenYin/UI/common/pop/CustomPicker3.swift new file mode 100644 index 0000000..78dea69 --- /dev/null +++ b/ShenYin/ShenYin/UI/common/pop/CustomPicker3.swift @@ -0,0 +1,110 @@ +import UIKit + +class CustomPicker3: BasePresentView { + private let titleLabel = UILabel() + private let btn = UIButton(type: .custom) + private let okBtn = CustomButton() + private let datePicker = UIDatePicker() + var selectedDate = Date() { + didSet { + datePicker.date = selectedDate + } + } + var didSelected: ((Date) -> Void)? + private var title: String = "" + + init(title: String, defaultDate: Date = createDate(year: 2000, month: 1, day: 1)) { + self.title = title + self.selectedDate = defaultDate + let h = CGFloat(50 + 250 + kSafeBtm) // UIDatePicker的高度通常为250左右加上底部安全距离 + super.init(contentHeight: h) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func setupSubView() { + super.setupSubView() + contentView.addSubviews([titleLabel, btn, okBtn, datePicker]) + } + + override func setupLayout() { + super.setupLayout() + titleLabel.snp.makeConstraints { (m) in + m.top.equalToSuperview() + m.left.right.equalToSuperview().inset(60) + m.height.equalTo(50) + } + btn.snp.makeConstraints { (m) in + m.centerY.equalTo(titleLabel) + m.right.equalToSuperview() + m.size.equalTo(60) + } + okBtn.snp.makeConstraints { make in + make.bottom.equalToSuperview().inset(32) + make.left.right.equalToSuperview().inset(51) + make.height.equalTo(46) + } + datePicker.snp.makeConstraints { make in + make.left.right.equalToSuperview() + make.top.equalToSuperview().inset(50) + make.bottom.equalTo(okBtn.snp.top).offset(-10) + } + } + + override func setupStyle() { + super.setupStyle() + contentView.backgroundColor = .color(.cellBg) + titleLabel.do { (v) in + v.textColor = .color(.secondary) + v.font = .semiBold(16) + v.textAlignment = .center + v.text = title + } + btn.do { v in + v.setImage(UIImage(named: "close_icon"), for: .normal) + v.addTarget(self, action: #selector(closeAction), for: .touchUpInside) + } + datePicker.do { v in + if #available(iOS 13.4, *) { + v.preferredDatePickerStyle = .wheels + } + v.backgroundColor = .color(.cellBg) + v.datePickerMode = .date + if DCConfig.appLanguage == .chinse || DCConfig.appLanguage == .Traditional_Chinese { + v.locale = Locale(identifier: "zh_CN") + } + + v.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged) + v.minimumDate = CustomPicker3.createDate(year: 1900, month: 1, day: 1) + v.maximumDate = Date() + v.date = selectedDate + } + okBtn.set(title: "确定", style: .theme1, target: self, action: #selector(okAction)) + } + + @objc func dateChanged(_ sender: UIDatePicker) { + selectedDate = sender.date + } + + @objc func closeAction() { + hide() + } + + @objc func okAction() { + didSelected?(selectedDate) + hide() + } + + private static func createDate(year: Int, month: Int, day: Int) -> Date { + var components = DateComponents() + components.year = year + components.month = month + components.day = day + components.hour = 0 + components.minute = 0 + components.second = 0 + return Calendar.current.date(from: components) ?? Date() + } +} diff --git a/ShenYin/ShenYin/lan/chinese.swift b/ShenYin/ShenYin/lan/chinese.swift index fa2ab45..51b6b72 100644 --- a/ShenYin/ShenYin/lan/chinese.swift +++ b/ShenYin/ShenYin/lan/chinese.swift @@ -268,6 +268,331 @@ let chineseMap:[String:String] = "嗨!我是":"", "查找眼镜":"", "眼镜响铃":"", + + "未识别到语音内容":"", + + "生日":"", + "身高":"", + "体重":"", + "运动偏好":"", + "入门":"", + "规律运动":"", + "资深达人":"", + + + + "运动":"", + "录音":"", + "音乐":"", + "户外跑步":"", + "户外骑行":"", + "健走":"", + "运动数据":"", + "全部":"", + "创建团队":"", + "创建我的团队":"", + "我创建和已加入的团队":"", + "智能运动计划建议":"", + "AI规划个人定制运动计划":"", + "路线探索":"", + "健走/跑步/骑行":"", + "目标":"", + "路线":"", + "组队":"", + "语音陪练":"", + "积累骑行距离":"", + "积累跑步距离":"", + "选择播报间距" :"", + "设置目标":"", + "距离":"", + "公里":"", + "设置路线":"", + "选择规划方式":"", + "请选择想要的路线样式":"", + "根据距离规划":"", + "选择跑步目标":"", + "请设置您本次的跑步目标":"", + "确认线路":"", + "选择一条适合的道路":"", + "确定并保存":"", + "总距离":"", + "时长":"", + "配速":"", + "卡路里":"", + "步数":"", + "长按3秒解锁":"", + "时速":"", + "结束运动":"", + "本次运动过短,将不会记录数据,是否结束?":"", + "结束":"", + "继续运动":"", + "平均配速":"", + "运动消耗":"", + "平均步幅":"", + "平均步频":"", + "积累爬升":"", + "积累下降":"", + "最快配速":"", + "每公里配速":"", + "公里,累计用时":"", + "步频":"", + "最快步频":"", + "最低海拔":"", + "最高海拔":"", + + "运动感受":"", + "非常轻松":"", + "很轻松":"", + "轻松":"", + "适中":"", + "稍微出汗":"", + "困难":"", + "很困难":"", + "力竭":"", + "无法坚持":"", + "平均时速":"", + "平均速度":"", + "最快速度":"", + + "指导语音密度" :"", + "详细":"", + "1公里配速、总平均配速、1公里用时、总运动时长":"", + "简洁":"", + "1公里配速、1公里用时":"", + "极简":"", + "总距离、总时长":"", + "次/分钟":"", + "默认":"", + "清脆":"", + "重击":"", + + + "语音播报" :"", + "节拍器" :"", + "里程播报" :"", + "当前已跑里程播报" :"", + "训练分段播报" :"", + "训练分段开始和结束提示音" :"", + "指导播报" :"", + "跑步过程中的指导于语音" :"", + "节拍器频率" :"", + "节拍器声音" :"", + "后台保护" :"", + "运动权限" :"", + "组队设置" :"", + "运动实况":"", + "组内成员基本运动信息实时显示" :"", + "开启灯带,解锁更多运动氛围" :"", + "灯带" :"", + "常亮" :"", + "呼吸" :"", + "闪烁":"", + "亮度":"", + "同步至队员":"", + "高亮度提升可见度,低亮度更省电量, 建议根据使用场景合理调节":"", + + "所有运动":"", + "周":"", + "月":"", + "å¹´":"", + "总":"", + "总时长":"", + "总消耗(千卡)":"", + "次数":"", + "没有更多内容":"", + "运动时长统计":"", + "类型":"", + "占比":"", + "用时":"", + "次":"", + + + "设置团队头像":"", + "团队名称":"", + "给团队起个名字":"", + "团队类型":"", + "简介":"", + "描述一下您的团":"", + "灯带设置":"", + "加入验证":"", + "开启后,成员需要申请才能加入":"", + "完成创建":"", + "户外跑步团":"", + "户外骑行团":"", + "户外健走团":"", + "团队玩法说明":"", + "运动团队是什么?":"", + "运动团队是由具备共同运动目标、互补技能的个体组成的集体,成员通过协作配合参与体育项目,追求竞技成绩、团队荣誉或共同健身目标;":"", + "团队玩法有什么?":"", + "多人在线同步运动时,可实时查看队友的位置与运动数据,随时掌握彼此状态; 在选定时段内,系统会针对不同运动数据指标(如配速、距离等),生成对应的排名; 可自主选择团队内的功能角色,基于角色定位与队友分工协作,提升团队运动效率与配合度。":"", + "团队详情":"", + "团长:":"", + "团队号:":"", + "简介:":"", + "总人数 (人)":"", + "总里程 (公里)":"", + "总时长 (分钟)":"", + "团队目标":"", + "距离 (公里)":"", + "时长 (分钟)":"", + "卡路里 (千卡)":"", + "排行":"", + "榜单排名在完成运动后 10~15 分钟更新":"", + "进入运动":"", + "目标距离":"", + "目标时长":"", + "目标卡路里":"", + "组队运动实况":"", + "成绩":"", + "配速排序 / 里程排序":"", + "选择时间":"", + "成立至今":"", + "团队信息修改":"", + "我的团队角色":"", + "成员管理":"", + "解散团队":"", + "选择你想要承担的团队角色吧":"", + "无":"", + "破风手":"", + "领跑者":"", + "跟跑者":"", + "冲刺手":"", + "配速员":"", + "补给员":"", + "全能手":"", + "团队角色说明":"", + "团队角色是什么?":"", + "团队运动中各角色是分工明确、协同发力的核心单元,通过精准配合最大化团队运动效果;":"", + "破风手:以 “挡风减阻” 为核心,为后方队友节省体能; 领跑者:把控整体节奏,稳定配速避免失衡; 跟跑者:借助风阻优势储备体力,为关键阶段蓄力; 冲刺手:聚焦终点前爆发,锁定最终成绩; 配速员:作为 “节奏标杆”,助力队友校准目标; 补给员:保障物资供应,维持运动续航; 全能手:灵活补位,适配破风、带速等多元需求。":"", + "成员列表":"", + "邀请":"", + "团长转让":"", + "移出团队":"", + "确认要把团长转让给TA吗?":"", + "确认要把TA移出团队吗?":"", + "确认要解散当前团队?":"", + "解散后所有成员均退出团队,确认解散吗?":"", + "确认解散":"", + "团队消息":"", + "入团申请":"", + "申请加入":"", + "同意":"", + "拒绝":"", + "申请通过":"", + "申请失败":"", + "团队解散":"", + "该团队已解散":"", + "加入团队":"", + "团队号":"", + "请输入团队号":"", + "打招呼内容":"", + "团队角色":"", + "退出团队":"", + "我的团队":"", + "我管理的":"", + "我加入的":"", + "人已加入":"", + + "生成计划":"", + "个性定制,打造最适合你的训练计划":"", + "与":"", + "的历史对话":"", + "当前":"", + "你的运动目标是什么":"", + "减重":"", + "提升跑步能力":"", + "你想通过什么运动方式减重":"", + "每周运动天数":"", + "天":"", + "每天运动时长":"", + "分钟左右":"", + "你每周的跑步距离是多少":"", + "你能接受什么难度":"", + "零基础":"", + "中低强度":"", + "中高强度":"", + "高强度":"", + "你是否存在伤病困扰":"", + "不存在伤病困扰":"", + "膝盖":"", + "关节疼痛、卡顿或不适":"", + "腰部":"", + "疼痛或下肢麻木":"", + "肩部":"", + "手腕":"", + "查看详情":"", + "重新定制":"", + "你想提升哪方面的跑步能力":"", + "跑步距离提升":"", + "跑步速度提升":"", + "马拉备赛":"", + "步频提升":"", + "关于你的跑步能力":"", + "当前单次最远跑步距离":"", + + + + "我的歌单":"", + "我的收藏":"", + "全选":"", + "完成":"", + "您要删除这首歌曲吗?":"", + "删除后,这首歌将无法恢复。":"", + "定时设置":"", + "选择定时":"", + "不开启":"", + "分钟":"", + "倒计时结束后关闭APP":"", + "播放完整首后停止":"", + "自定义时间":"", + + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", + // "":"", ] diff --git "a/document/\346\267\261\351\237\263APP \351\252\250\344\274\240\345\257\274\350\200\263\346\234\272\350\277\220\345\212\250\345\212\237\350\203\275\345\256\232\344\271\211-0122-V1.0.docx" "b/document/\346\267\261\351\237\263APP \351\252\250\344\274\240\345\257\274\350\200\263\346\234\272\350\277\220\345\212\250\345\212\237\350\203\275\345\256\232\344\271\211-0122-V1.0.docx" new file mode 100644 index 0000000..e5c82c8 Binary files /dev/null and "b/document/\346\267\261\351\237\263APP \351\252\250\344\274\240\345\257\274\350\200\263\346\234\272\350\277\220\345\212\250\345\212\237\350\203\275\345\256\232\344\271\211-0122-V1.0.docx" differ