);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Example/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = "骨传导sdk";
INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "使用蓝牙哦";
+ INFOPLIST_KEY_NSMicrophoneUsageDescription = "使用麦克风哦";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main;
"\"UIKit\"",
"-ObjC",
);
- PRODUCT_BUNDLE_IDENTIFIER = deepchords.guchuandao.Example;
+ PRODUCT_BUNDLE_IDENTIFIER = deepchords.ai.Example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "Example/VC/Example-Bridging-Header.h";
);
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Example/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = "骨传导sdk";
INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "使用蓝牙哦";
+ INFOPLIST_KEY_NSMicrophoneUsageDescription = "使用麦克风哦";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main;
"\"UIKit\"",
"-ObjC",
);
- PRODUCT_BUNDLE_IDENTIFIER = deepchords.guchuandao.Example;
+ PRODUCT_BUNDLE_IDENTIFIER = deepchords.ai.Example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OBJC_BRIDGING_HEADER = "Example/VC/Example-Bridging-Header.h";
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
+ <key>NSAppTransportSecurity</key>
+ <dict>
+ <key>NSAllowsArbitraryLoads</key>
+ <true/>
+ </dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
</array>
</dict>
</dict>
- <key>NSAppTransportSecurity</key>
- <dict>
- <key>NSAllowsArbitraryLoads</key>
- <true/>
- </dict>
- <key>CFBundleDisplayName</key>
- <string>骨传导sdk</string>
- <key>NSMicrophoneUsageDescription</key>
- <string>使用麦克风哦</string>
</dict>
</plist>
UI/Sleep/SleepVM.swift,
UI/Sport/MusicRootView.swift,
UI/Sport/RecordRootView.swift,
+ UI/Sport/Sport/Light/BrightnessView.swift,
+ UI/Sport/Sport/Light/LightSetVC.swift,
+ UI/Sport/Sport/Light/ModeView.swift,
+ UI/Sport/Sport/Light/StateView.swift,
UI/Sport/Sport/Ready/CountdownView.swift,
UI/Sport/Sport/Ready/CustomMapView.swift,
UI/Sport/Sport/Ready/FooterView.swift,
UI/Sport/Sport/Set/SportSetCell.swift,
UI/Sport/Sport/Set/SportSetModel.swift,
UI/Sport/Sport/Set/SportSetVC.swift,
+ UI/Sport/Sport/SportDetail/SportDetailBoard.swift,
+ UI/Sport/Sport/SportDetail/SportDetailVC.swift,
+ UI/Sport/Sport/Sporting/DetailBoard.swift,
+ UI/Sport/Sport/Sporting/SimpleBoard.swift,
+ UI/Sport/Sport/Sporting/SportingVC.swift,
+ UI/Sport/Sport/Target/CalorieView.swift,
+ UI/Sport/Sport/Target/DistanceView.swift,
+ UI/Sport/Sport/Target/DurationView.swift,
+ UI/Sport/Sport/Target/SportTargetVC.swift,
UI/Sport/Sport/Tools/MapManager.swift,
UI/Sport/SportHomeVC.swift,
UI/Sport/TranslateRootView.swift,
Sdk/JoySdk/VC/ModeVC.swift,
UI/Sport/MusicRootView.swift,
UI/Sport/RecordRootView.swift,
+ UI/Sport/Sport/Light/BrightnessView.swift,
+ UI/Sport/Sport/Light/LightSetVC.swift,
+ UI/Sport/Sport/Light/ModeView.swift,
+ UI/Sport/Sport/Light/StateView.swift,
UI/Sport/Sport/Ready/CountdownView.swift,
UI/Sport/Sport/Ready/CustomMapView.swift,
UI/Sport/Sport/Ready/FooterView.swift,
UI/Sport/Sport/Set/SportSetCell.swift,
UI/Sport/Sport/Set/SportSetModel.swift,
UI/Sport/Sport/Set/SportSetVC.swift,
+ UI/Sport/Sport/SportDetail/SportDetailBoard.swift,
+ UI/Sport/Sport/SportDetail/SportDetailVC.swift,
+ UI/Sport/Sport/Sporting/DetailBoard.swift,
+ UI/Sport/Sport/Sporting/SimpleBoard.swift,
+ UI/Sport/Sport/Sporting/SportingVC.swift,
+ UI/Sport/Sport/Target/CalorieView.swift,
+ UI/Sport/Sport/Target/DistanceView.swift,
+ UI/Sport/Sport/Target/DurationView.swift,
+ UI/Sport/Sport/Target/SportTargetVC.swift,
UI/Sport/Sport/Tools/MapManager.swift,
UI/Sport/SportHomeVC.swift,
UI/Sport/TranslateRootView.swift,
case updatePhone(param:[String:Any])
/// 更新邮箱
case updateEmail(param:[String:Any])
+ /// 获取用户信息
+ case getUserInfo
/// 更新用户信息
case updateUserInfo(param:[String:Any])
/// 获取用户存储空间
case voiceRecordCollection(param:[String:Any])
/// 获取背景图
case backgroundList
+
+ /// 创建团队
+ case createSportGroup(param:[String:Any])
+ /// 获取团队
+ case getSportGroupList(param:[String:Any])
+ /// 申请加入团队
+ case applyJoinGroup(param:[String:Any])
}
// 实现TargetType协议
return "/uc/phone/bind?smsCode=\(param["smsCode"]!)&phone=\(param["phone"]!)"
case .updateEmail(let param):
return "/uc/email?emailCode=\(param["emailCode"]!)&email=\(param["email"]!)"
+ case .getUserInfo:
+ return "/uc/userinfo"
case .updateUserInfo(let param):
var path = "/uc/userinfo?"
- if let username = param["username"]{
- path += "username=\(username)&"
+ if let text = param["username"]{
+ path += "username=\(text)&"
+ }
+ if let text = param["gender"]{
+ path += "gender=\(text)&"
+ }
+ if let text = param["tall"]{
+ path += "tall=\(text)&"
}
- if let gender = param["gender"]{
- path += "gender=\(gender)&"
+ if let text = param["weight"]{
+ path += "weight=\(text)&"
}
- if let countyId = param["countryId"]{
- path += "countyId=\(countyId)"
+ if let text = param["birthday"]{
+ path += "birthday=\(text)&"
}
+ if let text = param["preference"]{
+ path += "preference=\(text)&"
+ }
+ if let text = param["countryId"]{
+ path += "countyId=\(text)"
+ }
+ Logger.debug("path => ",path)
return path
case .storageSize:
return "/res/voice-file/storage-size"
case .backgroundList:
return "/dev/devBg/list"
+
+
+ case .createSportGroup(_):
+ return "/sp/sport-group"
+ case .getSportGroupList(_):
+ return "/sp/sport-group/list"
+ case .applyJoinGroup(let param):
+ return "/sp/sport-group/\(param["id"]!)/apply"
+
+
}
}
var method:RequestMethod{
switch self {
- case .register(_),.phoneCodeLogin(_),.emailCodeLogin(_),.appleLogin(_),.login(_),.commitFeedback(_),.voiceRecord(_),.voiceRecordText(_):
+ case .register(_),.phoneCodeLogin(_),.emailCodeLogin(_),.appleLogin(_),.login(_),.commitFeedback(_),.voiceRecord(_),.voiceRecordText(_),.createSportGroup(_),.applyJoinGroup(_):
return .post
case .updatePwd(_),.updateUserInfo(_),.updatePhone(_),.bindPhone(_),.updateEmail(_),.bindDevice(_),.otaUpdateVersion(_),.voiceRecordCollection(_),.updateVoiceRecord(_):
return .put
params += para
case let .updateVoiceRecord(para):
params += para
+ case let .createSportGroup(para):
+ params += para
+ case let .getSportGroupList(para):
+ params += para
+ case let .applyJoinGroup(para):
+ params += para
default:
break
}
"devtype": "iOS",
"devid": UIDevice().identifierForVendor?.uuidString ?? "unknow",
// "Content - Type": "application/json"
+ "dc-ut":CacheManager.shared.user.token ?? ""
]
}
}
static func request<T: HandyJSON>(_ target: CommomApi,completionHandler:@escaping ((T, String) -> Void)){
let url = target.url
let params = target.param
- Logger.debug("request => ",url)
- Logger.debug(YLToos.jsonToString(params))
+ Logger.debug("request => ",url,YLToos.jsonToString(params))
+// Logger.debug("header =>",YLToos.jsonToString(target.headers!))
if target.method == .get {
- HTTP.GET(url,parameters: params,requestSerializer: JSONParameterSerializer()){ response in
+ HTTP.GET(url,parameters: params,headers: target.headers,requestSerializer: JSONParameterSerializer()){ response in
handleResponse(response, completionHandler: completionHandler)
}
}
else if target.method == .post{
- HTTP.POST(url,parameters: params,requestSerializer: JSONParameterSerializer()){ response in
+ HTTP.POST(url,parameters: params,headers: target.headers,requestSerializer: JSONParameterSerializer()){ response in
handleResponse(response, completionHandler: completionHandler)
}
}
else if target.method == .put{
- HTTP.PUT(url,parameters: params,requestSerializer: JSONParameterSerializer()){ response in
+ HTTP.PUT(url,parameters: params,headers: target.headers,requestSerializer: JSONParameterSerializer()){ response in
handleResponse(response, completionHandler: completionHandler)
}
}
else if target.method == .delete{
- HTTP.DELETE(url,parameters: params,requestSerializer: JSONParameterSerializer()){ response in
+ HTTP.DELETE(url,parameters: params,headers: target.headers,requestSerializer: JSONParameterSerializer()){ response in
handleResponse(response, completionHandler: completionHandler)
}
}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 137@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 137@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 156@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 156@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 42@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 42@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 157@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 157@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
--- /dev/null
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "Slice 205@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "Slice 205@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
import HandyJSON
enum GenderType:String,HandyJSONEnum{
- case man = "1"
case female = "0"
+ case man = "1"
case unnkown = "2"
var title:String{
switch self {
}
class UserInfo:ResponseBaseModel {
+ /// 用户id
var id = ""
+ /// 头像
var avatar = ""
+ /// 昵称
var userName = ""
+ /// 创建时间
var createTime = ""
+ /// 手机号码
var phone = ""
+ /// 邮箱
var email = ""
+ /// 性别
var gender = GenderType.unnkown
+ /// 国家
var countryName = ""
+ /// 国家id
var countryId = ""
+ /// 生日
+ var birthday:String = ""
+ /// 身高
+ var tall:String = ""
+ ///体重
+ var weight:String = ""
+ /// 偏好
+ var preference:String = ""
+
var cacheCountryName:String{
for item in LoginVM.shared.countryList {
if let cache = UserCache.shared.get(){
self.info = cache
}
-
- if self.token != nil {
- tokenIsValid()
- }
}
var storageSize = 0
}
}
+ func getUserInfo(finished: ((Bool) -> Void)? = nil){
+ if CCDevice.isJoy {
+ HttpClient.request(CommomApi.getUserInfo) { [weak self](model:UserInfoRoot,res) in
+ guard let self = self else{return}
+ if model.isSuccess{
+ self.info = model.data
+ UserCache.shared.save(self.info)
+ finished?(true)
+ }
+ else{
+ if let dict = YLToos.stringToJson(res),let code = dict["code"] as? Int{
+ if code == 50000{
+ logout()
+ }
+ else if code == 50022{
+ if let vc = App.shared.topVC() as? BindingPhoneVC{
+
+ }
+ else{
+ App.shared.goToPage(BindingPhoneVC())
+ }
+ }
+ }
+ finished?(false)
+ }
+
+ }
+ }
+ else{
+ tokenIsValid(finished: finished)
+ }
+ }
func getStorageSize(completion:@escaping (_ result:CommonDataIntModel) ->Void){
HttpClient.request(.storageSize) { [weak self](result:CommonDataIntModel,res) in
}
static func loadCache(){
if CacheManager.shared.user.isLogin {
+ CacheManager.shared.user.tokenIsValid()
App.shared.didLogin()
}
else{
}
func willLogin(){
- CacheManager.shared.user.tokenIsValid {[weak self] success in
+ CacheManager.shared.user.getUserInfo {[weak self] success in
guard let self = self else{return}
if success {
didLogin()
App.shared.window = window
AppLaunch.start()
// MapManager.shared.setupSdk()
-// window?.rootViewController = UINavigationController(rootViewController: SportingVC())
-
+// window?.rootViewController = UINavigationController(rootViewController: CreateGroupVC())
+//
}
func sceneDidDisconnect(_ scene: UIScene) {
self?.startConectBle(model)
}
}
- CacheManager.shared.user.tokenIsValid(){[weak self] sucess in
+ CacheManager.shared.user.getUserInfo{[weak self] sucess in
self?.collectionView.reloadData()
}
}
conetedFailureCallback?(connectPeripheral!)
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
- Logger.debug("蓝牙已断开 \(peripheral)")
+ Logger.debug("蓝牙已断开 \(peripheral)",error?.localizedDescription ?? "",error.debugDescription)
YLprogressHUD.showAutoHiden("蓝牙已断开".l10n)
self.isConnetd = false
if CCDevice.isJoy{
// Created by liangshi on 2026/1/28.
//
-class CCConfig{
- static var appLanguage = AppSupportLanguage.english
-
- static let wxAppID = "wxd9d677e0024caa90"
- static let wxUniversalLink = "https://dc-cloud-pub.tos-cn-guangzhou.volces.com/app/"
- static let appStoreLink = "https://itunes.apple.com/cn/app/6752551504?mt=8"
- /// 版本检测
- static let appStoreVersionURL = "https://itunes.apple.com/cn/lookup?id=6752551504"
-
- /// 服务器地址
- //static let baseURL = "http://118.145.178.188:32000"
- static let baseURL = "https://app-api.deepchords.com"
- //海外版
- // static let baseURL = "https://app-api.deepchords-ai.com"
-
- /// 用户隐私协议地址
- static let yonghuBaseURL = "https://pub-tos.deepchords.com"
-}
-
-
-
//class CCConfig{
// static var appLanguage = AppSupportLanguage.english
-//
+//
// static let wxAppID = "wxeb3291e720293abc"
// static let wxUniversalLink = "https://www.playboykq.com/app/"
// static let appStoreLink = "https://itunes.apple.com/cn/app/6757697090?mt=8"
// /// 版本检测
// static let appStoreVersionURL = "https://itunes.apple.com/cn/lookup?id=6757697090"
-//
+//
// /// 服务器地址
-// static let baseURL = "https://app-api.playboykq.com"
-//
+// static let baseURL = "https://app-api.deepchords.com"
+//
// /// 用户隐私协议地址
// static let yonghuBaseURL = "https://pub-cdn.playboykq.com"
-//
+//
//}
+
+class CCConfig{
+ static var appLanguage = AppSupportLanguage.english
+
+ static let wxAppID = "wxeb3291e720293abc"
+ static let wxUniversalLink = "https://www.playboykq.com/app/"
+ static let appStoreLink = "https://itunes.apple.com/cn/app/6757697090?mt=8"
+ /// 版本检测
+ static let appStoreVersionURL = "https://itunes.apple.com/cn/lookup?id=6757697090"
+
+ /// 服务器地址
+ static let baseURL = "https://app-api.playboykq.com"
+
+ /// 用户隐私协议地址
+ static let yonghuBaseURL = "https://pub-cdn.playboykq.com"
+
+}
self?.startConectBle(model)
}
}
- CacheManager.shared.user.tokenIsValid(){[weak self] sucess in
+ CacheManager.shared.user.getUserInfo(){[weak self] sucess in
self?.collectionView.reloadData()
}
}
/// 日记管理
class Logger {
- static var isDebug: Bool = false
+ static var isDebug: Bool = true
fileprivate static let shared = Logger()
private var fileHandle:FileHandle?
func setupUI(){
if CCDevice.isJoy{
let homeVC = HomeDeviceVC()
+// let homeVC = SportHomeVC()
+
let modeVC = ModeVC()
let sleepVC = SleepVC()
let mineVC = MineVC()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
- CacheManager.shared.user.tokenIsValid(){[weak self] sucess in
+ CacheManager.shared.user.getUserInfo{[weak self] sucess in
self?.header.updateUI()
}
}
}
}
func updateUI(){
- CacheManager.shared.user.tokenIsValid(){[weak self] sucess in
+ CacheManager.shared.user.getUserInfo{[weak self] sucess in
guard let self = self else {return}
titleLabel.text = CacheManager.shared.user.info.userName
icon.kf.setImage(with:CacheManager.shared.user.info.avatar.yc.asUrl )
titleLabel.text = type.title
valueIcon.isHidden = type != .avatar
- if type == .nickName || type == .gender || type == .area {
- valueLabel.isHidden = false
+ if type == .avatar {
+ valueLabel.isHidden = true
}
else{
- valueLabel.isHidden = true
+ valueLabel.isHidden = false
}
let info = CacheManager.shared.user.info
if type == .nickName {
// valueLabel.text = info.countryName
valueLabel.text = info.cacheCountryName
}
+ else if type == .birthday {
+ valueLabel.text = info.birthday
+ }
+ else if type == .height {
+ valueLabel.text = info.tall + "cm"
+ }
+ else if type == .weight {
+ valueLabel.text = info.weight + "kg"
+ }
+ else if type == .hobbies {
+ valueLabel.text = info.preference
+ }
else if type == .avatar{
valueIcon.kf.setImage(with:CacheManager.shared.user.info.avatar.yc.asUrl )
}
let v = CustomPicker3(title: "日期".l10n)
// v.selectedIndex = 50
v.show()
- v.didSelected = {[weak self] (date) in
+ v.didSelected = {[weak self] (value) in
guard let self = self else { return }
-
+ CacheManager.shared.user.info.birthday = value.format(.short)
+// CacheManager.shared.user.info.birthday = "\(Int(value.timeIntervalSince1970))"
+
+ var params:[String:Any] = [:]
+ params["birthday"] = CacheManager.shared.user.info.birthday
+ uploadUserData(params)
}
}
func heightAction(){
v.show()
v.didSelected = {[weak self] (index,value) in
guard let self = self else { return }
-
+ CacheManager.shared.user.info.tall = String(value.prefix(value.count - 2))
+ var params:[String:Any] = [:]
+ params["tall"] = CacheManager.shared.user.info.tall
+ uploadUserData(params)
}
}
func weightAction(){
v.show()
v.didSelected = {[weak self] (index,value) in
guard let self = self else { return }
-
+ CacheManager.shared.user.info.weight = String(value.prefix(value.count - 2))
+ var params:[String:Any] = [:]
+ params["weight"] = CacheManager.shared.user.info.weight
+ uploadUserData(params)
}
}
func hobiesAction(){
v.show()
v.didSelected = {[weak self] (index,value) in
guard let self = self else { return }
-
+ CacheManager.shared.user.info.preference = value
+ var params:[String:Any] = [:]
+ params["preference"] = CacheManager.shared.user.info.preference
+ uploadUserData(params)
}
}
func genderAction(){
}
}
func refreshUI(){
- CacheManager.shared.user.tokenIsValid(){ [weak self] success in
+ CacheManager.shared.user.getUserInfo{ [weak self] success in
self?.tableView.reloadData()
}
LoginVM.fetchCountryList {[weak self] result in
--- /dev/null
+//
+// AddGroupHeader.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+class AddGroupHeader: BaseView {
+ let icon = UIImageView()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ addSubviews([icon,titleLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(10)
+ v.text = "设置团队头像".l10n
+ }
+
+ icon.do { v in
+ v.image = UIImage(named: "group_avatar")
+ yc.setCornerRadius(12)
+
+ }
+ }
+
+ override func setupLayout() {
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(90)
+ make.centerX.equalToSuperview()
+ make.top.equalToSuperview()
+ }
+ titleLabel.snp.makeConstraints { make in
+ make.centerX.equalToSuperview()
+ make.top.equalTo(icon.snp.bottom).offset(6)
+ }
+
+ }
+}
--- /dev/null
+//
+// CreateGroupVC.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/5.
+//
+
+import UIKit
+
+class CreateGroupVC: BaseVC{
+ let headerView = AddGroupHeader()
+ let nameView = SportInputItem()
+ let typeView = SportSelectItem()
+ let desView = SportInputItem()
+ let lightView = SportSelectItem()
+ let verifyView = SportSwitchItem()
+ let okBtn = CustomButton()
+ var sportType:SportType = .walk
+
+ override func setupViews() {
+ navBar.do { v in
+ v.title = "创建团队".l10n
+ }
+ view.addSubviews([headerView,nameView,typeView,desView,lightView,verifyView,okBtn])
+ nameView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "团队名称".l10n
+ v.textField.text = "111"
+ v.textField.attributedPlaceholder = NSAttributedString(string: "给团队起个名字".l10n, attributes: [NSAttributedString.Key.foregroundColor: UIColor.color(.placeholder)])
+
+ }
+ typeView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "团队类型".l10n
+ v.detailLabel.text = sportType.name
+ v.yc.addTap(target: self, action: #selector(typeAction))
+ }
+ desView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "简介".l10n
+ v.textField.attributedPlaceholder = NSAttributedString(string: "描述一下您的团".l10n, attributes: [NSAttributedString.Key.foregroundColor: UIColor.color(.placeholder)])
+ }
+ lightView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "灯带设置".l10n
+ v.yc.addTap(target: self, action: #selector(lightAction))
+
+ }
+ verifyView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "加入验证".l10n
+ v.detailLabel.text = "开启后,成员需要申请才能加入".l10n
+ }
+ okBtn.set(title: "完成创建".l10n,style: .theme1, target: self, action: #selector(okAction))
+ }
+ override func setupLayout() {
+ headerView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview()
+ make.top.equalToSuperview().inset(kNavBtm + 20)
+ make.height.equalTo(120)
+ }
+ nameView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(headerView.snp.bottom).offset(10)
+ make.height.equalTo(51)
+ }
+ typeView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(nameView.snp.bottom).offset(10)
+ make.height.equalTo(51)
+ }
+ desView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(typeView.snp.bottom).offset(10)
+ make.height.equalTo(65)
+ }
+ lightView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(desView.snp.bottom).offset(10)
+ make.height.equalTo(51)
+ }
+ verifyView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(lightView.snp.bottom).offset(10)
+ make.height.equalTo(65)
+ }
+ okBtn.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(80)
+ make.left.right.equalToSuperview().inset(51)
+ make.height.equalTo(46)
+ }
+ }
+ @objc func typeAction(){
+ let vc = GroupTypeVC()
+ vc.didSelected = {[weak self] value in
+ self?.sportType = value
+ self?.typeView.detailLabel.text = value.name
+ }
+ App.shared.goToPage(vc)
+ }
+ @objc func lightAction(){
+ App.shared.goToPage(LightSetVC())
+ }
+ @objc func okAction(){
+ if nameView.isEmpty {
+ YLprogressHUD.showAutoHiden("团队名称不能为空".l10n)
+ return
+ }
+
+ YLprogressHUD.showLoading()
+ var params:[String:Any] = [:]
+ // 团队名称,必须
+ params["name"] = nameView.value
+ // 头像
+// params["icon"] = ""
+ // 运动类型:running | cycling | walking,必须
+ params["type"] = sportType.rawValue
+ // 团队简介,非必须
+// params["introduction"] = ""
+ // 1加入审核,0不需要审核,非必须,默认0
+ params["joinReview"] = verifyView.iSwitch.isOn ? "1":"0"
+ let api = CommomApi.createSportGroup(param: params)
+ HttpClient.request(api){ (model:ResponseBaseModel, res) in
+
+ if model.isSuccess{
+ YLprogressHUD.hidden()
+ }
+ else{
+ YLprogressHUD.showAutoHiden("请求失败".l10n)
+ }
+ }
+ }
+}
+
--- /dev/null
+//
+// SportInputItem.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+class SportInputItem: BaseView,UITextFieldDelegate {
+ let valueLabel = UILabel()
+ let textField = UITextField()
+ let titleLabel = UILabel()
+ var maxLength = 10
+
+ var isEmpty:Bool{
+ if let text = textField.text,text.isNotEmpty {
+ return false
+ }
+ return true
+ }
+ var value:String{
+ return textField.text ?? ""
+ }
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([valueLabel,titleLabel,textField])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ }
+ textField.do { v in
+ v.textColor = .color(.first)
+ v.keyboardType = .default
+ v.returnKeyType = .done
+ v.textAlignment = .left
+ v.addTarget(self, action: #selector(textFieldValueChange), for: .valueChanged)
+// v.backgroundColor = .red
+ v.delegate = self
+ }
+ valueLabel.do { v in
+ v.textColor = .color(.placeholder)
+ v.font = .regular(10)
+ v.textAlignment = .right
+ v.text = "0/\(maxLength)"
+ }
+ backgroundColor = .white
+ }
+
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ textField.snp.makeConstraints { make in
+ make.left.equalTo(titleLabel.snp.right).offset(10).priority(.high)
+ make.centerY.height.equalToSuperview()
+ make.right.equalToSuperview().inset(50).priority(.low)
+ }
+ valueLabel.snp.makeConstraints { make in
+ make.width.equalTo(38)
+ make.height.equalToSuperview()
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
+ }
+ @objc func textFieldValueChange(){
+ valueLabel.text = "\(textField.text?.count ?? 0)/\(maxLength)"
+ }
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+ textField.resignFirstResponder()
+ return false
+ }
+}
+
+class SportTextViewItem: BaseView,UITextViewDelegate {
+ let valueLabel = UILabel()
+ let textView = UITextView()
+ let titleLabel = UILabel()
+ var maxLength = 10
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([valueLabel,titleLabel,textView])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ v.text = "简介".l10n
+ }
+ textView.do { v in
+ v.textColor = .color(.first)
+ v.keyboardType = .default
+ v.returnKeyType = .done
+ v.textAlignment = .left
+ v.delegate = self
+ }
+ valueLabel.do { v in
+ v.textColor = .color(.placeholder)
+ v.font = .regular(10)
+ v.textAlignment = .right
+ v.text = "0/\(maxLength)"
+ }
+ backgroundColor = .white
+ }
+
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ textView.snp.makeConstraints { make in
+ make.left.equalTo(titleLabel.snp.right).offset(10).priority(.high)
+ make.centerY.height.equalToSuperview()
+ make.right.equalToSuperview().inset(50).priority(.low)
+ }
+ valueLabel.snp.makeConstraints { make in
+ make.width.equalTo(38)
+ make.height.equalToSuperview()
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
+ }
+
+ func textViewDidChange(_ textView: UITextView) {
+ valueLabel.text = "\(textView.text?.count ?? 0)/\(maxLength)"
+ }
+
+ func textView(_ textView: UITextView, shouldChangeTextInRanges ranges: [NSValue], replacementText text: String) -> Bool {
+ textView.resignFirstResponder()
+
+ return false
+ }
+}
--- /dev/null
+//
+// SportItem.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+class SportSelectItem: BaseView {
+ let icon = UIImageView()
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([icon,titleLabel,detailLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(12)
+ }
+ icon.do { v in
+ v.image = UIImage(named: "arrow_2")
+ }
+ backgroundColor = .white
+ }
+
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(27)
+ }
+ icon.snp.makeConstraints { make in
+ make.width.equalTo(7)
+ make.height.equalTo(13)
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
+ }
+}
--- /dev/null
+//
+// SportSwitchItem.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+class SportSwitchItem: BaseTableViewCell {
+ let titleLabel = UILabel()
+ let detailLabel = UILabel()
+ let iSwitch = UISwitch()
+
+
+ override func setupViews() {
+ addSubviews([titleLabel,detailLabel,iSwitch])
+
+ 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
+ }
+ iSwitch.do { v in
+ v.addTarget(self, action: #selector(swicthAction), for: .valueChanged)
+ }
+ }
+
+ override func setupLayout() {
+ 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.right.equalToSuperview().inset(15)
+ m.centerY.equalToSuperview()
+ }
+ }
+
+
+ @objc func swicthAction(){
+ }
+}
--- /dev/null
+//
+// MyGroupCell.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+ class MyGroupCell: BaseTableViewCell {
+ let bgView = UIView()
+ let icon = UIImageView()
+ let nameLabel = UILabel()
+ let contentLabel = UILabel()
+
+ var model:MyGroupModel!{
+ didSet{
+ if model.icon.isEmpty{
+ icon.image = UIImage(named: "group_avatar")
+ }
+ else{
+ icon.kf.setImage(with: model.icon.yc.asUrl)
+ }
+ nameLabel.text = model.name
+ contentLabel.text = model.type.name + ".\(model.userCount)" + "人已加入".l10n
+ }
+ }
+
+
+ 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([icon,nameLabel,contentLabel])
+
+ backgroundColor = .color(.bgColor)
+ contentView.backgroundColor = .clear
+ selectionStyle = .none
+ bgView.do { v in
+ v.backgroundColor = .color(.cellBg)
+ v.yc.setCornerRadius(8)
+ }
+ nameLabel.do { (v) in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ v.textAlignment = .left
+ v.lineBreakMode = .byTruncatingTail
+ }
+ contentLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(11)
+ v.textAlignment = .left
+ v.lineBreakMode = .byTruncatingTail
+ }
+
+ icon.do { v in
+ v.yc.setCornerRadius(8)
+ }
+ }
+
+ override func setupLayout() {
+ bgView.snp.makeConstraints { (m) in
+ m.left.right.equalToSuperview().inset(18)
+ m.top.equalToSuperview().inset(6)
+ m.bottom.equalToSuperview()
+ }
+
+ icon.snp.makeConstraints { (m) in
+ m.size.equalTo(36)
+ m.left.equalToSuperview().inset(15)
+ m.top.equalToSuperview().inset(15)
+ }
+ nameLabel.snp.makeConstraints { (m) in
+ m.top.equalToSuperview().inset(16)
+ m.left.equalToSuperview().offset(60)
+ m.right.lessThanOrEqualToSuperview().inset(16)
+ }
+ contentLabel.snp.makeConstraints { (m) in
+ m.bottom.equalToSuperview().inset(16)
+ m.left.equalToSuperview().offset(60)
+ m.right.lessThanOrEqualToSuperview().inset(16)
+ }
+
+ }
+
+
+}
--- /dev/null
+//
+// Untitled.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+import HandyJSON
+
+class MyGroupModelRoot:ResponseBaseModel {
+ var data = [MyGroupModel]()
+}
+
+class MyGroupModel:HandyJSON {
+ var id = "" // 团队ID
+ var userId = ""// 用户ID,创建者的ID
+ var creatorNickname = "" // 创建者昵称
+ var creatorAvatar = "" // https://example.com/avatar.jpg", // 创建者头像
+ var icon = "" // https://example.com/icon.jpg", // 图标
+ var state = "" // 状态:1正常,0解散
+ var name = "" // 团队名称
+ var type:SportType = SportType.walk // 运动类型:running | cycling | walking
+ var introduction = "" // 团队简介
+ var joinReview = ""// 1加入审核,0不需要审核
+ var userCount = 0 //加入人数
+ var totalDistance = "" // 总距离,单位米
+ var totalTime = "" // 总运动时长,单位秒
+ var createTime = "" // 创建时间
+ var updateTime = ""// 更新时间
+ required public init() { }
+}
--- /dev/null
+//
+// MyGroupVC.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+import JXSegmentedView
+
+
+enum MyGroupType{
+ case create
+ case add
+
+ var name:String{
+ switch self {
+ case .create:
+ return "我管理的"
+ case .add:
+ return "我加入的"
+ }
+ }
+ var value:String{
+ switch self {
+ case .create:
+ return "1"
+ case .add:
+ return "0"
+ }
+ }
+ static var all:[MyGroupType] = [.create,.add]
+}
+
+class MyGroupVC: BaseVC {
+ private let segmentedDataSource = JXSegmentedTitleDataSource()
+ private let segmentedView = JXSegmentedView()
+ private lazy var listContainerView: JXSegmentedListContainerView! = {
+ let view = JXSegmentedListContainerView(dataSource: self, type: .scrollView)
+ return view
+ }()
+
+ var list:[MyGroupType] = MyGroupType.all
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ // AudioPlayView.shared.show()
+ self.view.addSubview(AudioPlayView.shared)
+ MapManager.shared.setupSdk()
+ }
+
+ override func setupLayout(){
+
+ segmentedView.snp.makeConstraints { (m) in
+ m.left.right.equalToSuperview()
+ m.height.equalTo(44.fitR)
+ m.top.equalToSuperview().inset(kNavBtm)
+ }
+ listContainerView.snp.makeConstraints { (m) in
+ m.width.left.equalToSuperview()
+ m.top.equalTo(segmentedView.snp.bottom)
+ m.bottom.equalToSuperview()
+ }
+ }
+ override func setupViews(){
+ view.addSubview(segmentedView)
+ view.addSubview(listContainerView)
+
+ view.backgroundColor = .color(.bgColor)
+ segmentedView.do { (v) in
+ segmentedDataSource.titleNormalColor = .color(.secondary)
+ segmentedDataSource.titleSelectedColor = .color(.first)
+ segmentedDataSource.titleNormalFont = .regular(14)
+ segmentedDataSource.titleSelectedFont = .bold(16)
+ segmentedDataSource.isTitleZoomEnabled = true
+ // segmentedDataSource.titleSelectedZoomScale = 1
+ segmentedDataSource.isTitleStrokeWidthEnabled = true
+ segmentedDataSource.isItemSpacingAverageEnabled = true
+ segmentedDataSource.isTitleColorGradientEnabled = true
+ segmentedDataSource.titles = list.map{"\($0.name)"}
+ segmentedView.backgroundColor = .clear
+
+ //配置指示器
+ let indicator = JXSegmentedIndicatorLineView()
+ indicator.indicatorWidth = 20
+ indicator.indicatorHeight = 4
+ indicator.verticalOffset = 6
+ indicator.indicatorColor = .color(.theme)
+ segmentedView.indicators = [indicator]
+
+ v.dataSource = segmentedDataSource
+ v.listContainer = listContainerView
+ }
+ }
+}
+
+extension MyGroupVC: JXSegmentedListContainerViewListDelegate {
+ func listView() -> UIView {
+ return view
+ }
+}
+
+extension MyGroupVC: JXSegmentedListContainerViewDataSource {
+ func numberOfLists(in listContainerView: JXSegmentedListContainerView) -> Int {
+ if let titleDataSource = segmentedView.dataSource as? JXSegmentedBaseDataSource {
+ return titleDataSource.dataSource.count
+ }
+ return 0
+ }
+
+ func listContainerView(_ listContainerView: JXSegmentedListContainerView, initListAt index: Int) -> JXSegmentedListContainerViewListDelegate {
+ let type = list[index]
+ return MyGroupView(selectType: type)
+
+ }
+}
--- /dev/null
+//
+// GroupListView.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+import UIKit
+import JXSegmentedView
+import MJRefresh
+
+
+class MyGroupView: BaseView,UITableViewDelegate,UITableViewDataSource {
+ let tableView = UITableView(frame: .zero, style: .plain)
+ var list = [MyGroupModel]()
+ var type = MyGroupType.add
+
+ init(selectType type:MyGroupType){
+ super.init(frame: .zero)
+ self.type = type
+ tableView.mj_header?.beginRefreshing()
+ }
+
+ override func setupViews() {
+ addSubview(tableView)
+ tableView.do { v in
+ v.backgroundColor = .color(.bgColor)
+ v.delegate = self
+ v.dataSource = self
+ v.rowHeight = 74
+ v.separatorStyle = .none
+ v.register(MyGroupCell.self, forCellReuseIdentifier: MyGroupCell.reuseID)
+ v.mj_header = MJRefreshNormalHeader(refreshingTarget: self, refreshingAction: #selector(refreshAction))
+ }
+ }
+
+ override func setupLayout() {
+ tableView.snp.makeConstraints { (m) in
+ m.top.equalToSuperview().inset(10)
+ m.left.right.bottom.equalToSuperview()
+ }
+ }
+
+ @objc func refreshAction(){
+ var params:[String:Any] = [:]
+ params["type"] = type.value
+
+ let api = CommomApi.getSportGroupList(param: params)
+ HttpClient.request(api) {[weak self] (model:MyGroupModelRoot,res) in
+ guard let self = self else {return}
+ if model.isSuccess{
+ list = model.data
+ }
+ tableView.reloadData()
+ tableView.mj_header?.endRefreshing()
+ }
+
+ }
+
+
+ @MainActor required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return list.count
+ }
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = MyGroupCell.cell(withTableView: tableView, indexPath: indexPath)
+ cell.model = list[indexPath.row]
+ return cell
+ }
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ }
+
+}
+
+extension MyGroupView: JXSegmentedListContainerViewListDelegate {
+ func listView() -> UIView {
+ return self
+ }
+}
--- /dev/null
+import UIKit
+import HandyJSON
+
+enum GroupRoleType:String,HandyJSONEnum{
+ case none = "none"
+ case pfs = "pfs"
+ case lpz = "lpz"
+ case gpz = "gpz"
+ case ccs = "ccs"
+ case psy = "psy"
+ case bjy = "bjy"
+ case qns = "qns"
+ case lqz = "lqz"
+ case gqz = "gqz"
+ case pps = "pps"
+
+
+ var name:String{
+ switch self {
+ case .none:
+ return "无"
+ case .pfs:
+ return "破风手"
+ case .lpz:
+ return "领跑者"
+ case .gpz:
+ return "跟跑者"
+ case .ccs:
+ return "冲刺手"
+ case .psy:
+ return "配速员"
+ case .bjy:
+ return "补给员"
+ case .qns:
+ return "全能手"
+ case .lqz:
+ return "领骑者"
+ case .gqz:
+ return "跟骑者"
+ case .pps:
+ return "爬坡手"
+ }
+ }
+ var color:UIColor{
+ switch self {
+ case .none:
+ return .red
+ case .pfs:
+ return .red
+ case .lpz:
+ return .red
+ case .gpz:
+ return .red
+ case .ccs:
+ return .red
+ case .psy:
+ return .red
+ case .bjy:
+ return .red
+ case .qns:
+ return .red
+ case .lqz:
+ return .red
+ case .gqz:
+ return .red
+ case .pps:
+ return .red
+ }
+ }
+
+ static var all:[GroupRoleType] = [.none,.pfs,.lpz,.gpz,.ccs,.psy,.bjy,.qns]
+}
+
+class GroupRoleVC: BaseVC{
+ let tableView = UITableView(frame: .zero, style: .plain)
+ var list:[GroupRoleType] = GroupRoleType.all
+ var currentType = GroupRoleType.none
+ let btn = CustomButton()
+ var didSelected:((GroupRoleType)->Void)?
+
+ 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.separatorStyle = .none
+ v.contentInset = UIEdgeInsets(top: 10, left: 0, bottom: 0, right: 0)
+ v.register(SelectCell.self, forCellReuseIdentifier: SelectCell.reuseID)
+ }
+ view.addSubviews([tableView,btn])
+
+ btn.set(title: "确定".l10n, target: self, action: #selector(btnAction))
+ }
+ override func setupLayout() {
+ tableView.snp.makeConstraints { make in
+ make.left.right.bottom.equalToSuperview()
+ make.top.equalTo(kNavBtm)
+ }
+ btn.snp.makeConstraints { make in
+ make.width.equalTo(272)
+ make.height.equalTo(46)
+ make.centerX.equalToSuperview()
+ make.bottom.equalToSuperview().inset(82)
+ }
+ }
+ @objc func btnAction(){
+ didSelected?(currentType)
+ self.navigationController?.popViewController(animated: true)
+ }
+}
+
+extension GroupRoleVC:UITableViewDelegate,UITableViewDataSource {
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return list.count
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = SelectCell.cell(withTableView: tableView, indexPath: indexPath)
+ cell.titleLabel.text = list[indexPath.row].name
+ 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: 8, height: 8))
+ }
+ else if indexPath.row == list.count - 1{
+ cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.bottomLeft,.bottomRight], cornerRadii: CGSize(width: 8, height: 8))
+ }
+ else{
+ cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.allCorners], cornerRadii: CGSize(width: 0, height: 0))
+ }
+ cell.selectedIcon.isHidden = list[indexPath.row] != currentType
+ return cell
+ }
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ let data = list[indexPath.row]
+ currentType = data
+ tableView.reloadData()
+ }
+}
--- /dev/null
+//
+// GroupTypeVC.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+import UIKit
+
+class GroupTypeVC: BaseVC{
+ let tableView = UITableView(frame: .zero, style: .plain)
+ var list:[SportType] = SportType.all
+ var currentType = SportType.walk
+ let btn = CustomButton()
+ var didSelected:((SportType)->Void)?
+
+ 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.separatorStyle = .none
+ v.contentInset = UIEdgeInsets(top: 10, left: 0, bottom: 0, right: 0)
+ v.register(SelectCell.self, forCellReuseIdentifier: SelectCell.reuseID)
+ }
+ view.addSubviews([tableView,btn])
+
+ btn.set(title: "确定".l10n, target: self, action: #selector(btnAction))
+ }
+ override func setupLayout() {
+ tableView.snp.makeConstraints { make in
+ make.left.right.bottom.equalToSuperview()
+ make.top.equalTo(kNavBtm)
+ }
+ btn.snp.makeConstraints { make in
+ make.width.equalTo(272)
+ make.height.equalTo(46)
+ make.centerX.equalToSuperview()
+ make.bottom.equalToSuperview().inset(82)
+ }
+ }
+ @objc func btnAction(){
+ didSelected?(currentType)
+ self.navigationController?.popViewController(animated: true)
+ }
+}
+
+extension GroupTypeVC:UITableViewDelegate,UITableViewDataSource {
+ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ return list.count
+ }
+
+ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let cell = SelectCell.cell(withTableView: tableView, indexPath: indexPath)
+ cell.titleLabel.text = list[indexPath.row].name
+ 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: 8, height: 8))
+ }
+ else if indexPath.row == list.count - 1{
+ cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.bottomLeft,.bottomRight], cornerRadii: CGSize(width: 8, height: 8))
+ }
+ else{
+ cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.allCorners], cornerRadii: CGSize(width: 0, height: 0))
+ }
+ cell.selectedIcon.isHidden = list[indexPath.row] != currentType
+ return cell
+ }
+ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ let data = list[indexPath.row]
+ currentType = data
+ tableView.reloadData()
+ }
+}
--- /dev/null
+//
+// AddGrpupVC.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/6.
+//
+
+import UIKit
+
+class AddGroupVC: BaseVC{
+ let nameView = SportInputItem()
+ let typeView = SportSelectItem()
+ let desView = SportInputItem()
+ let okBtn = CustomButton()
+ var sportType:GroupRoleType = .none
+
+ override func setupViews() {
+ navBar.do { v in
+ v.title = "加入团队".l10n
+ }
+ view.addSubviews([nameView,typeView,desView,okBtn])
+ nameView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "团队号".l10n
+ v.textField.text = "2019706199229804545"
+ v.textField.attributedPlaceholder = NSAttributedString(string: "请输入团队号".l10n, attributes: [NSAttributedString.Key.foregroundColor: UIColor.color(.placeholder)])
+
+ }
+ typeView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "团队角色".l10n
+ v.detailLabel.text = sportType.name
+ v.yc.addTap(target: self, action: #selector(typeAction))
+ }
+ desView.do { v in
+ v.yc.setCornerRadius(12)
+ v.titleLabel.text = "打招呼内容".l10n
+ v.textField.attributedPlaceholder = NSAttributedString(string: "描述一下您的团".l10n, attributes: [NSAttributedString.Key.foregroundColor: UIColor.color(.placeholder)])
+ }
+ okBtn.set(title: "加入".l10n,style: .theme1, target: self, action: #selector(okAction))
+ }
+ override func setupLayout() {
+ nameView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalToSuperview().inset(kNavBtm + 20)
+ make.height.equalTo(51)
+ }
+ typeView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(nameView.snp.bottom).offset(10)
+ make.height.equalTo(51)
+ }
+ desView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(18)
+ make.top.equalTo(typeView.snp.bottom).offset(10)
+ make.height.equalTo(65)
+ }
+ okBtn.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(80)
+ make.left.right.equalToSuperview().inset(51)
+ make.height.equalTo(46)
+ }
+ }
+ @objc func typeAction(){
+ let vc = GroupRoleVC()
+ vc.didSelected = {[weak self] value in
+ self?.sportType = value
+ self?.typeView.detailLabel.text = value.name
+ }
+ App.shared.goToPage(vc)
+ }
+ @objc func lightAction(){
+ App.shared.goToPage(LightSetVC())
+ }
+ @objc func okAction(){
+ if nameView.isEmpty {
+ YLprogressHUD.showAutoHiden("团队名称不能为空".l10n)
+ return
+ }
+
+ YLprogressHUD.showLoading()
+ var params:[String:Any] = [:]
+ params["id"] = nameView.value
+ params["requestText"] = desView.value
+
+ let api = CommomApi.applyJoinGroup(param: params)
+ HttpClient.request(api){ (model:ResponseBaseModel, res) in
+
+ if model.isSuccess{
+ YLprogressHUD.hidden()
+ }
+ else{
+ YLprogressHUD.showAutoHiden("请求失败".l10n)
+ }
+ }
+ }
+}
+
}
@objc func skipAction(){
timer.invalidate()
- App.shared.goToPage(BaseVC())
+ App.shared.goToPage(SportingVC())
removeFromSuperview()
}
}
App.shared.goToPage(SportTargetVC())
}
@objc func goAction(){
- if true {
+ if false {
CustomAlert.showWith(title: "完善数据".l10n, messgage: "完善你的身体档案,让运动数据更准确。".l10n,ok: "前往".l10n) {
} okCallback: {
extension SportRootView{
class DataView: BaseView {
-
+ let header = headItem()
+ let line = UIView()
+ let lastView = ItemView()
override func setupViews() {
backgroundColor = .color(.cellBg)
+ addSubviews([header,lastView,line])
+ line.backgroundColor = .color(.separateLine)
}
override func setupLayout() {
+ header.snp.makeConstraints { make in
+ make.left.right.top.equalToSuperview()
+ make.height.equalTo(51)
+ }
+ lastView.snp.makeConstraints { make in
+ make.left.right.bottom.equalToSuperview()
+ make.height.equalTo(72)
+ }
+ line.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(14)
+ make.height.equalTo(1)
+ make.bottom.equalTo(header)
+ }
+ }
+ class headItem: BaseView {
+ let icon = UIImageView()
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([icon,titleLabel,detailLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ v.text = "运动数据".l10n
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(12)
+ v.text = "全部".l10n
+ }
+ icon.do { v in
+ v.image = UIImage(named: "arrow_2")
+ }
+ backgroundColor = .white
+ }
+
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(27)
+ }
+ icon.snp.makeConstraints { make in
+ make.width.equalTo(7)
+ make.height.equalTo(13)
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
+ }
+ }
+
+ class ItemView: BaseView {
+ let icon = UIImageView()
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([icon,titleLabel,detailLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ v.text = "户外跑步 6.21公里"
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(10)
+ v.text = "30分26秒"
+ }
+ icon.do { v in
+ v.image = UIImage(named: "add_2")
+ }
+ backgroundColor = .white
+ }
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(16)
+ make.left.equalToSuperview().inset(64)
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(16)
+ make.left.equalTo(titleLabel)
+ }
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(40)
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ }
}
}
}
extension SportRootView{
class GroupView: BaseView {
+ let creatGroup = ItemView()
+ let addGroup = ItemView()
+ let myGroup = ItemView()
+ override func setupViews() {
+ addSubviews([creatGroup,addGroup,myGroup])
+ creatGroup.do { v in
+ v.titleLabel.text = "创建团队".l10n
+ v.detailLabel.text = "创建我的团队".l10n
+ v.yc.addTap(target: self, action: #selector(creatAction))
+ }
+ addGroup.do { v in
+ v.titleLabel.text = "加入团队".l10n
+ v.detailLabel.text = "加入已创建的团队".l10n
+ v.yc.addTap(target: self, action: #selector(joinAction))
+
+ }
+ myGroup.do { v in
+ v.titleLabel.text = "我的团队".l10n
+ v.detailLabel.text = "我创建和已加入的团队".l10n
+ v.icon.isHidden = true
+ v.yc.addTap(target: self, action: #selector(myAction))
+ }
+ }
+
+ override func setupLayout() {
+ creatGroup.snp.makeConstraints { make in
+ make.left.top.right.equalToSuperview()
+ make.height.equalTo(65)
+ }
+ addGroup.snp.makeConstraints { make in
+ make.left.bottom.equalToSuperview()
+ make.height.equalTo(65)
+ make.width.equalTo((kScreenWid - 36 - 10)/2)
+ }
+ myGroup.snp.makeConstraints { make in
+ make.right.bottom.equalToSuperview()
+ make.height.equalTo(addGroup)
+ make.left.equalTo(addGroup.snp.right).offset(10)
+ }
+ }
+ @objc func creatAction(){
+ App.shared.goToPage(CreateGroupVC())
+ }
+ @objc func joinAction(){
+ App.shared.goToPage(AddGroupVC())
+ }
+ @objc func myAction(){
+ App.shared.goToPage(MyGroupVC())
+ }
+ }
+ class ItemView: BaseView {
+ let icon = UIImageView()
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
override func setupViews() {
- backgroundColor = .color(.cellBg)
+ backgroundColor = .color(.cellBg)
+ yc.setCornerRadius(12)
+ addSubviews([icon,titleLabel,detailLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(10)
+ }
+ icon.do { v in
+ v.image = UIImage(named: "add_2")
+ }
+ backgroundColor = .white
}
override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(16)
+ make.left.equalToSuperview().inset(14)
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(16)
+ make.left.equalTo(titleLabel)
+ }
+ icon.snp.makeConstraints { make in
+ make.size.equalTo(36)
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
}
}
}
extension SportRootView{
class PlanView: BaseView {
-
+ let icon = ItemView()
override func setupViews() {
- backgroundColor = .color(.cellBg)
+ addSubviews([icon])
+ icon.do { v in
+ v.titleLabel.text = "智能运动计划建议".l10n
+ v.detailLabel.text = "AI规划个人定制运动计划".l10n
+ }
}
override func setupLayout() {
-
+ icon.snp.makeConstraints { make in
+ make.edges.equalToSuperview()
+ }
}
}
}
extension SportRootView{
class RouteView: BaseView {
-
+ let header = headItem()
+ let line = UIView()
+ let routeView1 = UIView()
+ let routeView2 = UIView()
+
override func setupViews() {
backgroundColor = .color(.cellBg)
+ addSubviews([header,routeView1,routeView2,line])
+ line.backgroundColor = .color(.separateLine)
+
+ routeView1.do { v in
+ v.backgroundColor = .lightGray
+ v.yc.setCornerRadius(12)
+ }
+ routeView2.do { v in
+ v.backgroundColor = .lightGray
+ v.yc.setCornerRadius(12)
+ }
}
override func setupLayout() {
+ header.snp.makeConstraints { make in
+ make.left.right.top.equalToSuperview()
+ make.height.equalTo(51)
+ }
+ routeView1.snp.makeConstraints { make in
+ make.left.bottom.equalToSuperview().inset(14)
+ make.height.equalTo(96)
+ make.width.equalTo(((kScreenWid - 64 - 10)/2))
+ }
+ routeView2.snp.makeConstraints { make in
+ make.right.bottom.equalToSuperview().inset(14)
+ make.height.equalTo(96)
+ make.width.equalTo(((kScreenWid - 64 - 10)/2))
+ }
+ line.snp.makeConstraints { make in
+ make.left.right.equalToSuperview().inset(14)
+ make.height.equalTo(1)
+ make.bottom.equalTo(header)
+ }
+ }
+ class headItem: BaseView {
+ let icon = UIImageView()
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ yc.setCornerRadius(12)
+ addSubviews([icon,titleLabel,detailLabel])
+
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .medium(14)
+ v.text = "路线探索".l10n
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(12)
+ v.text = "全部".l10n
+ }
+ icon.do { v in
+ v.image = UIImage(named: "arrow_2")
+ }
+ backgroundColor = .white
+ }
+ override func setupLayout() {
+
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.left.equalToSuperview().inset(14)
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(27)
+ }
+ icon.snp.makeConstraints { make in
+ make.width.equalTo(7)
+ make.height.equalTo(13)
+ make.centerY.equalToSuperview()
+ make.right.equalToSuperview().inset(12)
+ }
+ }
}
+
+
}
}
//
// Created by liangshi on 2026/1/20.
//
+import HandyJSON
-
-enum SportType{
- case run
- case ride
- case walk
+enum SportType:String,HandyJSONEnum{
+ case run = "running"
+ case ride = "cycling"
+ case walk = "walking"
var name:String{
switch self {
return "sport_walk"
}
}
+
static var all:[SportType] = [.run,.ride,.walk]
}
var type:SportType = .run{
didSet{
titleLabel.text = type.name
+ icon.image = UIImage(named: type.icon)
}
}
override func setupViews() {
addSubviews([titleLabel,icon])
icon.do { v in
- v.image = UIImage(named: type.icon)
+
}
titleLabel.do { v in
v.textColor = .color(.first)
--- /dev/null
+////
+//// Untitled.swift
+//// ShenYin
+////
+//// Created by liangshi on 2026/2/5.
+////
+//
+import UIKit
+
+extension SportDetailVC{
+ class SportDetailBoard: BaseView {
+ let topIcon = UIImageView()
+ let header = headerItem()
+ let distanceItem = LabelItem()
+ let durationItem = LabelItem()
+ let speedItem = LabelItem()
+ let calorieItem = LabelItem()
+ let stepItem = LabelItem()
+ let okBtn = UIButton(type: .custom)
+
+ override func setupViews() {
+ backgroundColor = .white
+ addSubviews([topIcon,header,distanceItem,durationItem,speedItem,calorieItem,stepItem,okBtn])
+ topIcon.do { v in
+ v.backgroundColor = .color(.secondary)
+ v.yc.setCornerRadius(2)
+ }
+ distanceItem.do { v in
+ v.titleLabel.text = "0"
+ v.detailLabel.text = "总距离".l10n
+ }
+ durationItem.do { v in
+ v.titleLabel.text = "00:00:00"
+ v.detailLabel.text = "总时长".l10n
+ }
+ speedItem.do { v in
+ v.titleLabel.text = "8'26\""
+ v.detailLabel.text = "配速".l10n
+ }
+ calorieItem.do { v in
+ v.titleLabel.text = "300"
+ v.detailLabel.text = "卡路里".l10n
+ }
+ stepItem.do { v in
+ v.titleLabel.text = "1200"
+ v.detailLabel.text = "步数".l10n
+ }
+ okBtn.do { v in
+ v.setImage(UIImage(named: "btn_pause"), for: .normal)
+ v.addTarget(self, action: #selector(okAction), for: .touchUpInside)
+ }
+ }
+
+ override func setupLayout() {
+ topIcon.snp.makeConstraints { make in
+ make.width.equalTo(50)
+ make.height.equalTo(4)
+ make.top.equalToSuperview().inset(6)
+ make.centerX.equalToSuperview()
+ }
+ header.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(28)
+ make.left.right.equalToSuperview()
+ make.height.equalTo(25)
+ }
+ distanceItem.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(18)
+ make.top.equalToSuperview().inset(100)
+ make.height.equalTo(50)
+ }
+ durationItem.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(18)
+ make.top.equalToSuperview().inset(180)
+ make.height.equalTo(50)
+ }
+ speedItem.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(kScreenWid/2 + 18)
+ make.top.equalTo(durationItem.snp.top)
+ make.height.equalTo(50)
+ }
+ calorieItem.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(18)
+ make.top.equalToSuperview().inset(250)
+ make.height.equalTo(50)
+ }
+ stepItem.snp.makeConstraints { make in
+ make.left.equalToSuperview().inset(kScreenWid/2 + 18)
+ make.top.equalTo(calorieItem.snp.top)
+ make.height.equalTo(50)
+ }
+ okBtn.snp.makeConstraints { make in
+ make.centerX.equalToSuperview()
+ make.bottom.equalToSuperview().inset(50)
+ make.size.equalTo(90)
+ }
+ }
+
+ @objc func okAction(){
+ App.shared.goToPage(SportDetailVC())
+ }
+
+
+ class headerItem: BaseView {
+ let deviceLabel = UILabel()
+ let deviceView = UIView()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ addSubviews([titleLabel,deviceView])
+ deviceView.addSubviews([deviceLabel])
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .bold(16)
+ v.textAlignment = .left
+ v.text = "户外跑步"
+ }
+ deviceView.do { v in
+ v.backgroundColor = .rgb(0xF7F7F7 )
+ v.yc.setCornerRadius(13)
+ }
+ deviceLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(10)
+ v.textAlignment = .center
+ v.text = "Deep Lite2 Ultra"
+ }
+ }
+
+ override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview().inset(0)
+ make.left.equalToSuperview().inset(18)
+ }
+ deviceView.snp.makeConstraints { make in
+ make.width.equalTo(120)
+ make.height.equalTo(26)
+ make.left.equalToSuperview().inset(94)
+ make.centerY.equalToSuperview()
+ }
+ deviceLabel.snp.makeConstraints { make in
+ make.centerY.right.equalToSuperview()
+ make.left.equalToSuperview().inset(18)
+ }
+ }
+ }
+
+
+ class LabelItem: BaseView {
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ addSubviews([titleLabel,detailLabel])
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .bold(24)
+ v.textAlignment = .left
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(12)
+ v.textAlignment = .left
+ }
+ }
+
+ override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(0)
+ make.left.right.equalToSuperview()
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(0)
+ make.left.right.equalToSuperview()
+ }
+ }
+ }
+ }
+
+
+
+}
--- /dev/null
+//
+// SportDetailVC.swift
+// ShenYin
+//
+// Created by liangshi on 2026/2/5.
+//
+
+import MAMapKit
+
+class SportDetailVC: BaseVC {
+ var mapView:MAMapView!
+ let simpleView = UIView()
+ let detailView = SportDetailBoard()
+
+ override func setupViews() {
+
+
+
+ mapView = MAMapView(frame: .zero)
+ mapView.delegate = self
+ mapView.showsUserLocation = true
+ mapView.zoomLevel = 16
+ mapView.userTrackingMode = .followWithHeading
+
+ view.addSubviews([mapView,simpleView,detailView])
+ mapView.do { v in
+
+ }
+ simpleView.do { v in
+ v.yc.setCorners(withRoundedRect: CGRect(x: 0, y: 0, width: kScreenWid, height: 100), roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 20, height: 20))
+ v.yc.addTap(target: self, action: #selector(simpleTapAction))
+ }
+ detailView.do { v in
+ v.yc.setCorners(withRoundedRect: CGRect(x: 0, y: 0, width: kScreenWid, height: 460), roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 20, height: 20))
+ v.isHidden = true
+ v.yc.addTap(target: self, action: #selector(detailTapAction))
+ }
+ }
+ override func setupLayout() {
+ simpleView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview()
+ make.bottom.equalToSuperview()
+ make.height.equalTo(100)
+ }
+ detailView.snp.makeConstraints { make in
+ make.left.right.equalToSuperview()
+ make.bottom.equalToSuperview()
+ make.height.equalTo(460)
+ }
+ mapView.snp.makeConstraints { make in
+ make.left.right.top.equalToSuperview()
+ make.bottom.equalTo(simpleView.snp.top).offset(20)
+ }
+ }
+ override func setupData() {
+
+ }
+
+ @objc func simpleTapAction(){
+ simpleView.isHidden = true
+ detailView.isHidden = false
+ showDetail()
+ }
+ @objc func detailTapAction(){
+ simpleView.isHidden = false
+ detailView.isHidden = true
+ showSimple()
+ }
+ func showSimple(){
+ mapView.snp.remakeConstraints { make in
+ make.left.right.top.equalToSuperview()
+ make.bottom.equalTo(simpleView.snp.top).offset(20)
+ }
+ }
+ func showDetail(){
+ mapView.snp.remakeConstraints { make in
+ make.left.right.top.equalToSuperview()
+ make.bottom.equalTo(detailView.snp.top).offset(20)
+ }
+ }
+}
+
+extension SportDetailVC:MAMapViewDelegate{
+ func mapViewRequireLocationAuth(_ locationManager: CLLocationManager!) {
+ // locationManager.requestAlwaysAuthorization()
+ }
+}
extension SportingVC{
class DetailBoard: BaseView {
let topIcon = UIImageView()
+ let header = headerItem()
let distanceItem = LabelItem()
let durationItem = LabelItem()
let speedItem = LabelItem()
let calorieItem = LabelItem()
let stepItem = LabelItem()
+ let okBtn = UIButton(type: .custom)
override func setupViews() {
backgroundColor = .white
- addSubviews([topIcon,distanceItem,durationItem,speedItem,calorieItem,stepItem])
+ addSubviews([topIcon,header,distanceItem,durationItem,speedItem,calorieItem,stepItem,okBtn])
topIcon.do { v in
v.backgroundColor = .color(.secondary)
v.yc.setCornerRadius(2)
v.detailLabel.text = "总时长".l10n
}
speedItem.do { v in
- v.titleLabel.text = "00:00:00"
- v.detailLabel.text = "总时长".l10n
+ v.titleLabel.text = "8'26\""
+ v.detailLabel.text = "配速".l10n
}
calorieItem.do { v in
- v.titleLabel.text = "00:00:00"
- v.detailLabel.text = "总时长".l10n
+ v.titleLabel.text = "300"
+ v.detailLabel.text = "卡路里".l10n
}
stepItem.do { v in
- v.titleLabel.text = "00:00:00"
- v.detailLabel.text = "总时长".l10n
+ v.titleLabel.text = "1200"
+ v.detailLabel.text = "步数".l10n
+ }
+ okBtn.do { v in
+ v.setImage(UIImage(named: "btn_pause"), for: .normal)
+ v.addTarget(self, action: #selector(okAction), for: .touchUpInside)
}
}
make.top.equalToSuperview().inset(6)
make.centerX.equalToSuperview()
}
+ header.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(28)
+ make.left.right.equalToSuperview()
+ make.height.equalTo(25)
+ }
distanceItem.snp.makeConstraints { make in
make.left.equalToSuperview().inset(18)
- make.top.equalToSuperview().inset(27)
+ make.top.equalToSuperview().inset(100)
make.height.equalTo(50)
}
durationItem.snp.makeConstraints { make in
make.top.equalTo(durationItem.snp.top)
make.height.equalTo(50)
}
- distanceItem.snp.makeConstraints { make in
+ calorieItem.snp.makeConstraints { make in
make.left.equalToSuperview().inset(18)
make.top.equalToSuperview().inset(250)
make.height.equalTo(50)
}
stepItem.snp.makeConstraints { make in
make.left.equalToSuperview().inset(kScreenWid/2 + 18)
- make.top.equalTo(distanceItem.snp.top)
+ make.top.equalTo(calorieItem.snp.top)
make.height.equalTo(50)
}
+ okBtn.snp.makeConstraints { make in
+ make.centerX.equalToSuperview()
+ make.bottom.equalToSuperview().inset(50)
+ make.size.equalTo(90)
+ }
}
- @objc func groupAction(){
- App.shared.goToPage(SportSetVC())
+ @objc func okAction(){
+ App.shared.goToPage(SportDetailVC())
}
- }
-
- class LabelItem: BaseView {
- let detailLabel = UILabel()
- let titleLabel = UILabel()
- override func setupViews() {
- addSubviews([titleLabel,detailLabel])
- titleLabel.do { v in
- v.textColor = .color(.first)
- v.font = .bold(24)
- v.textAlignment = .left
- }
- detailLabel.do { v in
- v.textColor = .color(.secondary)
- v.font = .regular(12)
- v.textAlignment = .left
+ class headerItem: BaseView {
+ let deviceLabel = UILabel()
+ let deviceView = UIView()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ addSubviews([titleLabel,deviceView])
+ deviceView.addSubviews([deviceLabel])
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .bold(16)
+ v.textAlignment = .left
+ v.text = "户外跑步"
+ }
+ deviceView.do { v in
+ v.backgroundColor = .rgb(0xF7F7F7 )
+ v.yc.setCornerRadius(13)
+ }
+ deviceLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(10)
+ v.textAlignment = .center
+ v.text = "Deep Lite2 Ultra"
+ }
+ }
+
+ override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.centerY.equalToSuperview().inset(0)
+ make.left.equalToSuperview().inset(18)
+ }
+ deviceView.snp.makeConstraints { make in
+ make.width.equalTo(120)
+ make.height.equalTo(26)
+ make.left.equalToSuperview().inset(94)
+ make.centerY.equalToSuperview()
+ }
+ deviceLabel.snp.makeConstraints { make in
+ make.centerY.right.equalToSuperview()
+ make.left.equalToSuperview().inset(18)
+ }
}
}
- override func setupLayout() {
- titleLabel.snp.makeConstraints { make in
- make.top.equalToSuperview().inset(0)
- make.left.right.equalToSuperview()
- }
- detailLabel.snp.makeConstraints { make in
- make.bottom.equalToSuperview().inset(0)
- make.left.right.equalToSuperview()
+
+ class LabelItem: BaseView {
+ let detailLabel = UILabel()
+ let titleLabel = UILabel()
+
+ override func setupViews() {
+ addSubviews([titleLabel,detailLabel])
+ titleLabel.do { v in
+ v.textColor = .color(.first)
+ v.font = .bold(24)
+ v.textAlignment = .left
+ }
+ detailLabel.do { v in
+ v.textColor = .color(.secondary)
+ v.font = .regular(12)
+ v.textAlignment = .left
+ }
+ }
+
+ override func setupLayout() {
+ titleLabel.snp.makeConstraints { make in
+ make.top.equalToSuperview().inset(0)
+ make.left.right.equalToSuperview()
+ }
+ detailLabel.snp.makeConstraints { make in
+ make.bottom.equalToSuperview().inset(0)
+ make.left.right.equalToSuperview()
+ }
}
}
}
-
+
+
+
}
}
simpleView.do { v in
- // v.backgroundColor = .blue
+ v.yc.setCorners(withRoundedRect: CGRect(x: 0, y: 0, width: kScreenWid, height: 100), roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 20, height: 20))
v.yc.addTap(target: self, action: #selector(simpleTapAction))
}
detailView.do { v in
+ v.yc.setCorners(withRoundedRect: CGRect(x: 0, y: 0, width: kScreenWid, height: 460), roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 20, height: 20))
v.isHidden = true
v.yc.addTap(target: self, action: #selector(detailTapAction))
}
}
mapView.snp.makeConstraints { make in
make.left.right.top.equalToSuperview()
- make.bottom.equalTo(simpleView.snp.top)
+ make.bottom.equalTo(simpleView.snp.top).offset(20)
}
}
override func setupData() {
func showSimple(){
mapView.snp.remakeConstraints { make in
make.left.right.top.equalToSuperview()
- make.bottom.equalTo(simpleView.snp.top)
+ make.bottom.equalTo(simpleView.snp.top).offset(20)
}
}
func showDetail(){
mapView.snp.remakeConstraints { make in
make.left.right.top.equalToSuperview()
- make.bottom.equalTo(detailView.snp.top)
+ make.bottom.equalTo(detailView.snp.top).offset(20)
}
}
}
static let shared = MapManager()
func setupSdk(){
+ MAMapView.updatePrivacyAgree(AMapPrivacyAgreeStatus.didAgree)
AMapServices.shared().apiKey = "57aebc5a63fa3ccb8cb81ae0cab649d1"
//判断是否是首次启动
if !UserDefaults.standard.bool(forKey: "agreeStatus") {