diff --git a/.DS_Store b/.DS_Store index b44cd28..f5d7a1d 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..752cb24 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/Pods/AMap3DMap/ diff --git a/AboutViewController.m b/AboutViewController.m new file mode 100644 index 0000000..0bf7184 --- /dev/null +++ b/AboutViewController.m @@ -0,0 +1,139 @@ +// +// AboutViewController.m +// MRMobileRun +// +// Created by 杨远舟 on 2020/8/6. +// + +#import "AboutViewController.h" +#import "Masonry.h" +@interface AboutViewController () + +@end + +@implementation AboutViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + [self.navigationItem setTitle:@"关于约跑"]; + + UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(125, 170, 130, 130)]; + imageView.image = [UIImage imageNamed:@"约跑"]; + imageView.layer.shadowColor = [UIColor blackColor].CGColor; + imageView.layer.shadowOffset= CGSizeMake(0,0);//偏移距离 + imageView.layer.shadowOpacity=0.3;//不透明度 + imageView.layer.shadowRadius=10.0;//半径 + [self.view addSubview:imageView]; + [imageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.view); + make.top.equalTo(self.view).offset(170*kRateY); + make.width.equalTo(@(130*kRateY)); + make.height.equalTo(@(130*kRateY)); + }]; + + UILabel *lable2 = [[UILabel alloc]initWithFrame:CGRectMake(145, 305,100, 50)]; + lable2.text = @"重邮约跑"; + lable2.textAlignment = NSTextAlignmentCenter; + [lable2 setFont:[UIFont fontWithName:@"Helvetica-Bold"size:23]]; + [self.view addSubview:lable2]; + [lable2 mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.view); + make.top.equalTo(self.view).offset(305*kRateY); + make.width.equalTo(@(100*kRateX)); + make.height.equalTo(@(50*kRateY)); + }]; + + UILabel *lable3 = [[UILabel alloc]initWithFrame:CGRectMake(147, 330, 100, 50)]; + lable3.text = @"Version 2.0.1"; + lable3.textAlignment = NSTextAlignmentCenter; + lable3.textColor = [UIColor lightGrayColor]; + lable3.font = [UIFont systemFontOfSize:15]; + [self.view addSubview:lable3]; + [lable3 mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.view); + make.top.equalTo(self.view).offset(330*kRateY); + make.width.equalTo(@(100*kRateX)); + make.height.equalTo(@(50*kRateY)); + }]; + + UILabel *lable4 = [[UILabel alloc]initWithFrame:CGRectMake(70, 655, 280, 50)]; + lable4.text = @"CopyRight@2013-2020 All Reserved"; + lable4.textAlignment = NSTextAlignmentCenter; + lable4.textColor = [UIColor lightGrayColor]; + lable4.font = [UIFont systemFontOfSize:15]; + [self.view addSubview:lable4]; + [lable4 mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.view); + make.top.equalTo(self.view).offset(665*kRateY); + make.width.equalTo(@(280*kRateX)); + make.height.equalTo(@(50*kRateY)); + }]; + + UIButton *btn1 = [[UIButton alloc]initWithFrame:CGRectMake(110, 630, 80, 30)]; + btn1.backgroundColor = [UIColor clearColor]; + [btn1 setTitle:@"检查更新" forState:UIControlStateNormal]; + [btn1 setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; + [btn1 addTarget:self action:@selector(actionAlert1) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:btn1]; + [btn1 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(110*kRateX); + make.top.equalTo(self.view).offset(630*kRateY); + make.width.equalTo(@(80*kRateX)); + make.height.equalTo(@(30*kRateY)); + }]; + + UIButton *btn2 = [[UIButton alloc]initWithFrame:CGRectMake(185, 630, 90, 30)]; + btn2.backgroundColor = [UIColor clearColor]; + [btn2 setTitle:@"| 使用条款" forState:UIControlStateNormal]; + [btn2 setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; + [btn2 addTarget:self action:@selector(actionAlert2) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:btn2]; + [btn2 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(185*kRateX); + make.top.equalTo(self.view).offset(630*kRateY); + make.width.equalTo(@(90*kRateX)); + make.height.equalTo(@(30*kRateY)); + }]; + + if (@available(iOS 13.0, *)) { + UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return [UIColor whiteColor]; + } else { //深色模式 + UIColor *color = [UIColor whiteColor]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:color forKey:UITextAttributeTextColor]; + self.navigationController.navigationBar.titleTextAttributes = dict; + + return [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } + }]; + self.view.backgroundColor = rightColor; //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } + +} +- (void)actionAlert1{ + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"已是最新版本,无需更新"message:@""preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]; + [alertController addAction:cancelAction]; + [alertController addAction:okAction]; + [self presentViewController:alertController animated:YES completion:nil]; +} +- (void)actionAlert2{ + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"使用条款"message:@"版权归红岩网校所有,感谢您的使用"preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]; + + [alertController addAction:okAction]; + [self presentViewController:alertController animated:YES completion:nil]; +} +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/Impact.ttf b/Impact.ttf new file mode 100644 index 0000000..8f6da36 Binary files /dev/null and b/Impact.ttf differ diff --git a/MRMobileRun.xcodeproj/project.pbxproj b/MRMobileRun.xcodeproj/project.pbxproj index 238b0c0..0587e1e 100644 --- a/MRMobileRun.xcodeproj/project.pbxproj +++ b/MRMobileRun.xcodeproj/project.pbxproj @@ -3,10 +3,33 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ + 182C88A9253151730007F0D9 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182C88A8253151730007F0D9 /* CoreTelephony.framework */; }; + 182C88AB253151830007F0D9 /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 182C88AA253151820007F0D9 /* libc++.tbd */; }; + 182C88B02531518E0007F0D9 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 182C88AF2531518E0007F0D9 /* libz.tbd */; }; + 182C88B5253151A20007F0D9 /* ExternalAccessory.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 182C88B4253151A20007F0D9 /* ExternalAccessory.framework */; }; + 182C88CD25329A620007F0D9 /* MGDTimeTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 182C88CC25329A620007F0D9 /* MGDTimeTool.m */; }; + 182C88D625329AD90007F0D9 /* MGDDataTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 182C88D525329AD90007F0D9 /* MGDDataTool.m */; }; + 182C88DC25329B100007F0D9 /* MGDRefreshTool.m in Sources */ = {isa = PBXBuildFile; fileRef = 182C88DB25329B100007F0D9 /* MGDRefreshTool.m */; }; + 184DE3CD251C442D00CFB058 /* MGDShareDataView.m in Sources */ = {isa = PBXBuildFile; fileRef = 184DE3CC251C442D00CFB058 /* MGDShareDataView.m */; }; + 185510C824F02405009D5026 /* MGDTabBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 185510C724F02405009D5026 /* MGDTabBar.m */; }; + 185510CB24F0241E009D5026 /* MGDTabBarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 185510CA24F0241E009D5026 /* MGDTabBarViewController.m */; }; + 187C812D24D037B30040A78E /* MGDShareModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 187C812C24D037B30040A78E /* MGDShareModel.m */; }; + 187C813024D037CE0040A78E /* MGDSharePlatform.m in Sources */ = {isa = PBXBuildFile; fileRef = 187C812E24D037CE0040A78E /* MGDSharePlatform.m */; }; + 18CD285F24C5B1B70093D396 /* MRTabBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 18CD285B24C5B1B70093D396 /* MRTabBarView.m */; }; + 18CD286024C5B1B70093D396 /* MRTabBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 18CD285C24C5B1B70093D396 /* MRTabBar.m */; }; + 18CD286124C5B1B70093D396 /* MRTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18CD285D24C5B1B70093D396 /* MRTabBarController.m */; }; + 18D838D224F4AAEF0074D7F4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 18D838D124F4AAEF0074D7F4 /* Assets.xcassets */; }; + 1A16B99324EED4AA00EAD884 /* AboutViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A16B99224EED4AA00EAD884 /* AboutViewController.m */; }; + 1A16B99624EED4BA00EAD884 /* SportSettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A16B99524EED4BA00EAD884 /* SportSettingViewController.m */; }; + 1A16B99824EED4CB00EAD884 /* SportSettingViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1A16B99724EED4CB00EAD884 /* SportSettingViewController.xib */; }; + 1A16B99F24EED4E700EAD884 /* YYZCommentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A16B99924EED4E700EAD884 /* YYZCommentViewController.m */; }; + 1A16B9A024EED4E700EAD884 /* YYZTextView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1A16B99A24EED4E700EAD884 /* YYZTextView.xib */; }; + 1A16B9A124EED4E700EAD884 /* YYZTextViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A16B99D24EED4E700EAD884 /* YYZTextViewController.m */; }; + 1A16B9A224EED4E700EAD884 /* YYZTextViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1A16B99E24EED4E700EAD884 /* YYZTextViewController.xib */; }; 280B3B7C228B9F9700FDD695 /* LJJInviteSearchVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 280B3B7B228B9F9700FDD695 /* LJJInviteSearchVC.m */; }; 280B3B7F228BA04200FDD695 /* LJJInviteSearchView.m in Sources */ = {isa = PBXBuildFile; fileRef = 280B3B7E228BA04200FDD695 /* LJJInviteSearchView.m */; }; 2889400F231E2D7B0002EDA8 /* MRRunningHistoryTrackController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2889400E231E2D7B0002EDA8 /* MRRunningHistoryTrackController.m */; }; @@ -53,13 +76,11 @@ 2F14F897239100B600356CDF /* ZYLSelfRankView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F14F896239100B600356CDF /* ZYLSelfRankView.m */; }; 2F14F89A2391025000356CDF /* ZYLSliderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F14F8992391025000356CDF /* ZYLSliderView.m */; }; 2F27F579243B5BDB00315D61 /* ZYLHealthManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F27F578243B5BDB00315D61 /* ZYLHealthManager.m */; }; - 2F27F57C243CB0F900315D61 /* ZYLCountdownView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F27F57B243CB0F900315D61 /* ZYLCountdownView.m */; }; 2F36BD022240CF4B00C1D8FC /* WeProgressCircle.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2F36BCFE2240CF4A00C1D8FC /* WeProgressCircle.xib */; }; 2F36BD032240CF4B00C1D8FC /* WeProgressCircle.png in Resources */ = {isa = PBXBuildFile; fileRef = 2F36BD002240CF4A00C1D8FC /* WeProgressCircle.png */; }; 2F36BD042240CF4B00C1D8FC /* WeProgressCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F36BD012240CF4A00C1D8FC /* WeProgressCircle.m */; }; 2F3ACABD230C41E2008D51E5 /* ZYLStartRunningButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F3ACABC230C41E2008D51E5 /* ZYLStartRunningButton.m */; }; 2F4044D62395429200EE93EC /* ZYLSegmentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F4044D52395429200EE93EC /* ZYLSegmentView.m */; }; - 2F495E1D2281BD99003DD714 /* ZYLPolling.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F495E1C2281BD99003DD714 /* ZYLPolling.m */; }; 2F495E232282BE19003DD714 /* HttpClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F495E222282BE19003DD714 /* HttpClient.m */; }; 2F495E2B2282BE6F003DD714 /* MRLoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F495E2A2282BE6F003DD714 /* MRLoginViewController.m */; }; 2F495E2E2282BE8A003DD714 /* MRLoginModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F495E2D2282BE8A003DD714 /* MRLoginModel.m */; }; @@ -75,10 +96,7 @@ 2F495E542282C064003DD714 /* LJJInviteRunView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F495E532282C064003DD714 /* LJJInviteRunView.m */; }; 2F495E572282D39B003DD714 /* ZYLRunningDataRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F495E562282D39B003DD714 /* ZYLRunningDataRequest.m */; }; 2F495E5A2282E509003DD714 /* ZYLRunningRecordModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F495E592282E509003DD714 /* ZYLRunningRecordModel.m */; }; - 2F495E602282FA90003DD714 /* MRTabBar.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F495E5F2282FA90003DD714 /* MRTabBar.m */; }; 2F5A1B4D2245DAB90014B249 /* MRBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F5A1B4C2245DAB90014B249 /* MRBaseViewController.m */; }; - 2F5A1B612245FCF70014B249 /* MRTabBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F5A1B602245FCF70014B249 /* MRTabBarView.m */; }; - 2F5A1B67224610580014B249 /* MRTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F5A1B66224610580014B249 /* MRTabBarController.m */; }; 2F5A1B6B2246451F0014B249 /* ZYLMainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F5A1B6A2246451F0014B249 /* ZYLMainViewController.m */; }; 2F5A1B72224659BB0014B249 /* ZYLArrowBtn.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F5A1B71224659BB0014B249 /* ZYLArrowBtn.m */; }; 2F5A1B7522465A250014B249 /* ZYLAvatarBtn.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F5A1B7422465A250014B249 /* ZYLAvatarBtn.m */; }; @@ -100,21 +118,11 @@ 2F5A1BAC22468BD40014B249 /* MRTimeLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F5A1BAB22468BD40014B249 /* MRTimeLabel.m */; }; 2F5CBE97225F00A000813943 /* GTMBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F5CBE95225F00A000813943 /* GTMBase64.m */; }; 2F5CBE98225F00A000813943 /* AES128Util.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F5CBE96225F00A000813943 /* AES128Util.m */; }; - 2F60AB40227C7E5300109420 /* MRAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F60AB3F227C7E5300109420 /* MRAlertView.m */; }; - 2F60AB43227C816400109420 /* ZYLUptateRunningData.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F60AB42227C816400109420 /* ZYLUptateRunningData.m */; }; - 2F60AB46227C858C00109420 /* ZYLTimeStamp.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F60AB45227C858C00109420 /* ZYLTimeStamp.m */; }; 2F60AB48227C934A00109420 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F60AB47227C934900109420 /* CoreMotion.framework */; }; - 2F60AB4B227C939D00109420 /* ZYLSteps.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F60AB4A227C939C00109420 /* ZYLSteps.m */; }; - 2F60AB4E227C9A1200109420 /* ZYLUpdateData.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F60AB4D227C9A1200109420 /* ZYLUpdateData.m */; }; 2F64924F243A031700472B57 /* ZYLGetTimeScale.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F64924E243A031700472B57 /* ZYLGetTimeScale.m */; }; 2F6DF0B8227B2E2700BA6099 /* ZYLRunningViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F6DF0B7227B2E2700BA6099 /* ZYLRunningViewController.m */; }; 2F6DF0BC227B2E4A00BA6099 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F6DF0BB227B2E4A00BA6099 /* CoreLocation.framework */; }; - 2F6DF0BF227B300800BA6099 /* ZYLRunningTabView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F6DF0BE227B300800BA6099 /* ZYLRunningTabView.m */; }; - 2F6DF0C2227B301B00BA6099 /* ZYLRunningRecordView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F6DF0C1227B301B00BA6099 /* ZYLRunningRecordView.m */; }; 2F6DF0C4227B303900BA6099 /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F6DF0C3227B303900BA6099 /* HealthKit.framework */; }; - 2F6DF0C7227B349D00BA6099 /* MRPauseAndResumeBtu.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F6DF0C6227B349D00BA6099 /* MRPauseAndResumeBtu.m */; }; - 2F6DF0CC227B34A400BA6099 /* MRStopBtu.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F6DF0C8227B34A400BA6099 /* MRStopBtu.m */; }; - 2F6DF0CD227B34A400BA6099 /* MRRunningLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F6DF0CA227B34A400BA6099 /* MRRunningLabel.m */; }; 2F734CC422675CC6006D8B63 /* ZYLPersonalModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F734CC322675CC6006D8B63 /* ZYLPersonalModel.m */; }; 2F734CCA22675EF9006D8B63 /* ZYLUploadAvatar.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F734CC922675EF9006D8B63 /* ZYLUploadAvatar.m */; }; 2F734CCD22676997006D8B63 /* ZYLChangeNickname.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F734CCC22676997006D8B63 /* ZYLChangeNickname.m */; }; @@ -131,8 +139,6 @@ 2F9673BD22F026E100BC6099 /* AESCipher.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F9673BB22F026E100BC6099 /* AESCipher.m */; }; 2F9CB6DF239BD8F60003C09D /* ZYLRewriteTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F9CB6DE239BD8F60003C09D /* ZYLRewriteTextField.m */; }; 2F9CB6E2239BDA260003C09D /* ZYLConfirmButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F9CB6E1239BDA260003C09D /* ZYLConfirmButton.m */; }; - 2FB21108227D77D0000D5A2E /* ZYLMD5Encrypt.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FB21107227D77D0000D5A2E /* ZYLMD5Encrypt.m */; }; - 2FB2110B22806711000D5A2E /* ZYLRecordTimeString.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FB2110A22806711000D5A2E /* ZYLRecordTimeString.m */; }; 2FB2110E22807D90000D5A2E /* ZYLBackBtn.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FB2110D22807D90000D5A2E /* ZYLBackBtn.m */; }; 2FBE8938230C446F0042AB0D /* ZYLNoticeBanner.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FBE8937230C446E0042AB0D /* ZYLNoticeBanner.m */; }; 2FBE893B230C448D0042AB0D /* ZYLButtonNoticeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2FBE893A230C448D0042AB0D /* ZYLButtonNoticeView.m */; }; @@ -151,8 +157,52 @@ 2FF4B25222845E3300779B7B /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FF4B25122845E3300779B7B /* AVFoundation.framework */; }; 2FF4B25422845E3B00779B7B /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FF4B25322845E3B00779B7B /* Photos.framework */; }; A2FBE48C666D5B5BDE81DFAA /* libPods-MRMobileRun.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AE32067601EFD0623CB60126 /* libPods-MRMobileRun.a */; }; + B840E7162562A41D006E8F77 /* StepModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B840E7152562A41D006E8F77 /* StepModel.m */; }; + B840E71C2562A937006E8F77 /* StepManager.m in Sources */ = {isa = PBXBuildFile; fileRef = B840E71B2562A937006E8F77 /* StepManager.m */; }; + B897C29924EE85B900E230EE /* RecordtimeString.m in Sources */ = {isa = PBXBuildFile; fileRef = B897C29824EE85B900E230EE /* RecordtimeString.m */; }; + B8ACCD9B24D4331B00D9F0D4 /* MASmoothPathTool.m in Sources */ = {isa = PBXBuildFile; fileRef = B8ACCD9A24D4331B00D9F0D4 /* MASmoothPathTool.m */; }; + B8BDEE8F24C7F8C20013293B /* RunLocationModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B8BDEE8E24C7F8C20013293B /* RunLocationModel.m */; }; + B8D9633124E9B2AE0035CF1C /* ZYLTimeStamp.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9632F24E9B2AD0035CF1C /* ZYLTimeStamp.m */; }; + B8D9633924E9B2CD0035CF1C /* Impact.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B8D9633224E9B2C80035CF1C /* Impact.ttf */; }; + B8D9633A24E9B2CD0035CF1C /* RunMainPageCV.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9633424E9B2CA0035CF1C /* RunMainPageCV.m */; }; + B8D9633B24E9B2CD0035CF1C /* MGDCellDataViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9633524E9B2CB0035CF1C /* MGDCellDataViewController.m */; }; + B8D9633C24E9B2CD0035CF1C /* MGDDataViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9633824E9B2CD0035CF1C /* MGDDataViewController.m */; }; + B8D9639424E9B33D0035CF1C /* RunningMainPageView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9638024E9B3320035CF1C /* RunningMainPageView.m */; }; + B8D9639524E9B33D0035CF1C /* SZHAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9638124E9B3330035CF1C /* SZHAlertView.m */; }; + B8D9639624E9B33D0035CF1C /* LongPressView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9638324E9B3340035CF1C /* LongPressView.m */; }; + B8D9639724E9B33D0035CF1C /* SZHChart.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9638724E9B3360035CF1C /* SZHChart.m */; }; + B8D9639824E9B33D0035CF1C /* MGDOverView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9638A24E9B3380035CF1C /* MGDOverView.m */; }; + B8D9639924E9B33D0035CF1C /* MGDDataView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9638D24E9B33A0035CF1C /* MGDDataView.m */; }; + B8D9639A24E9B33D0035CF1C /* RunMainBtn.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9638E24E9B33A0035CF1C /* RunMainBtn.m */; }; + B8D9639B24E9B33D0035CF1C /* SZHWaveChart.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9639024E9B33B0035CF1C /* SZHWaveChart.m */; }; + B8D9639C24E9B33D0035CF1C /* MGDButtonsView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9639124E9B33C0035CF1C /* MGDButtonsView.m */; }; + B8D9639D24E9B33D0035CF1C /* MGDShareView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8D9639324E9B33D0035CF1C /* MGDShareView.m */; }; + B8EA9A1C2508EDD9009290FE /* style_extra.data in Resources */ = {isa = PBXBuildFile; fileRef = B8EA9A1A2508EDD8009290FE /* style_extra.data */; }; + B8EA9A1D2508EDD9009290FE /* style.data in Resources */ = {isa = PBXBuildFile; fileRef = B8EA9A1B2508EDD9009290FE /* style.data */; }; + B8FA9FB6250BABDB009457AF /* style2.data in Resources */ = {isa = PBXBuildFile; fileRef = B8FA9FB5250BABDB009457AF /* style2.data */; }; + B8FA9FB8250BABE3009457AF /* style_extra2.data in Resources */ = {isa = PBXBuildFile; fileRef = B8FA9FB7250BABE3009457AF /* style_extra2.data */; }; + B8FAA01D250F9027009457AF /* 结束白.svg in Resources */ = {isa = PBXBuildFile; fileRef = B8FAA01C250F9027009457AF /* 结束白.svg */; }; + B8FAA020250F979D009457AF /* UIImage+SVGTool.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FAA01E250F979C009457AF /* UIImage+SVGTool.m */; }; + B8FAA022250F99EA009457AF /* 继续白.svg in Resources */ = {isa = PBXBuildFile; fileRef = B8FAA021250F99EA009457AF /* 继续白.svg */; }; + B8FAA024250F9B44009457AF /* 暂停白.svg in Resources */ = {isa = PBXBuildFile; fileRef = B8FAA023250F9B44009457AF /* 暂停白.svg */; }; + B8FAA026250F9B4F009457AF /* 暂停黑.svg in Resources */ = {isa = PBXBuildFile; fileRef = B8FAA025250F9B4F009457AF /* 暂停黑.svg */; }; + B8FAA028250F9F9C009457AF /* 锁定白.svg in Resources */ = {isa = PBXBuildFile; fileRef = B8FAA027250F9F9C009457AF /* 锁定白.svg */; }; + B8FAA02A250F9FA4009457AF /* 锁定黑.svg in Resources */ = {isa = PBXBuildFile; fileRef = B8FAA029250F9FA4009457AF /* 锁定黑.svg */; }; + B8FAA02C250FA3E2009457AF /* 锁定灰.svg in Resources */ = {isa = PBXBuildFile; fileRef = B8FAA02B250FA3E2009457AF /* 锁定灰.svg */; }; + B8FE2AF624EBA434009DC23D /* YBRectConst.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2AD824EBA434009DC23D /* YBRectConst.m */; }; + B8FE2AF724EBA434009DC23D /* YBPopupMenuPath.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2AD924EBA434009DC23D /* YBPopupMenuPath.m */; }; + B8FE2AF824EBA434009DC23D /* YBPopupMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2ADB24EBA434009DC23D /* YBPopupMenu.m */; }; + B8FE2AF924EBA434009DC23D /* MGDUserData.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2ADE24EBA434009DC23D /* MGDUserData.m */; }; + B8FE2AFA24EBA434009DC23D /* MGDSportData.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2AE124EBA434009DC23D /* MGDSportData.m */; }; + B8FE2AFB24EBA434009DC23D /* MGDBaseInfoView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2AE524EBA434009DC23D /* MGDBaseInfoView.m */; }; + B8FE2AFC24EBA434009DC23D /* MGDSportTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2AE624EBA434009DC23D /* MGDSportTableView.m */; }; + B8FE2AFD24EBA434009DC23D /* MGDColumnChartView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2AEA24EBA434009DC23D /* MGDColumnChartView.m */; }; + B8FE2AFF24EBA434009DC23D /* MGDTopView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2AEC24EBA434009DC23D /* MGDTopView.m */; }; + B8FE2B0024EBA434009DC23D /* MGDMiddleView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2AED24EBA434009DC23D /* MGDMiddleView.m */; }; + B8FE2B0124EBA434009DC23D /* MGDSportTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2AEE24EBA434009DC23D /* MGDSportTableViewCell.m */; }; + B8FE2B0224EBA434009DC23D /* MGDMineViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2AF224EBA434009DC23D /* MGDMineViewController.m */; }; + B8FE2B0324EBA434009DC23D /* MGDMoreViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FE2AF524EBA434009DC23D /* MGDMoreViewController.m */; }; CE0CC17E222E2059001283EA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0CC17D222E2059001283EA /* AppDelegate.m */; }; - CE0CC186222E205B001283EA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE0CC185222E205B001283EA /* Assets.xcassets */; }; CE0CC189222E205B001283EA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CE0CC187222E205B001283EA /* LaunchScreen.storyboard */; }; CE0CC18C222E205B001283EA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0CC18B222E205B001283EA /* main.m */; }; CE0CC196222E205C001283EA /* MRMobileRunTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0CC195222E205C001283EA /* MRMobileRunTests.m */; }; @@ -164,6 +214,21 @@ CE0CC1CE222E5048001283EA /* MRDemoModel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0CC1CD222E5048001283EA /* MRDemoModel.m */; }; CE0CC1D1222E505C001283EA /* MRDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0CC1D0222E505C001283EA /* MRDemoViewController.m */; }; CE0CC1D4222E506B001283EA /* MRDemoViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0CC1D3222E506B001283EA /* MRDemoViewModel.m */; }; + E323B11724E144270092BD40 /* GYYHealthTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E323B11624E144270092BD40 /* GYYHealthTableViewCell.m */; }; + E323B11B24E1444C0092BD40 /* GYYRunTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E323B11A24E1444C0092BD40 /* GYYRunTableViewCell.m */; }; + E323B11D24E144680092BD40 /* GYYHealthManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E323B11C24E144680092BD40 /* GYYHealthManager.m */; }; + E323B12024E144890092BD40 /* GYYRunModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E323B11F24E144890092BD40 /* GYYRunModel.m */; }; + E34D9E2224E981A800906BAD /* GYYRankHeaderMainView.m in Sources */ = {isa = PBXBuildFile; fileRef = E34D9E2124E981A800906BAD /* GYYRankHeaderMainView.m */; }; + E34D9E2524E981D400906BAD /* GYYRankTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E34D9E2424E981D400906BAD /* GYYRankTableViewCell.m */; }; + E34D9E2824E981F000906BAD /* GYYRankModel.m in Sources */ = {isa = PBXBuildFile; fileRef = E34D9E2624E981F000906BAD /* GYYRankModel.m */; }; + E3F60FDA24F13049001F42B1 /* GYYRankChildViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E3F60FD924F13049001F42B1 /* GYYRankChildViewController.m */; }; + E3F60FDE24F13057001F42B1 /* GYYRankUnitViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E3F60FDB24F13057001F42B1 /* GYYRankUnitViewController.m */; }; + E3F60FF024F14CE8001F42B1 /* TYPagerController.m in Sources */ = {isa = PBXBuildFile; fileRef = E3F60FE324F14CE8001F42B1 /* TYPagerController.m */; }; + E3F60FF124F14CE8001F42B1 /* TYPagerViewLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = E3F60FE424F14CE8001F42B1 /* TYPagerViewLayout.m */; }; + E3F60FF224F14CE8001F42B1 /* TYTabPagerBar.m in Sources */ = {isa = PBXBuildFile; fileRef = E3F60FE624F14CE8001F42B1 /* TYTabPagerBar.m */; }; + E3F60FF324F14CE8001F42B1 /* TYTabPagerBarLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = E3F60FE724F14CE8001F42B1 /* TYTabPagerBarLayout.m */; }; + E3F60FF424F14CE8001F42B1 /* TYTabPagerBarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E3F60FEB24F14CE8001F42B1 /* TYTabPagerBarCell.m */; }; + E3F60FF524F14CE8001F42B1 /* TYPagerView.m in Sources */ = {isa = PBXBuildFile; fileRef = E3F60FEC24F14CE8001F42B1 /* TYPagerView.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -185,6 +250,45 @@ /* Begin PBXFileReference section */ 152E1617FE665064308B5999 /* Pods-MRMobileRun.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MRMobileRun.release.xcconfig"; path = "Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun.release.xcconfig"; sourceTree = ""; }; + 182C88A8253151730007F0D9 /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; + 182C88AA253151820007F0D9 /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; + 182C88AF2531518E0007F0D9 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; + 182C88B4253151A20007F0D9 /* ExternalAccessory.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ExternalAccessory.framework; path = System/Library/Frameworks/ExternalAccessory.framework; sourceTree = SDKROOT; }; + 182C88B9253151ED0007F0D9 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/PrivateFrameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; + 182C88CB25329A620007F0D9 /* MGDTimeTool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGDTimeTool.h; sourceTree = ""; }; + 182C88CC25329A620007F0D9 /* MGDTimeTool.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGDTimeTool.m; sourceTree = ""; }; + 182C88D425329AD90007F0D9 /* MGDDataTool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGDDataTool.h; sourceTree = ""; }; + 182C88D525329AD90007F0D9 /* MGDDataTool.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGDDataTool.m; sourceTree = ""; }; + 182C88DA25329B100007F0D9 /* MGDRefreshTool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGDRefreshTool.h; sourceTree = ""; }; + 182C88DB25329B100007F0D9 /* MGDRefreshTool.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGDRefreshTool.m; sourceTree = ""; }; + 184DE3CB251C442D00CFB058 /* MGDShareDataView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGDShareDataView.h; sourceTree = ""; }; + 184DE3CC251C442D00CFB058 /* MGDShareDataView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGDShareDataView.m; sourceTree = ""; }; + 185510C624F02405009D5026 /* MGDTabBar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGDTabBar.h; sourceTree = ""; }; + 185510C724F02405009D5026 /* MGDTabBar.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGDTabBar.m; sourceTree = ""; }; + 185510C924F0241E009D5026 /* MGDTabBarViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGDTabBarViewController.h; sourceTree = ""; }; + 185510CA24F0241E009D5026 /* MGDTabBarViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGDTabBarViewController.m; sourceTree = ""; }; + 187C812A24D037860040A78E /* MGDShareModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDShareModel.h; sourceTree = ""; }; + 187C812C24D037B30040A78E /* MGDShareModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDShareModel.m; sourceTree = ""; }; + 187C812E24D037CE0040A78E /* MGDSharePlatform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDSharePlatform.m; sourceTree = ""; }; + 187C812F24D037CE0040A78E /* MGDSharePlatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDSharePlatform.h; sourceTree = ""; }; + 18CD285924C5B1B70093D396 /* MRTabBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRTabBar.h; sourceTree = ""; }; + 18CD285A24C5B1B70093D396 /* MRTabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRTabBarController.h; sourceTree = ""; }; + 18CD285B24C5B1B70093D396 /* MRTabBarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MRTabBarView.m; sourceTree = ""; }; + 18CD285C24C5B1B70093D396 /* MRTabBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MRTabBar.m; sourceTree = ""; }; + 18CD285D24C5B1B70093D396 /* MRTabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MRTabBarController.m; sourceTree = ""; }; + 18CD285E24C5B1B70093D396 /* MRTabBarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRTabBarView.h; sourceTree = ""; }; + 18D838D124F4AAEF0074D7F4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 1A16B99124EED4AA00EAD884 /* AboutViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutViewController.h; sourceTree = ""; }; + 1A16B99224EED4AA00EAD884 /* AboutViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutViewController.m; sourceTree = ""; }; + 1A16B99424EED4BA00EAD884 /* SportSettingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SportSettingViewController.h; sourceTree = ""; }; + 1A16B99524EED4BA00EAD884 /* SportSettingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SportSettingViewController.m; sourceTree = ""; }; + 1A16B99724EED4CB00EAD884 /* SportSettingViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SportSettingViewController.xib; sourceTree = ""; }; + 1A16B99924EED4E700EAD884 /* YYZCommentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YYZCommentViewController.m; sourceTree = ""; }; + 1A16B99A24EED4E700EAD884 /* YYZTextView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = YYZTextView.xib; sourceTree = ""; }; + 1A16B99B24EED4E700EAD884 /* YYZCommentViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YYZCommentViewController.h; sourceTree = ""; }; + 1A16B99C24EED4E700EAD884 /* YYZTextViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YYZTextViewController.h; sourceTree = ""; }; + 1A16B99D24EED4E700EAD884 /* YYZTextViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YYZTextViewController.m; sourceTree = ""; }; + 1A16B99E24EED4E700EAD884 /* YYZTextViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = YYZTextViewController.xib; sourceTree = ""; }; 280B3B7A228B9F9700FDD695 /* LJJInviteSearchVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LJJInviteSearchVC.h; sourceTree = ""; }; 280B3B7B228B9F9700FDD695 /* LJJInviteSearchVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LJJInviteSearchVC.m; sourceTree = ""; }; 280B3B7D228BA04200FDD695 /* LJJInviteSearchView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LJJInviteSearchView.h; sourceTree = ""; }; @@ -274,8 +378,6 @@ 2F14F8992391025000356CDF /* ZYLSliderView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLSliderView.m; sourceTree = ""; }; 2F27F577243B5BDB00315D61 /* ZYLHealthManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLHealthManager.h; sourceTree = ""; }; 2F27F578243B5BDB00315D61 /* ZYLHealthManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLHealthManager.m; sourceTree = ""; }; - 2F27F57A243CB0F900315D61 /* ZYLCountdownView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLCountdownView.h; sourceTree = ""; }; - 2F27F57B243CB0F900315D61 /* ZYLCountdownView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLCountdownView.m; sourceTree = ""; }; 2F36BCFE2240CF4A00C1D8FC /* WeProgressCircle.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WeProgressCircle.xib; sourceTree = ""; }; 2F36BCFF2240CF4A00C1D8FC /* WeProgressCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeProgressCircle.h; sourceTree = ""; }; 2F36BD002240CF4A00C1D8FC /* WeProgressCircle.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = WeProgressCircle.png; sourceTree = ""; }; @@ -284,8 +386,6 @@ 2F3ACABC230C41E2008D51E5 /* ZYLStartRunningButton.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLStartRunningButton.m; sourceTree = ""; }; 2F4044D42395429200EE93EC /* ZYLSegmentView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLSegmentView.h; sourceTree = ""; }; 2F4044D52395429200EE93EC /* ZYLSegmentView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLSegmentView.m; sourceTree = ""; }; - 2F495E1B2281BD99003DD714 /* ZYLPolling.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLPolling.h; sourceTree = ""; }; - 2F495E1C2281BD99003DD714 /* ZYLPolling.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLPolling.m; sourceTree = ""; }; 2F495E212282BE19003DD714 /* HttpClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HttpClient.h; sourceTree = ""; }; 2F495E222282BE19003DD714 /* HttpClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HttpClient.m; sourceTree = ""; }; 2F495E292282BE6F003DD714 /* MRLoginViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRLoginViewController.h; sourceTree = ""; }; @@ -316,14 +416,8 @@ 2F495E562282D39B003DD714 /* ZYLRunningDataRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLRunningDataRequest.m; sourceTree = ""; }; 2F495E582282E509003DD714 /* ZYLRunningRecordModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLRunningRecordModel.h; sourceTree = ""; }; 2F495E592282E509003DD714 /* ZYLRunningRecordModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLRunningRecordModel.m; sourceTree = ""; }; - 2F495E5E2282FA90003DD714 /* MRTabBar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MRTabBar.h; sourceTree = ""; }; - 2F495E5F2282FA90003DD714 /* MRTabBar.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MRTabBar.m; sourceTree = ""; }; 2F5A1B4B2245DAB90014B249 /* MRBaseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MRBaseViewController.h; sourceTree = ""; }; 2F5A1B4C2245DAB90014B249 /* MRBaseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MRBaseViewController.m; sourceTree = ""; }; - 2F5A1B5F2245FCF70014B249 /* MRTabBarView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MRTabBarView.h; sourceTree = ""; }; - 2F5A1B602245FCF70014B249 /* MRTabBarView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MRTabBarView.m; sourceTree = ""; }; - 2F5A1B65224610580014B249 /* MRTabBarController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MRTabBarController.h; sourceTree = ""; }; - 2F5A1B66224610580014B249 /* MRTabBarController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MRTabBarController.m; sourceTree = ""; }; 2F5A1B692246451F0014B249 /* ZYLMainViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLMainViewController.h; sourceTree = ""; }; 2F5A1B6A2246451F0014B249 /* ZYLMainViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLMainViewController.m; sourceTree = ""; }; 2F5A1B70224659BB0014B249 /* ZYLArrowBtn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLArrowBtn.h; sourceTree = ""; }; @@ -332,7 +426,6 @@ 2F5A1B7422465A250014B249 /* ZYLAvatarBtn.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLAvatarBtn.m; sourceTree = ""; }; 2F5A1B7622465B1D0014B249 /* ZYLTitleLabel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLTitleLabel.h; sourceTree = ""; }; 2F5A1B7722465B1D0014B249 /* ZYLTitleLabel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLTitleLabel.m; sourceTree = ""; }; - 2F5A1B7B224662B00014B249 /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; 2F5A1B7C224670A90014B249 /* ZYLLeaderboardBtn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLLeaderboardBtn.h; sourceTree = ""; }; 2F5A1B7D224670A90014B249 /* ZYLLeaderboardBtn.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLLeaderboardBtn.m; sourceTree = ""; }; 2F5A1B7F224671140014B249 /* ZYLRunningRecordBtn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLRunningRecordBtn.h; sourceTree = ""; }; @@ -369,33 +462,13 @@ 2F5CBE94225F00A000813943 /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = ""; }; 2F5CBE95225F00A000813943 /* GTMBase64.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMBase64.m; sourceTree = ""; }; 2F5CBE96225F00A000813943 /* AES128Util.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AES128Util.m; sourceTree = ""; }; - 2F60AB3E227C7E5300109420 /* MRAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRAlertView.h; sourceTree = ""; }; - 2F60AB3F227C7E5300109420 /* MRAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MRAlertView.m; sourceTree = ""; }; - 2F60AB41227C816400109420 /* ZYLUptateRunningData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLUptateRunningData.h; sourceTree = ""; }; - 2F60AB42227C816400109420 /* ZYLUptateRunningData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLUptateRunningData.m; sourceTree = ""; }; - 2F60AB44227C858C00109420 /* ZYLTimeStamp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLTimeStamp.h; sourceTree = ""; }; - 2F60AB45227C858C00109420 /* ZYLTimeStamp.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLTimeStamp.m; sourceTree = ""; }; 2F60AB47227C934900109420 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; - 2F60AB49227C939C00109420 /* ZYLSteps.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLSteps.h; sourceTree = ""; }; - 2F60AB4A227C939C00109420 /* ZYLSteps.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLSteps.m; sourceTree = ""; }; - 2F60AB4C227C9A1200109420 /* ZYLUpdateData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLUpdateData.h; sourceTree = ""; }; - 2F60AB4D227C9A1200109420 /* ZYLUpdateData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLUpdateData.m; sourceTree = ""; }; 2F64924D243A031700472B57 /* ZYLGetTimeScale.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLGetTimeScale.h; sourceTree = ""; }; 2F64924E243A031700472B57 /* ZYLGetTimeScale.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLGetTimeScale.m; sourceTree = ""; }; 2F6DF0B6227B2E2700BA6099 /* ZYLRunningViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLRunningViewController.h; sourceTree = ""; }; 2F6DF0B7227B2E2700BA6099 /* ZYLRunningViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLRunningViewController.m; sourceTree = ""; }; 2F6DF0BB227B2E4A00BA6099 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; - 2F6DF0BD227B300800BA6099 /* ZYLRunningTabView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLRunningTabView.h; sourceTree = ""; }; - 2F6DF0BE227B300800BA6099 /* ZYLRunningTabView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLRunningTabView.m; sourceTree = ""; }; - 2F6DF0C0227B301B00BA6099 /* ZYLRunningRecordView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLRunningRecordView.h; sourceTree = ""; }; - 2F6DF0C1227B301B00BA6099 /* ZYLRunningRecordView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLRunningRecordView.m; sourceTree = ""; }; 2F6DF0C3227B303900BA6099 /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; }; - 2F6DF0C5227B349D00BA6099 /* MRPauseAndResumeBtu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRPauseAndResumeBtu.h; sourceTree = ""; }; - 2F6DF0C6227B349D00BA6099 /* MRPauseAndResumeBtu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MRPauseAndResumeBtu.m; sourceTree = ""; }; - 2F6DF0C8227B34A400BA6099 /* MRStopBtu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MRStopBtu.m; sourceTree = ""; }; - 2F6DF0C9227B34A400BA6099 /* MRRunningLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRRunningLabel.h; sourceTree = ""; }; - 2F6DF0CA227B34A400BA6099 /* MRRunningLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MRRunningLabel.m; sourceTree = ""; }; - 2F6DF0CB227B34A400BA6099 /* MRStopBtu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MRStopBtu.h; sourceTree = ""; }; 2F734CC222675CC6006D8B63 /* ZYLPersonalModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLPersonalModel.h; sourceTree = ""; }; 2F734CC322675CC6006D8B63 /* ZYLPersonalModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLPersonalModel.m; sourceTree = ""; }; 2F734CC822675EF9006D8B63 /* ZYLUploadAvatar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLUploadAvatar.h; sourceTree = ""; }; @@ -428,10 +501,6 @@ 2F9CB6DE239BD8F60003C09D /* ZYLRewriteTextField.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLRewriteTextField.m; sourceTree = ""; }; 2F9CB6E0239BDA260003C09D /* ZYLConfirmButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLConfirmButton.h; sourceTree = ""; }; 2F9CB6E1239BDA260003C09D /* ZYLConfirmButton.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLConfirmButton.m; sourceTree = ""; }; - 2FB21106227D77D0000D5A2E /* ZYLMD5Encrypt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLMD5Encrypt.h; sourceTree = ""; }; - 2FB21107227D77D0000D5A2E /* ZYLMD5Encrypt.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLMD5Encrypt.m; sourceTree = ""; }; - 2FB2110922806711000D5A2E /* ZYLRecordTimeString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLRecordTimeString.h; sourceTree = ""; }; - 2FB2110A22806711000D5A2E /* ZYLRecordTimeString.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ZYLRecordTimeString.m; sourceTree = ""; }; 2FB2110C22807D90000D5A2E /* ZYLBackBtn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ZYLBackBtn.h; path = MRRunning/ZYLBackBtn.h; sourceTree = ""; }; 2FB2110D22807D90000D5A2E /* ZYLBackBtn.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ZYLBackBtn.m; path = MRRunning/ZYLBackBtn.m; sourceTree = ""; }; 2FBE8936230C446E0042AB0D /* ZYLNoticeBanner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZYLNoticeBanner.h; sourceTree = ""; }; @@ -466,10 +535,88 @@ 2FF4B25322845E3B00779B7B /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = System/Library/Frameworks/Photos.framework; sourceTree = SDKROOT; }; AE32067601EFD0623CB60126 /* libPods-MRMobileRun.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MRMobileRun.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B02B7E7755F4D843FA333CD9 /* Pods-MRMobileRun.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MRMobileRun.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun.debug.xcconfig"; sourceTree = ""; }; + B840E7142562A41D006E8F77 /* StepModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StepModel.h; sourceTree = ""; }; + B840E7152562A41D006E8F77 /* StepModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StepModel.m; sourceTree = ""; }; + B840E71A2562A937006E8F77 /* StepManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StepManager.h; sourceTree = ""; }; + B840E71B2562A937006E8F77 /* StepManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = StepManager.m; sourceTree = ""; }; + B897C29724EE85B800E230EE /* RecordtimeString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordtimeString.h; sourceTree = ""; }; + B897C29824EE85B900E230EE /* RecordtimeString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecordtimeString.m; sourceTree = ""; }; + B8ACCD9924D4331B00D9F0D4 /* MASmoothPathTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASmoothPathTool.h; sourceTree = ""; }; + B8ACCD9A24D4331B00D9F0D4 /* MASmoothPathTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASmoothPathTool.m; sourceTree = ""; }; + B8BDEE8D24C7F8C20013293B /* RunLocationModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RunLocationModel.h; sourceTree = ""; }; + B8BDEE8E24C7F8C20013293B /* RunLocationModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RunLocationModel.m; sourceTree = ""; }; + B8D9632F24E9B2AD0035CF1C /* ZYLTimeStamp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ZYLTimeStamp.m; sourceTree = ""; }; + B8D9633024E9B2AE0035CF1C /* ZYLTimeStamp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZYLTimeStamp.h; sourceTree = ""; }; + B8D9633224E9B2C80035CF1C /* Impact.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Impact.ttf; sourceTree = ""; }; + B8D9633324E9B2C90035CF1C /* RunMainPageCV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RunMainPageCV.h; sourceTree = ""; }; + B8D9633424E9B2CA0035CF1C /* RunMainPageCV.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RunMainPageCV.m; sourceTree = ""; }; + B8D9633524E9B2CB0035CF1C /* MGDCellDataViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDCellDataViewController.m; sourceTree = ""; }; + B8D9633624E9B2CB0035CF1C /* MGDCellDataViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDCellDataViewController.h; sourceTree = ""; }; + B8D9633724E9B2CC0035CF1C /* MGDDataViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDDataViewController.h; sourceTree = ""; }; + B8D9633824E9B2CD0035CF1C /* MGDDataViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDDataViewController.m; sourceTree = ""; }; + B8D9638024E9B3320035CF1C /* RunningMainPageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RunningMainPageView.m; sourceTree = ""; }; + B8D9638124E9B3330035CF1C /* SZHAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SZHAlertView.m; sourceTree = ""; }; + B8D9638224E9B3340035CF1C /* MGDShareView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDShareView.h; sourceTree = ""; }; + B8D9638324E9B3340035CF1C /* LongPressView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LongPressView.m; sourceTree = ""; }; + B8D9638424E9B3350035CF1C /* SZHWaveChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SZHWaveChart.h; sourceTree = ""; }; + B8D9638524E9B3350035CF1C /* RunningMainPageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RunningMainPageView.h; sourceTree = ""; }; + B8D9638624E9B3360035CF1C /* SZHChart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SZHChart.h; sourceTree = ""; }; + B8D9638724E9B3360035CF1C /* SZHChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SZHChart.m; sourceTree = ""; }; + B8D9638824E9B3370035CF1C /* MGDButtonsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDButtonsView.h; sourceTree = ""; }; + B8D9638924E9B3370035CF1C /* LongPressView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LongPressView.h; sourceTree = ""; }; + B8D9638A24E9B3380035CF1C /* MGDOverView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDOverView.m; sourceTree = ""; }; + B8D9638B24E9B3380035CF1C /* SZHAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SZHAlertView.h; sourceTree = ""; }; + B8D9638C24E9B3390035CF1C /* RunMainBtn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RunMainBtn.h; sourceTree = ""; }; + B8D9638D24E9B33A0035CF1C /* MGDDataView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDDataView.m; sourceTree = ""; }; + B8D9638E24E9B33A0035CF1C /* RunMainBtn.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RunMainBtn.m; sourceTree = ""; }; + B8D9638F24E9B33B0035CF1C /* MGDDataView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDDataView.h; sourceTree = ""; }; + B8D9639024E9B33B0035CF1C /* SZHWaveChart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SZHWaveChart.m; sourceTree = ""; }; + B8D9639124E9B33C0035CF1C /* MGDButtonsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDButtonsView.m; sourceTree = ""; }; + B8D9639224E9B33C0035CF1C /* MGDOverView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDOverView.h; sourceTree = ""; }; + B8D9639324E9B33D0035CF1C /* MGDShareView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDShareView.m; sourceTree = ""; }; + B8D9639E24E9B4360035CF1C /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; + B8EA9A1A2508EDD8009290FE /* style_extra.data */ = {isa = PBXFileReference; lastKnownFileType = file; path = style_extra.data; sourceTree = ""; }; + B8EA9A1B2508EDD9009290FE /* style.data */ = {isa = PBXFileReference; lastKnownFileType = file; path = style.data; sourceTree = ""; }; + B8FA9FB5250BABDB009457AF /* style2.data */ = {isa = PBXFileReference; lastKnownFileType = file; path = style2.data; sourceTree = ""; }; + B8FA9FB7250BABE3009457AF /* style_extra2.data */ = {isa = PBXFileReference; lastKnownFileType = file; path = style_extra2.data; sourceTree = ""; }; + B8FAA01C250F9027009457AF /* 结束白.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "结束白.svg"; sourceTree = ""; }; + B8FAA01E250F979C009457AF /* UIImage+SVGTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+SVGTool.m"; sourceTree = ""; }; + B8FAA01F250F979D009457AF /* UIImage+SVGTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+SVGTool.h"; sourceTree = ""; }; + B8FAA021250F99EA009457AF /* 继续白.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "继续白.svg"; sourceTree = ""; }; + B8FAA023250F9B44009457AF /* 暂停白.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "暂停白.svg"; sourceTree = ""; }; + B8FAA025250F9B4F009457AF /* 暂停黑.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "暂停黑.svg"; sourceTree = ""; }; + B8FAA027250F9F9C009457AF /* 锁定白.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "锁定白.svg"; sourceTree = ""; }; + B8FAA029250F9FA4009457AF /* 锁定黑.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "锁定黑.svg"; sourceTree = ""; }; + B8FAA02B250FA3E2009457AF /* 锁定灰.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "锁定灰.svg"; sourceTree = ""; }; + B8FE2AD724EBA434009DC23D /* YBPopupMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YBPopupMenu.h; sourceTree = ""; }; + B8FE2AD824EBA434009DC23D /* YBRectConst.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YBRectConst.m; sourceTree = ""; }; + B8FE2AD924EBA434009DC23D /* YBPopupMenuPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YBPopupMenuPath.m; sourceTree = ""; }; + B8FE2ADA24EBA434009DC23D /* YBRectConst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YBRectConst.h; sourceTree = ""; }; + B8FE2ADB24EBA434009DC23D /* YBPopupMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YBPopupMenu.m; sourceTree = ""; }; + B8FE2ADC24EBA434009DC23D /* YBPopupMenuPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YBPopupMenuPath.h; sourceTree = ""; }; + B8FE2ADE24EBA434009DC23D /* MGDUserData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDUserData.m; sourceTree = ""; }; + B8FE2ADF24EBA434009DC23D /* MGDSportData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDSportData.h; sourceTree = ""; }; + B8FE2AE024EBA434009DC23D /* MGDUserData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDUserData.h; sourceTree = ""; }; + B8FE2AE124EBA434009DC23D /* MGDSportData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDSportData.m; sourceTree = ""; }; + B8FE2AE424EBA434009DC23D /* MGDColumnChartView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDColumnChartView.h; sourceTree = ""; }; + B8FE2AE524EBA434009DC23D /* MGDBaseInfoView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDBaseInfoView.m; sourceTree = ""; }; + B8FE2AE624EBA434009DC23D /* MGDSportTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDSportTableView.m; sourceTree = ""; }; + B8FE2AE724EBA434009DC23D /* MGDSportTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDSportTableViewCell.h; sourceTree = ""; }; + B8FE2AE824EBA434009DC23D /* MGDMiddleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDMiddleView.h; sourceTree = ""; }; + B8FE2AE924EBA434009DC23D /* MGDTopView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDTopView.h; sourceTree = ""; }; + B8FE2AEA24EBA434009DC23D /* MGDColumnChartView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDColumnChartView.m; sourceTree = ""; }; + B8FE2AEC24EBA434009DC23D /* MGDTopView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDTopView.m; sourceTree = ""; }; + B8FE2AED24EBA434009DC23D /* MGDMiddleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDMiddleView.m; sourceTree = ""; }; + B8FE2AEE24EBA434009DC23D /* MGDSportTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDSportTableViewCell.m; sourceTree = ""; }; + B8FE2AEF24EBA434009DC23D /* MGDSportTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDSportTableView.h; sourceTree = ""; }; + B8FE2AF024EBA434009DC23D /* MGDBaseInfoView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDBaseInfoView.h; sourceTree = ""; }; + B8FE2AF224EBA434009DC23D /* MGDMineViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDMineViewController.m; sourceTree = ""; }; + B8FE2AF324EBA434009DC23D /* MGDMoreViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDMoreViewController.h; sourceTree = ""; }; + B8FE2AF424EBA434009DC23D /* MGDMineViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGDMineViewController.h; sourceTree = ""; }; + B8FE2AF524EBA434009DC23D /* MGDMoreViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGDMoreViewController.m; sourceTree = ""; }; CE0CC179222E2059001283EA /* MRMobileRun.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MRMobileRun.app; sourceTree = BUILT_PRODUCTS_DIR; }; CE0CC17C222E2059001283EA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; CE0CC17D222E2059001283EA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - CE0CC185222E205B001283EA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; CE0CC188222E205B001283EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; CE0CC18A222E205B001283EA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; CE0CC18B222E205B001283EA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; @@ -494,6 +641,36 @@ CE0CC1D2222E506B001283EA /* MRDemoViewModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MRDemoViewModel.h; sourceTree = ""; }; CE0CC1D3222E506B001283EA /* MRDemoViewModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MRDemoViewModel.m; sourceTree = ""; }; CE0CC1D9222E5C9F001283EA /* MRRouterPublic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MRRouterPublic.h; sourceTree = ""; }; + E323B11624E144270092BD40 /* GYYHealthTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GYYHealthTableViewCell.m; sourceTree = ""; }; + E323B11824E144390092BD40 /* GYYHealthTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GYYHealthTableViewCell.h; sourceTree = ""; }; + E323B11924E144440092BD40 /* GYYRunTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GYYRunTableViewCell.h; sourceTree = ""; }; + E323B11A24E1444C0092BD40 /* GYYRunTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GYYRunTableViewCell.m; sourceTree = ""; }; + E323B11C24E144680092BD40 /* GYYHealthManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GYYHealthManager.m; sourceTree = ""; }; + E323B11E24E1446D0092BD40 /* GYYHealthManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GYYHealthManager.h; sourceTree = ""; }; + E323B11F24E144890092BD40 /* GYYRunModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GYYRunModel.m; sourceTree = ""; }; + E323B12124E1448F0092BD40 /* GYYRunModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GYYRunModel.h; sourceTree = ""; }; + E34D9E2024E981A800906BAD /* GYYRankHeaderMainView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GYYRankHeaderMainView.h; sourceTree = ""; }; + E34D9E2124E981A800906BAD /* GYYRankHeaderMainView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GYYRankHeaderMainView.m; sourceTree = ""; }; + E34D9E2324E981D400906BAD /* GYYRankTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GYYRankTableViewCell.h; sourceTree = ""; }; + E34D9E2424E981D400906BAD /* GYYRankTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GYYRankTableViewCell.m; sourceTree = ""; }; + E34D9E2624E981F000906BAD /* GYYRankModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GYYRankModel.m; sourceTree = ""; }; + E34D9E2724E981F000906BAD /* GYYRankModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GYYRankModel.h; sourceTree = ""; }; + E3F60FD824F13049001F42B1 /* GYYRankChildViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GYYRankChildViewController.h; sourceTree = ""; }; + E3F60FD924F13049001F42B1 /* GYYRankChildViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GYYRankChildViewController.m; sourceTree = ""; }; + E3F60FDB24F13057001F42B1 /* GYYRankUnitViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GYYRankUnitViewController.m; sourceTree = ""; }; + E3F60FDD24F13057001F42B1 /* GYYRankUnitViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GYYRankUnitViewController.h; sourceTree = ""; }; + E3F60FE324F14CE8001F42B1 /* TYPagerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYPagerController.m; sourceTree = ""; }; + E3F60FE424F14CE8001F42B1 /* TYPagerViewLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYPagerViewLayout.m; sourceTree = ""; }; + E3F60FE624F14CE8001F42B1 /* TYTabPagerBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYTabPagerBar.m; sourceTree = ""; }; + E3F60FE724F14CE8001F42B1 /* TYTabPagerBarLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYTabPagerBarLayout.m; sourceTree = ""; }; + E3F60FE824F14CE8001F42B1 /* TYTabPagerBarCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYTabPagerBarCell.h; sourceTree = ""; }; + E3F60FE924F14CE8001F42B1 /* TYTabPagerBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYTabPagerBar.h; sourceTree = ""; }; + E3F60FEA24F14CE8001F42B1 /* TYTabPagerBarLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYTabPagerBarLayout.h; sourceTree = ""; }; + E3F60FEB24F14CE8001F42B1 /* TYTabPagerBarCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYTabPagerBarCell.m; sourceTree = ""; }; + E3F60FEC24F14CE8001F42B1 /* TYPagerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYPagerView.m; sourceTree = ""; }; + E3F60FED24F14CE8001F42B1 /* TYPagerViewLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYPagerViewLayout.h; sourceTree = ""; }; + E3F60FEE24F14CE8001F42B1 /* TYPagerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYPagerController.h; sourceTree = ""; }; + E3F60FEF24F14CE8001F42B1 /* TYPagerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYPagerView.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -501,6 +678,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 182C88B5253151A20007F0D9 /* ExternalAccessory.framework in Frameworks */, + 182C88B02531518E0007F0D9 /* libz.tbd in Frameworks */, + 182C88AB253151830007F0D9 /* libc++.tbd in Frameworks */, + 182C88A9253151730007F0D9 /* CoreTelephony.framework in Frameworks */, 2FF4B25422845E3B00779B7B /* Photos.framework in Frameworks */, 2FF4B25222845E3300779B7B /* AVFoundation.framework in Frameworks */, 2F60AB48227C934A00109420 /* CoreMotion.framework in Frameworks */, @@ -527,6 +708,36 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 182C88CA25329A410007F0D9 /* Tool */ = { + isa = PBXGroup; + children = ( + 182C88CB25329A620007F0D9 /* MGDTimeTool.h */, + 182C88CC25329A620007F0D9 /* MGDTimeTool.m */, + 182C88D425329AD90007F0D9 /* MGDDataTool.h */, + 182C88D525329AD90007F0D9 /* MGDDataTool.m */, + 182C88DA25329B100007F0D9 /* MGDRefreshTool.h */, + 182C88DB25329B100007F0D9 /* MGDRefreshTool.m */, + ); + path = Tool; + sourceTree = ""; + }; + 18CD285824C5B1B70093D396 /* MRTabBar */ = { + isa = PBXGroup; + children = ( + 18CD285A24C5B1B70093D396 /* MRTabBarController.h */, + 18CD285D24C5B1B70093D396 /* MRTabBarController.m */, + 18CD285924C5B1B70093D396 /* MRTabBar.h */, + 18CD285C24C5B1B70093D396 /* MRTabBar.m */, + 18CD285E24C5B1B70093D396 /* MRTabBarView.h */, + 18CD285B24C5B1B70093D396 /* MRTabBarView.m */, + 185510C624F02405009D5026 /* MGDTabBar.h */, + 185510C724F02405009D5026 /* MGDTabBar.m */, + 185510C924F0241E009D5026 /* MGDTabBarViewController.h */, + 185510CA24F0241E009D5026 /* MGDTabBarViewController.m */, + ); + path = MRTabBar; + sourceTree = ""; + }; 1B011DB0C0CCA19896847627 /* Pods */ = { isa = PBXGroup; children = ( @@ -550,6 +761,11 @@ 2B186BF3715610DC086E3283 /* Frameworks */ = { isa = PBXGroup; children = ( + 182C88B9253151ED0007F0D9 /* JavaScriptCore.framework */, + 182C88B4253151A20007F0D9 /* ExternalAccessory.framework */, + 182C88AF2531518E0007F0D9 /* libz.tbd */, + 182C88AA253151820007F0D9 /* libc++.tbd */, + 182C88A8253151730007F0D9 /* CoreTelephony.framework */, 2FF4B25322845E3B00779B7B /* Photos.framework */, 2FF4B25122845E3300779B7B /* AVFoundation.framework */, 2F60AB47227C934900109420 /* CoreMotion.framework */, @@ -640,6 +856,17 @@ children = ( 2F0E8167225F4B3400D5E511 /* ZYLPersonalViewController.h */, 2F0E8168225F4B3400D5E511 /* ZYLPersonalViewController.m */, + 1A16B99124EED4AA00EAD884 /* AboutViewController.h */, + 1A16B99224EED4AA00EAD884 /* AboutViewController.m */, + 1A16B99724EED4CB00EAD884 /* SportSettingViewController.xib */, + 1A16B99424EED4BA00EAD884 /* SportSettingViewController.h */, + 1A16B99524EED4BA00EAD884 /* SportSettingViewController.m */, + 1A16B99B24EED4E700EAD884 /* YYZCommentViewController.h */, + 1A16B99924EED4E700EAD884 /* YYZCommentViewController.m */, + 1A16B99A24EED4E700EAD884 /* YYZTextView.xib */, + 1A16B99C24EED4E700EAD884 /* YYZTextViewController.h */, + 1A16B99D24EED4E700EAD884 /* YYZTextViewController.m */, + 1A16B99E24EED4E700EAD884 /* YYZTextViewController.xib */, ); name = ViewController; sourceTree = ""; @@ -647,68 +874,45 @@ 2F14BF86226AE5A800CCA2B8 /* MRRunning */ = { isa = PBXGroup; children = ( + B80EA16F24EA762400915445 /* resource */, + B8ACCD9824D4330600D9F0D4 /* Tool */, + B84F257D24D16CD600EB8FB7 /* Time */, 2F14BF8A226AE5E400CCA2B8 /* ViewController */, - 2F14BF89226AE5DA00CCA2B8 /* View */, + B8D9637F24E9B3190035CF1C /* Views */, 2F14BF88226AE5CD00CCA2B8 /* Model */, - 2F14BF87226AE5BE00CCA2B8 /* ViewModel */, ); path = MRRunning; sourceTree = ""; }; - 2F14BF87226AE5BE00CCA2B8 /* ViewModel */ = { - isa = PBXGroup; - children = ( - 2F60AB41227C816400109420 /* ZYLUptateRunningData.h */, - 2F60AB42227C816400109420 /* ZYLUptateRunningData.m */, - 2F60AB44227C858C00109420 /* ZYLTimeStamp.h */, - 2F60AB45227C858C00109420 /* ZYLTimeStamp.m */, - 2F60AB49227C939C00109420 /* ZYLSteps.h */, - 2F60AB4A227C939C00109420 /* ZYLSteps.m */, - 2F60AB4C227C9A1200109420 /* ZYLUpdateData.h */, - 2F60AB4D227C9A1200109420 /* ZYLUpdateData.m */, - 2FB21106227D77D0000D5A2E /* ZYLMD5Encrypt.h */, - 2FB21107227D77D0000D5A2E /* ZYLMD5Encrypt.m */, - 2FB2110922806711000D5A2E /* ZYLRecordTimeString.h */, - 2FB2110A22806711000D5A2E /* ZYLRecordTimeString.m */, - 2F495E1B2281BD99003DD714 /* ZYLPolling.h */, - 2F495E1C2281BD99003DD714 /* ZYLPolling.m */, - ); - name = ViewModel; - sourceTree = ""; - }; 2F14BF88226AE5CD00CCA2B8 /* Model */ = { isa = PBXGroup; children = ( + 187C812F24D037CE0040A78E /* MGDSharePlatform.h */, + 187C812E24D037CE0040A78E /* MGDSharePlatform.m */, + 187C812A24D037860040A78E /* MGDShareModel.h */, + 187C812C24D037B30040A78E /* MGDShareModel.m */, + B8BDEE8D24C7F8C20013293B /* RunLocationModel.h */, + B8BDEE8E24C7F8C20013293B /* RunLocationModel.m */, + B840E7142562A41D006E8F77 /* StepModel.h */, + B840E7152562A41D006E8F77 /* StepModel.m */, + B840E71A2562A937006E8F77 /* StepManager.h */, + B840E71B2562A937006E8F77 /* StepManager.m */, ); name = Model; sourceTree = ""; }; - 2F14BF89226AE5DA00CCA2B8 /* View */ = { - isa = PBXGroup; - children = ( - 2F60AB3E227C7E5300109420 /* MRAlertView.h */, - 2F60AB3F227C7E5300109420 /* MRAlertView.m */, - 2F6DF0C9227B34A400BA6099 /* MRRunningLabel.h */, - 2F6DF0CA227B34A400BA6099 /* MRRunningLabel.m */, - 2F6DF0CB227B34A400BA6099 /* MRStopBtu.h */, - 2F6DF0C8227B34A400BA6099 /* MRStopBtu.m */, - 2F6DF0C5227B349D00BA6099 /* MRPauseAndResumeBtu.h */, - 2F6DF0C6227B349D00BA6099 /* MRPauseAndResumeBtu.m */, - 2F6DF0BD227B300800BA6099 /* ZYLRunningTabView.h */, - 2F6DF0BE227B300800BA6099 /* ZYLRunningTabView.m */, - 2F6DF0C0227B301B00BA6099 /* ZYLRunningRecordView.h */, - 2F6DF0C1227B301B00BA6099 /* ZYLRunningRecordView.m */, - 2F27F57A243CB0F900315D61 /* ZYLCountdownView.h */, - 2F27F57B243CB0F900315D61 /* ZYLCountdownView.m */, - ); - name = View; - sourceTree = ""; - }; 2F14BF8A226AE5E400CCA2B8 /* ViewController */ = { isa = PBXGroup; children = ( 2F6DF0B6227B2E2700BA6099 /* ZYLRunningViewController.h */, 2F6DF0B7227B2E2700BA6099 /* ZYLRunningViewController.m */, + B8D9633324E9B2C90035CF1C /* RunMainPageCV.h */, + B8D9633424E9B2CA0035CF1C /* RunMainPageCV.m */, + B8D9633224E9B2C80035CF1C /* Impact.ttf */, + B8D9633724E9B2CC0035CF1C /* MGDDataViewController.h */, + B8D9633824E9B2CD0035CF1C /* MGDDataViewController.m */, + B8D9633624E9B2CB0035CF1C /* MGDCellDataViewController.h */, + B8D9633524E9B2CB0035CF1C /* MGDCellDataViewController.m */, ); name = ViewController; sourceTree = ""; @@ -872,19 +1076,6 @@ name = Controller; sourceTree = ""; }; - 2F5A1B522245DFB00014B249 /* MRTabBar */ = { - isa = PBXGroup; - children = ( - 2F5A1B65224610580014B249 /* MRTabBarController.h */, - 2F5A1B66224610580014B249 /* MRTabBarController.m */, - 2F495E5E2282FA90003DD714 /* MRTabBar.h */, - 2F495E5F2282FA90003DD714 /* MRTabBar.m */, - 2F5A1B5F2245FCF70014B249 /* MRTabBarView.h */, - 2F5A1B602245FCF70014B249 /* MRTabBarView.m */, - ); - path = MRTabBar; - sourceTree = ""; - }; 2F5A1B68224644470014B249 /* MRMainView */ = { isa = PBXGroup; children = ( @@ -899,6 +1090,8 @@ 2F5A1B6C224646790014B249 /* Controller */ = { isa = PBXGroup; children = ( + E323B11E24E1446D0092BD40 /* GYYHealthManager.h */, + E323B11C24E144680092BD40 /* GYYHealthManager.m */, 2F5A1B692246451F0014B249 /* ZYLMainViewController.h */, 2F5A1B6A2246451F0014B249 /* ZYLMainViewController.m */, ); @@ -908,6 +1101,8 @@ 2F5A1B6D2246468E0014B249 /* Model */ = { isa = PBXGroup; children = ( + E323B12124E1448F0092BD40 /* GYYRunModel.h */, + E323B11F24E144890092BD40 /* GYYRunModel.m */, 2F14BF8B226AE62800CCA2B8 /* ZYLHomePageModel.h */, 2F14BF8C226AE62800CCA2B8 /* ZYLHomePageModel.m */, 2F495E582282E509003DD714 /* ZYLRunningRecordModel.h */, @@ -919,6 +1114,10 @@ 2F5A1B6E2246469B0014B249 /* View */ = { isa = PBXGroup; children = ( + E323B11A24E1444C0092BD40 /* GYYRunTableViewCell.m */, + E323B11924E144440092BD40 /* GYYRunTableViewCell.h */, + E323B11824E144390092BD40 /* GYYHealthTableViewCell.h */, + E323B11624E144270092BD40 /* GYYHealthTableViewCell.m */, 2FF3BB08238D48F400DB9051 /* oldVIew */, 2FF3BB0C238D4AFB00DB9051 /* ZYLMediumChineseLabel.h */, 2FF3BB0D238D4AFB00DB9051 /* ZYLMediumChineseLabel.m */, @@ -1044,6 +1243,7 @@ 2FD8E783224F4FF3003EC09E /* MRRankView */ = { isa = PBXGroup; children = ( + E3F60FE224F14CE8001F42B1 /* TYPagerController */, 2FD8E787224F5033003EC09E /* ViewModel */, 2FD8E786224F5026003EC09E /* Controller */, 2FD8E785224F501C003EC09E /* Model */, @@ -1055,6 +1255,10 @@ 2FD8E784224F500F003EC09E /* View */ = { isa = PBXGroup; children = ( + E34D9E2324E981D400906BAD /* GYYRankTableViewCell.h */, + E34D9E2424E981D400906BAD /* GYYRankTableViewCell.m */, + E34D9E2024E981A800906BAD /* GYYRankHeaderMainView.h */, + E34D9E2124E981A800906BAD /* GYYRankHeaderMainView.m */, 2FF3BB30238EB51100DB9051 /* old */, 2FF3BB31238EB57900DB9051 /* ZYLSelfRankCell.h */, 2FF3BB32238EB57900DB9051 /* ZYLSelfRankCell.m */, @@ -1075,6 +1279,8 @@ 2FD8E785224F501C003EC09E /* Model */ = { isa = PBXGroup; children = ( + E34D9E2724E981F000906BAD /* GYYRankModel.h */, + E34D9E2624E981F000906BAD /* GYYRankModel.m */, 2F0E816A225F745F00D5E511 /* ZYLClassRankModel.h */, 2F0E816B225F745F00D5E511 /* ZYLClassRankModel.m */, 2F0E816D225F748800D5E511 /* ZYLStudentRankModel.h */, @@ -1090,6 +1296,10 @@ 2FD8E786224F5026003EC09E /* Controller */ = { isa = PBXGroup; children = ( + E3F60FDD24F13057001F42B1 /* GYYRankUnitViewController.h */, + E3F60FDB24F13057001F42B1 /* GYYRankUnitViewController.m */, + E3F60FD824F13049001F42B1 /* GYYRankChildViewController.h */, + E3F60FD924F13049001F42B1 /* GYYRankChildViewController.m */, 2F4044D723954D7F00EE93EC /* old */, 2F14F88C2390BD6000356CDF /* ZYLRankViewController.h */, 2F14F88D2390BD6000356CDF /* ZYLRankViewController.m */, @@ -1157,6 +1367,141 @@ name = old; sourceTree = ""; }; + B80EA16F24EA762400915445 /* resource */ = { + isa = PBXGroup; + children = ( + B8EA9A1A2508EDD8009290FE /* style_extra.data */, + B8EA9A1B2508EDD9009290FE /* style.data */, + B8FA9FB5250BABDB009457AF /* style2.data */, + B8FA9FB7250BABE3009457AF /* style_extra2.data */, + B8FAA01C250F9027009457AF /* 结束白.svg */, + B8FAA021250F99EA009457AF /* 继续白.svg */, + B8FAA023250F9B44009457AF /* 暂停白.svg */, + B8FAA025250F9B4F009457AF /* 暂停黑.svg */, + B8FAA027250F9F9C009457AF /* 锁定白.svg */, + B8FAA029250F9FA4009457AF /* 锁定黑.svg */, + B8FAA02B250FA3E2009457AF /* 锁定灰.svg */, + ); + name = resource; + sourceTree = ""; + }; + B84F257D24D16CD600EB8FB7 /* Time */ = { + isa = PBXGroup; + children = ( + B897C29724EE85B800E230EE /* RecordtimeString.h */, + B897C29824EE85B900E230EE /* RecordtimeString.m */, + B8D9633024E9B2AE0035CF1C /* ZYLTimeStamp.h */, + B8D9632F24E9B2AD0035CF1C /* ZYLTimeStamp.m */, + ); + name = Time; + sourceTree = ""; + }; + B8ACCD9824D4330600D9F0D4 /* Tool */ = { + isa = PBXGroup; + children = ( + B8FAA01F250F979D009457AF /* UIImage+SVGTool.h */, + B8FAA01E250F979C009457AF /* UIImage+SVGTool.m */, + B8ACCD9924D4331B00D9F0D4 /* MASmoothPathTool.h */, + B8ACCD9A24D4331B00D9F0D4 /* MASmoothPathTool.m */, + ); + name = Tool; + sourceTree = ""; + }; + B8D9637F24E9B3190035CF1C /* Views */ = { + isa = PBXGroup; + children = ( + B8D9638524E9B3350035CF1C /* RunningMainPageView.h */, + B8D9638024E9B3320035CF1C /* RunningMainPageView.m */, + B8D9638924E9B3370035CF1C /* LongPressView.h */, + B8D9638324E9B3340035CF1C /* LongPressView.m */, + B8D9638824E9B3370035CF1C /* MGDButtonsView.h */, + B8D9639124E9B33C0035CF1C /* MGDButtonsView.m */, + B8D9638F24E9B33B0035CF1C /* MGDDataView.h */, + B8D9638D24E9B33A0035CF1C /* MGDDataView.m */, + B8D9639224E9B33C0035CF1C /* MGDOverView.h */, + B8D9638A24E9B3380035CF1C /* MGDOverView.m */, + B8D9638224E9B3340035CF1C /* MGDShareView.h */, + B8D9639324E9B33D0035CF1C /* MGDShareView.m */, + B8D9638C24E9B3390035CF1C /* RunMainBtn.h */, + B8D9638E24E9B33A0035CF1C /* RunMainBtn.m */, + B8D9638B24E9B3380035CF1C /* SZHAlertView.h */, + B8D9638124E9B3330035CF1C /* SZHAlertView.m */, + B8D9638624E9B3360035CF1C /* SZHChart.h */, + B8D9638724E9B3360035CF1C /* SZHChart.m */, + B8D9638424E9B3350035CF1C /* SZHWaveChart.h */, + B8D9639024E9B33B0035CF1C /* SZHWaveChart.m */, + 184DE3CB251C442D00CFB058 /* MGDShareDataView.h */, + 184DE3CC251C442D00CFB058 /* MGDShareDataView.m */, + ); + name = Views; + sourceTree = ""; + }; + B8FE2AD524EBA434009DC23D /* MRMineView */ = { + isa = PBXGroup; + children = ( + 182C88CA25329A410007F0D9 /* Tool */, + B8FE2AD624EBA434009DC23D /* YBPopupMenu */, + B8FE2ADD24EBA434009DC23D /* Model */, + B8FE2AE224EBA434009DC23D /* View */, + B8FE2AF124EBA434009DC23D /* ViewController */, + ); + path = MRMineView; + sourceTree = ""; + }; + B8FE2AD624EBA434009DC23D /* YBPopupMenu */ = { + isa = PBXGroup; + children = ( + B8FE2AD724EBA434009DC23D /* YBPopupMenu.h */, + B8FE2AD824EBA434009DC23D /* YBRectConst.m */, + B8FE2AD924EBA434009DC23D /* YBPopupMenuPath.m */, + B8FE2ADA24EBA434009DC23D /* YBRectConst.h */, + B8FE2ADB24EBA434009DC23D /* YBPopupMenu.m */, + B8FE2ADC24EBA434009DC23D /* YBPopupMenuPath.h */, + ); + path = YBPopupMenu; + sourceTree = ""; + }; + B8FE2ADD24EBA434009DC23D /* Model */ = { + isa = PBXGroup; + children = ( + B8FE2AE024EBA434009DC23D /* MGDUserData.h */, + B8FE2ADE24EBA434009DC23D /* MGDUserData.m */, + B8FE2ADF24EBA434009DC23D /* MGDSportData.h */, + B8FE2AE124EBA434009DC23D /* MGDSportData.m */, + ); + path = Model; + sourceTree = ""; + }; + B8FE2AE224EBA434009DC23D /* View */ = { + isa = PBXGroup; + children = ( + B8FE2AE924EBA434009DC23D /* MGDTopView.h */, + B8FE2AEC24EBA434009DC23D /* MGDTopView.m */, + B8FE2AF024EBA434009DC23D /* MGDBaseInfoView.h */, + B8FE2AE524EBA434009DC23D /* MGDBaseInfoView.m */, + B8FE2AE824EBA434009DC23D /* MGDMiddleView.h */, + B8FE2AED24EBA434009DC23D /* MGDMiddleView.m */, + B8FE2AEF24EBA434009DC23D /* MGDSportTableView.h */, + B8FE2AE624EBA434009DC23D /* MGDSportTableView.m */, + B8FE2AE724EBA434009DC23D /* MGDSportTableViewCell.h */, + B8FE2AEE24EBA434009DC23D /* MGDSportTableViewCell.m */, + B8FE2AE424EBA434009DC23D /* MGDColumnChartView.h */, + B8FE2AEA24EBA434009DC23D /* MGDColumnChartView.m */, + ); + path = View; + sourceTree = ""; + }; + B8FE2AF124EBA434009DC23D /* ViewController */ = { + isa = PBXGroup; + children = ( + B8FE2AF424EBA434009DC23D /* MGDMineViewController.h */, + B8FE2AF224EBA434009DC23D /* MGDMineViewController.m */, + B8FE2AF324EBA434009DC23D /* MGDMoreViewController.h */, + B8FE2AF524EBA434009DC23D /* MGDMoreViewController.m */, + ); + path = ViewController; + sourceTree = ""; + }; CE0CC170222E2059001283EA = { isa = PBXGroup; children = ( @@ -1182,24 +1527,25 @@ CE0CC17B222E2059001283EA /* MRMobileRun */ = { isa = PBXGroup; children = ( + 18CD285824C5B1B70093D396 /* MRTabBar */, 2F054302243B348600A11C17 /* MRMobileRun.entitlements */, 2F5A1BA022468A910014B249 /* Base */, - 2F5A1B522245DFB00014B249 /* MRTabBar */, 2832369F231D4531003F92BD /* MRRunningHistoryTrackView */, 2F5A1B68224644470014B249 /* MRMainView */, 2FD8E783224F4FF3003EC09E /* MRRankView */, 2F0E8162225F451D00D5E511 /* MRSettinglView */, 2F14BF86226AE5A800CCA2B8 /* MRRunning */, 2F495E1F2282BD34003DD714 /* MRLogin */, + B8FE2AD524EBA434009DC23D /* MRMineView */, CE0CC1C0222E4F7E001283EA /* MVVMDemoModule */, 2F495E3B2282BF0F003DD714 /* MRInviteView */, CE0CC1D8222E5C61001283EA /* MRRouterManager */, CE0CC1AE222E22FB001283EA /* MRMainUIModule */, CE0CC17C222E2059001283EA /* AppDelegate.h */, CE0CC17D222E2059001283EA /* AppDelegate.m */, - CE0CC185222E205B001283EA /* Assets.xcassets */, CE0CC187222E205B001283EA /* LaunchScreen.storyboard */, - 2F5A1B7B224662B00014B249 /* PrefixHeader.pch */, + 18D838D124F4AAEF0074D7F4 /* Assets.xcassets */, + B8D9639E24E9B4360035CF1C /* PrefixHeader.pch */, CE0CC18A222E205B001283EA /* Info.plist */, CE0CC18B222E205B001283EA /* main.m */, ); @@ -1300,6 +1646,33 @@ path = MRRouterManager; sourceTree = ""; }; + E3F60FE224F14CE8001F42B1 /* TYPagerController */ = { + isa = PBXGroup; + children = ( + E3F60FE324F14CE8001F42B1 /* TYPagerController.m */, + E3F60FE424F14CE8001F42B1 /* TYPagerViewLayout.m */, + E3F60FE524F14CE8001F42B1 /* TabPager */, + E3F60FEC24F14CE8001F42B1 /* TYPagerView.m */, + E3F60FED24F14CE8001F42B1 /* TYPagerViewLayout.h */, + E3F60FEE24F14CE8001F42B1 /* TYPagerController.h */, + E3F60FEF24F14CE8001F42B1 /* TYPagerView.h */, + ); + path = TYPagerController; + sourceTree = ""; + }; + E3F60FE524F14CE8001F42B1 /* TabPager */ = { + isa = PBXGroup; + children = ( + E3F60FE624F14CE8001F42B1 /* TYTabPagerBar.m */, + E3F60FE724F14CE8001F42B1 /* TYTabPagerBarLayout.m */, + E3F60FE824F14CE8001F42B1 /* TYTabPagerBarCell.h */, + E3F60FE924F14CE8001F42B1 /* TYTabPagerBar.h */, + E3F60FEA24F14CE8001F42B1 /* TYTabPagerBarLayout.h */, + E3F60FEB24F14CE8001F42B1 /* TYTabPagerBarCell.m */, + ); + path = TabPager; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1416,10 +1789,25 @@ 2F0E814E225F309B00D5E511 /* XIGInviteTableViewCell.xib in Resources */, 2F36BD022240CF4B00C1D8FC /* WeProgressCircle.xib in Resources */, CE0CC189222E205B001283EA /* LaunchScreen.storyboard in Resources */, + B8FA9FB6250BABDB009457AF /* style2.data in Resources */, + 1A16B9A224EED4E700EAD884 /* YYZTextViewController.xib in Resources */, + B8FAA028250F9F9C009457AF /* 锁定白.svg in Resources */, + B8FAA022250F99EA009457AF /* 继续白.svg in Resources */, + B8EA9A1C2508EDD9009290FE /* style_extra.data in Resources */, + B8FAA01D250F9027009457AF /* 结束白.svg in Resources */, + B8D9633924E9B2CD0035CF1C /* Impact.ttf in Resources */, 2F0E8144225F309B00D5E511 /* XIGClassTableViewCell.xib in Resources */, + 1A16B99824EED4CB00EAD884 /* SportSettingViewController.xib in Resources */, + B8FAA02A250F9FA4009457AF /* 锁定黑.svg in Resources */, + 1A16B9A024EED4E700EAD884 /* YYZTextView.xib in Resources */, 2F36BD032240CF4B00C1D8FC /* WeProgressCircle.png in Resources */, - CE0CC186222E205B001283EA /* Assets.xcassets in Resources */, + B8EA9A1D2508EDD9009290FE /* style.data in Resources */, + 18D838D224F4AAEF0074D7F4 /* Assets.xcassets in Resources */, + B8FAA026250F9B4F009457AF /* 暂停黑.svg in Resources */, 2F0E8153225F30A400D5E511 /* XIGView.xib in Resources */, + B8FAA024250F9B44009457AF /* 暂停白.svg in Resources */, + B8FA9FB8250BABE3009457AF /* style_extra2.data in Resources */, + B8FAA02C250FA3E2009457AF /* 锁定灰.svg in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1463,19 +1851,16 @@ buildActionMask = 2147483647; files = ( ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources.sh", - "${PODS_ROOT}/AMap2DMap/MAMapKit.framework/AMap.bundle", - "${PODS_ROOT}/MJRefresh/MJRefresh/MJRefresh.bundle", + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AMap.bundle", - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MJRefresh.bundle", + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -1485,23 +1870,27 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 18CD286024C5B1B70093D396 /* MRTabBar.m in Sources */, 2F4044D62395429200EE93EC /* ZYLSegmentView.m in Sources */, + 182C88D625329AD90007F0D9 /* MGDDataTool.m in Sources */, 2F5A1B84224671920014B249 /* ZYLBackgroundView.m in Sources */, 2F5CBE98225F00A000813943 /* AES128Util.m in Sources */, 2F495E2B2282BE6F003DD714 /* MRLoginViewController.m in Sources */, + E323B11724E144270092BD40 /* GYYHealthTableViewCell.m in Sources */, + B8D9639424E9B33D0035CF1C /* RunningMainPageView.m in Sources */, + B8BDEE8F24C7F8C20013293B /* RunLocationModel.m in Sources */, 2F14F88E2390BD6000356CDF /* ZYLRankViewController.m in Sources */, - 2F495E1D2281BD99003DD714 /* ZYLPolling.m in Sources */, 2FF3BB20238D4C1700DB9051 /* ZYLGraybar.m in Sources */, + B8FE2AF924EBA434009DC23D /* MGDUserData.m in Sources */, 2F9673BD22F026E100BC6099 /* AESCipher.m in Sources */, - 2F6DF0C7227B349D00BA6099 /* MRPauseAndResumeBtu.m in Sources */, 2F5A1B72224659BB0014B249 /* ZYLArrowBtn.m in Sources */, 2F0E819322608CB800D5E511 /* ZYLPhotoSelectedVIew.m in Sources */, 2F5A1BA922468BC80014B249 /* MRNumLabel.m in Sources */, CE0CC1BB222E4D37001283EA /* MRHomeViewController.m in Sources */, + B8D9639D24E9B33D0035CF1C /* MGDShareView.m in Sources */, 28A5EDFE22DE927A00CA6B6A /* LJJInviteOk.m in Sources */, 2F7ADC80237C2A8D00FE9461 /* ZYLWelcomeLabel.m in Sources */, - 2F6DF0C2227B301B00BA6099 /* ZYLRunningRecordView.m in Sources */, - 2FB21108227D77D0000D5A2E /* ZYLMD5Encrypt.m in Sources */, + E3F60FF124F14CE8001F42B1 /* TYPagerViewLayout.m in Sources */, 2FF3BB2C238D6B9900DB9051 /* ZYLHostView.m in Sources */, 2F0E816F225F748800D5E511 /* ZYLStudentRankModel.m in Sources */, 2F495E512282BFFA003DD714 /* LJJInviteRunModel.m in Sources */, @@ -1511,23 +1900,35 @@ 2F7ADC7A23799ECD00FE9461 /* ZYLSettingDarkModeCell.m in Sources */, CE0CC17E222E2059001283EA /* AppDelegate.m in Sources */, 2F5A1B7E224670A90014B249 /* ZYLLeaderboardBtn.m in Sources */, - 2FB2110B22806711000D5A2E /* ZYLRecordTimeString.m in Sources */, 2F14F8942390C0DC00356CDF /* ZYLSchoolRankViewController.m in Sources */, + 18CD286124C5B1B70093D396 /* MRTabBarController.m in Sources */, + B8ACCD9B24D4331B00D9F0D4 /* MASmoothPathTool.m in Sources */, 2F0E817E22605E8A00D5E511 /* ZYLRankModel.m in Sources */, + E3F60FDA24F13049001F42B1 /* GYYRankChildViewController.m in Sources */, 2F5A1B7822465B1D0014B249 /* ZYLTitleLabel.m in Sources */, 2F0E818D22608C3F00D5E511 /* ZYLNicknameTextField.m in Sources */, + B8FAA020250F979D009457AF /* UIImage+SVGTool.m in Sources */, + E3F60FF324F14CE8001F42B1 /* TYTabPagerBarLayout.m in Sources */, + 18CD285F24C5B1B70093D396 /* MRTabBarView.m in Sources */, + E34D9E2224E981A800906BAD /* GYYRankHeaderMainView.m in Sources */, 2F0E8148225F309B00D5E511 /* XIGClassTableViewCell.m in Sources */, 2F734CCD22676997006D8B63 /* ZYLChangeNickname.m in Sources */, 2F7ADC89237C2FDB00FE9461 /* ZYLLoginView.m in Sources */, 2F5A1B9922468A890014B249 /* NSString+We.m in Sources */, + B8FE2B0324EBA434009DC23D /* MGDMoreViewController.m in Sources */, 2FF3BB14238D4B9900DB9051 /* ZYLNoticeWhiteLabel.m in Sources */, 2F0E8178225F774800D5E511 /* ZYLStudentRankViewModel.m in Sources */, - 2F5A1B612245FCF70014B249 /* MRTabBarView.m in Sources */, + B8FE2AF824EBA434009DC23D /* YBPopupMenu.m in Sources */, 2FF3BB11238D4B1A00DB9051 /* ZYLNumLabel.m in Sources */, CE0CC1D4222E506B001283EA /* MRDemoViewModel.m in Sources */, 2FF3BB0B238D499600DB9051 /* ZYLPlateChinieseLabel.m in Sources */, CE0CC1BF222E4F73001283EA /* MRRouterManager.m in Sources */, + B8D9639B24E9B33D0035CF1C /* SZHWaveChart.m in Sources */, 28ED985F22F14431003AA58D /* LJJSearchedVC.m in Sources */, + B840E7162562A41D006E8F77 /* StepModel.m in Sources */, + 187C813024D037CE0040A78E /* MGDSharePlatform.m in Sources */, + E3F60FDE24F13057001F42B1 /* GYYRankUnitViewController.m in Sources */, + 1A16B99324EED4AA00EAD884 /* AboutViewController.m in Sources */, 2FF3BB26238D4DB200DB9051 /* ZYLUnitLabel.m in Sources */, 2F0E818422608BD600D5E511 /* ZYLPersonalBackGroud.m in Sources */, 2F0E8145225F309B00D5E511 /* XIGSegementView.m in Sources */, @@ -1536,6 +1937,8 @@ 2F7ADC6B237973CF00FE9461 /* ZYLSettingBackgound.m in Sources */, 2FBE8938230C446F0042AB0D /* ZYLNoticeBanner.m in Sources */, 2F495E542282C064003DD714 /* LJJInviteRunView.m in Sources */, + 187C812D24D037B30040A78E /* MGDShareModel.m in Sources */, + B840E71C2562A937006E8F77 /* StepManager.m in Sources */, 2F0E817B225F775600D5E511 /* ZYLInvitationRankViewModel.m in Sources */, 2F3ACABD230C41E2008D51E5 /* ZYLStartRunningButton.m in Sources */, 2F5A1B87224688280014B249 /* ZYLMainView.m in Sources */, @@ -1546,34 +1949,46 @@ 2F5A1B81224671140014B249 /* ZYLRunningRecordBtn.m in Sources */, 2F495E4B2282BFEB003DD714 /* LJJInviteViewModel.m in Sources */, 2F495E372282BEAD003DD714 /* MRLoginBtu.m in Sources */, + B8FE2AF724EBA434009DC23D /* YBPopupMenuPath.m in Sources */, + E3F60FF024F14CE8001F42B1 /* TYPagerController.m in Sources */, 2F5CBE97225F00A000813943 /* GTMBase64.m in Sources */, 28EBE4EC22F07A70001B4293 /* LJJSearchedView.m in Sources */, + B8FE2AFA24EBA434009DC23D /* MGDSportData.m in Sources */, + E34D9E2524E981D400906BAD /* GYYRankTableViewCell.m in Sources */, 2F0E814D225F309B00D5E511 /* XIGRankViewViewController.m in Sources */, + B8D9633C24E9B2CD0035CF1C /* MGDDataViewController.m in Sources */, 2F14F89A2391025000356CDF /* ZYLSliderView.m in Sources */, + B8FE2AFB24EBA434009DC23D /* MGDBaseInfoView.m in Sources */, 2F0E8146225F309B00D5E511 /* XIGInviteTableViewCell.m in Sources */, 2F5A1B9D22468A890014B249 /* UILabel+We.m in Sources */, - 2F6DF0CD227B34A400BA6099 /* MRRunningLabel.m in Sources */, + 182C88CD25329A620007F0D9 /* MGDTimeTool.m in Sources */, 2F0E8147225F309B00D5E511 /* XIGClassRankViewController.m in Sources */, 2F0E814A225F309B00D5E511 /* XIGClass.m in Sources */, + 1A16B99624EED4BA00EAD884 /* SportSettingViewController.m in Sources */, 2FF3BB17238D4BB400DB9051 /* ZYLGrayNoticeLabel.m in Sources */, 2F495E392282BEB3003DD714 /* MRLoginView.m in Sources */, - 2F495E602282FA90003DD714 /* MRTabBar.m in Sources */, 2F495E4E2282BFF3003DD714 /* LJJInviteSearchResultView.m in Sources */, + B8D9639524E9B33D0035CF1C /* SZHAlertView.m in Sources */, 2F5A1BA622468BBA0014B249 /* MRChineseLabel.m in Sources */, + B8FE2B0024EBA434009DC23D /* MGDMiddleView.m in Sources */, 2F495E452282BFD0003DD714 /* LJJInviteRunVCViewController.m in Sources */, 2FF3BB1D238D4C0B00DB9051 /* ZYLRedBar.m in Sources */, 2F9CB6DF239BD8F60003C09D /* ZYLRewriteTextField.m in Sources */, - 2F6DF0BF227B300800BA6099 /* ZYLRunningTabView.m in Sources */, + E3F60FF524F14CE8001F42B1 /* TYPagerView.m in Sources */, 2F14F8912390C0CC00356CDF /* ZYLAcademyRankViewController.m in Sources */, + B8D9639624E9B33D0035CF1C /* LongPressView.m in Sources */, 2F14BF8D226AE62800CCA2B8 /* ZYLHomePageModel.m in Sources */, 2F734CC422675CC6006D8B63 /* ZYLPersonalModel.m in Sources */, + E323B11B24E1444C0092BD40 /* GYYRunTableViewCell.m in Sources */, 2F495E322282BE9F003DD714 /* MRLoginTextField.m in Sources */, 2F27F579243B5BDB00315D61 /* ZYLHealthManager.m in Sources */, + B8D9639A24E9B33D0035CF1C /* RunMainBtn.m in Sources */, 280B3B7F228BA04200FDD695 /* LJJInviteSearchView.m in Sources */, 2F495E2E2282BE8A003DD714 /* MRLoginModel.m in Sources */, + E323B12024E144890092BD40 /* GYYRunModel.m in Sources */, + B8FE2AFC24EBA434009DC23D /* MGDSportTableView.m in Sources */, 2F14F897239100B600356CDF /* ZYLSelfRankView.m in Sources */, 2F0E819022608C9300D5E511 /* ZYLLogoutBtn.m in Sources */, - 2F60AB4B227C939D00109420 /* ZYLSteps.m in Sources */, 2F0E8175225F771700D5E511 /* ZYLClassRankViewModel.m in Sources */, 2F5A1B4D2245DAB90014B249 /* MRBaseViewController.m in Sources */, 2F5A1B7522465A250014B249 /* ZYLAvatarBtn.m in Sources */, @@ -1584,48 +1999,64 @@ 2F5A1BAC22468BD40014B249 /* MRTimeLabel.m in Sources */, 2F5A1B9E22468A890014B249 /* UIView+We.m in Sources */, 2F0E8152225F30A400D5E511 /* XIGStudentViewController.m in Sources */, - 2F6DF0CC227B34A400BA6099 /* MRStopBtu.m in Sources */, 2F0E8169225F4B3400D5E511 /* ZYLPersonalViewController.m in Sources */, 2F0E815B225F33C400D5E511 /* UIImage+Extension.m in Sources */, 28A5EDFB22DE925600CA6B6A /* LJJInviteCancel.m in Sources */, - 2F27F57C243CB0F900315D61 /* ZYLCountdownView.m in Sources */, + 1A16B9A124EED4E700EAD884 /* YYZTextViewController.m in Sources */, 2F734CCA22675EF9006D8B63 /* ZYLUploadAvatar.m in Sources */, 2F0E8172225F74A700D5E511 /* ZYLInvitationRankModel.m in Sources */, + B8FE2AFF24EBA434009DC23D /* MGDTopView.m in Sources */, CE0CC1CB222E5038001283EA /* MRDemoTableViewCell.m in Sources */, 2F495E5A2282E509003DD714 /* ZYLRunningRecordModel.m in Sources */, 2FF3BB33238EB57900DB9051 /* ZYLSelfRankCell.m in Sources */, 2F6DF0B8227B2E2700BA6099 /* ZYLRunningViewController.m in Sources */, 2F5A1B9B22468A890014B249 /* UIColor+We.m in Sources */, - 2F60AB40227C7E5300109420 /* MRAlertView.m in Sources */, 2F7ADC86237C2EB000FE9461 /* ZYLLoginButton.m in Sources */, - 2F60AB46227C858C00109420 /* ZYLTimeStamp.m in Sources */, 2FF3BB3C238EB64D00DB9051 /* ZYLRankTableViewCell.m in Sources */, 2FF3BB0E238D4AFB00DB9051 /* ZYLMediumChineseLabel.m in Sources */, 2F495E482282BFDD003DD714 /* LJJInviteSearchResultViewController.m in Sources */, 2F0E8142225F309B00D5E511 /* XIGBeforeYou.m in Sources */, 2F5A1B9C22468A890014B249 /* WeKit.m in Sources */, - 2F60AB4E227C9A1200109420 /* ZYLUpdateData.m in Sources */, - 2F60AB43227C816400109420 /* ZYLUptateRunningData.m in Sources */, + B8D9633A24E9B2CD0035CF1C /* RunMainPageCV.m in Sources */, 2F0E814C225F309B00D5E511 /* XIGInviteViewController.m in Sources */, 2F0E818A22608C1300D5E511 /* ZYLSetAvatarBtn.m in Sources */, 280B3B7C228B9F9700FDD695 /* LJJInviteSearchVC.m in Sources */, 2FF3BB23238D4C5400DB9051 /* ZYLBackGroudView.m in Sources */, + E34D9E2824E981F000906BAD /* GYYRankModel.m in Sources */, 2F7ADC7723799CEE00FE9461 /* ZYLSettingNameCell.m in Sources */, CE0CC1CE222E5048001283EA /* MRDemoModel.m in Sources */, + B8FE2AFD24EBA434009DC23D /* MGDColumnChartView.m in Sources */, + B897C29924EE85B900E230EE /* RecordtimeString.m in Sources */, 2F7ADC7423799AA900FE9461 /* ZYLSettingIconCell.m in Sources */, + B8D9633124E9B2AE0035CF1C /* ZYLTimeStamp.m in Sources */, 2F5A1BA322468BA80014B249 /* MRBackBtu.m in Sources */, + 185510C824F02405009D5026 /* MGDTabBar.m in Sources */, + B8D9639824E9B33D0035CF1C /* MGDOverView.m in Sources */, 2F64924F243A031700472B57 /* ZYLGetTimeScale.m in Sources */, 2F7ADC83237C2BEB00FE9461 /* ZYLLoginField.m in Sources */, + E3F60FF224F14CE8001F42B1 /* TYTabPagerBar.m in Sources */, + E3F60FF424F14CE8001F42B1 /* TYTabPagerBarCell.m in Sources */, + B8FE2B0124EBA434009DC23D /* MGDSportTableViewCell.m in Sources */, + 184DE3CD251C442D00CFB058 /* MGDShareDataView.m in Sources */, 2889400F231E2D7B0002EDA8 /* MRRunningHistoryTrackController.m in Sources */, + 182C88DC25329B100007F0D9 /* MGDRefreshTool.m in Sources */, 2F0E818122608BB400D5E511 /* ZYLPersonalInformationView.m in Sources */, + B8D9633B24E9B2CD0035CF1C /* MGDCellDataViewController.m in Sources */, 2FB2110E22807D90000D5A2E /* ZYLBackBtn.m in Sources */, 2F5A1B9A22468A890014B249 /* UIButton+We.m in Sources */, 2F7ADC712379957800FE9461 /* ZYLSettingNomalCell.m in Sources */, 2F0E816C225F745F00D5E511 /* ZYLClassRankModel.m in Sources */, + B8D9639724E9B33D0035CF1C /* SZHChart.m in Sources */, + B8FE2B0224EBA434009DC23D /* MGDMineViewController.m in Sources */, 2F36BD042240CF4B00C1D8FC /* WeProgressCircle.m in Sources */, + B8FE2AF624EBA434009DC23D /* YBRectConst.m in Sources */, + B8D9639C24E9B33D0035CF1C /* MGDButtonsView.m in Sources */, + B8D9639924E9B33D0035CF1C /* MGDDataView.m in Sources */, + E323B11D24E144680092BD40 /* GYYHealthManager.m in Sources */, 2F9CB6E2239BDA260003C09D /* ZYLConfirmButton.m in Sources */, 2F495E232282BE19003DD714 /* HttpClient.m in Sources */, - 2F5A1B67224610580014B249 /* MRTabBarController.m in Sources */, + 1A16B99F24EED4E700EAD884 /* YYZCommentViewController.m in Sources */, + 185510CB24F0241E009D5026 /* MGDTabBarViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1723,7 +2154,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -1776,7 +2207,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; @@ -1792,18 +2223,24 @@ CODE_SIGN_ENTITLEMENTS = MRMobileRun/MRMobileRun.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = XLUA47KKY5; + DEVELOPMENT_TEAM = USX8LB59D7; + EXCLUDED_ARCHS = ""; + "EXCLUDED_ARCHS[sdk=*]" = arm64; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SRCROOT)/MRMobileRun/PrefixHeader.pch"; INFOPLIST_FILE = MRMobileRun/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.rrr.MRMobileRun; + PRODUCT_BUNDLE_IDENTIFIER = "com.r.MRMobileRunyc-1"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SYSTEM_FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); TARGETED_DEVICE_FAMILY = 1; }; name = Debug; @@ -1816,18 +2253,24 @@ CODE_SIGN_ENTITLEMENTS = MRMobileRun/MRMobileRun.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = XLUA47KKY5; + DEVELOPMENT_TEAM = USX8LB59D7; + EXCLUDED_ARCHS = ""; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "$(SRCROOT)/MRMobileRun/PrefixHeader.pch"; INFOPLIST_FILE = MRMobileRun/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.rrr.MRMobileRun; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "com.r.MRMobileRunyc-1"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SYSTEM_FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); TARGETED_DEVICE_FAMILY = 1; }; name = Release; @@ -1837,6 +2280,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RT6PQ9CYD3; INFOPLIST_FILE = MRMobileRunTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1855,6 +2299,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RT6PQ9CYD3; INFOPLIST_FILE = MRMobileRunTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1872,6 +2317,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RT6PQ9CYD3; INFOPLIST_FILE = MRMobileRunUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1889,6 +2335,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RT6PQ9CYD3; INFOPLIST_FILE = MRMobileRunUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/MRMobileRun.xcodeproj/project.xcworkspace/xcuserdata/shizihan.xcuserdatad/UserInterfaceState.xcuserstate b/MRMobileRun.xcodeproj/project.xcworkspace/xcuserdata/shizihan.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..6f68337 Binary files /dev/null and b/MRMobileRun.xcodeproj/project.xcworkspace/xcuserdata/shizihan.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MRMobileRun.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/xcschememanagement.plist b/MRMobileRun.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..9f526c6 --- /dev/null +++ b/MRMobileRun.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + MRMobileRun.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/MRMobileRun.xcodeproj/xcuserdata/guoyunyao.xcuserdatad/xcschemes/xcschememanagement.plist b/MRMobileRun.xcodeproj/xcuserdata/guoyunyao.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..9f526c6 --- /dev/null +++ b/MRMobileRun.xcodeproj/xcuserdata/guoyunyao.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + MRMobileRun.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/MRMobileRun.xcodeproj/xcuserdata/shizihan.xcuserdatad/xcschemes/xcschememanagement.plist b/MRMobileRun.xcodeproj/xcuserdata/shizihan.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..9f526c6 --- /dev/null +++ b/MRMobileRun.xcodeproj/xcuserdata/shizihan.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + MRMobileRun.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/MRMobileRun.xcodeproj/xcuserdata/yyz.xcuserdatad/xcschemes/xcschememanagement.plist b/MRMobileRun.xcodeproj/xcuserdata/yyz.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..9f526c6 --- /dev/null +++ b/MRMobileRun.xcodeproj/xcuserdata/yyz.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + MRMobileRun.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/MRMobileRun.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate b/MRMobileRun.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..eeeb0c5 Binary files /dev/null and b/MRMobileRun.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MRMobileRun.xcworkspace/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/MRMobileRun.xcworkspace/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..9dc4aa6 --- /dev/null +++ b/MRMobileRun.xcworkspace/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/MRMobileRun.xcworkspace/xcuserdata/guoyunyao.xcuserdatad/UserInterfaceState.xcuserstate b/MRMobileRun.xcworkspace/xcuserdata/guoyunyao.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..65d057c Binary files /dev/null and b/MRMobileRun.xcworkspace/xcuserdata/guoyunyao.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MRMobileRun.xcworkspace/xcuserdata/guoyunyao.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/MRMobileRun.xcworkspace/xcuserdata/guoyunyao.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..32e663c --- /dev/null +++ b/MRMobileRun.xcworkspace/xcuserdata/guoyunyao.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/MRMobileRun.xcworkspace/xcuserdata/shizihan.xcuserdatad/UserInterfaceState.xcuserstate b/MRMobileRun.xcworkspace/xcuserdata/shizihan.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..81a5bba Binary files /dev/null and b/MRMobileRun.xcworkspace/xcuserdata/shizihan.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MRMobileRun.xcworkspace/xcuserdata/shizihan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/MRMobileRun.xcworkspace/xcuserdata/shizihan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..fad34ec --- /dev/null +++ b/MRMobileRun.xcworkspace/xcuserdata/shizihan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MRMobileRun.xcworkspace/xcuserdata/yyz.xcuserdatad/UserInterfaceState.xcuserstate b/MRMobileRun.xcworkspace/xcuserdata/yyz.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..cfb940f Binary files /dev/null and b/MRMobileRun.xcworkspace/xcuserdata/yyz.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MRMobileRun/.DS_Store b/MRMobileRun/.DS_Store deleted file mode 100644 index 823aa3d..0000000 Binary files a/MRMobileRun/.DS_Store and /dev/null differ diff --git a/MRMobileRun/AppDelegate.m b/MRMobileRun/AppDelegate.m index 8d4455c..333144e 100644 --- a/MRMobileRun/AppDelegate.m +++ b/MRMobileRun/AppDelegate.m @@ -10,23 +10,34 @@ #import "ZYLMainViewController.h" #import "ZYLLoginViewController.h" #import "MRLoginModel.h" +#import +#import "MGDTabBarViewController.h" #define BUGLY_APPID @"354f05b571" #define BUGLY_APPKEY @"c423889d-fa34-4de8-aa6c-8e29305d03b6" +//高德地图的key +#define MAMAP_KEY @"030a8e0b2b3c762f76c33bf8eeb6ce11" +#define NewKey @"c99a9b7d1464962d9a11a2726f83f670" +#define YCKey @"f88d0c41a8c63e93cadd7d78901ab5c0" +#define YCTestKey @"eec603f5701c69575d743998d449d1b0" //杨诚的测试用的key @interface AppDelegate () -@property (nonatomic, strong) MRTabBarController *tabBarVC; +@property (nonatomic, strong) MGDTabBarViewController *tabBarVC; @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + +// [AMapServices sharedServices].apiKey = YCKey; //将高德地图的key配置在代码中 + [AMapServices sharedServices].apiKey = YCTestKey; //杨诚的测试用的key + self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.backgroundColor = COLOR_WITH_HEX(0xFAFAFA); NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; ZYLLoginViewController *loginVC = [[ZYLLoginViewController alloc] init]; // ZYLMainViewController *mainVC = [[ZYLMainViewController alloc] init]; - MRTabBarController *tabVC = [[MRTabBarController alloc] init]; + MGDTabBarViewController *tabVC = [[MGDTabBarViewController alloc] init]; UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController: tabVC]; self.window.rootViewController = nav; if ([user valueForKey:@"password"]) { @@ -72,5 +83,8 @@ - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } +- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window { + return UIInterfaceOrientationMaskPortrait; +} @end diff --git a/MRMobileRun/Assets.xcassets.zip b/MRMobileRun/Assets.xcassets.zip new file mode 100644 index 0000000..3358a2f Binary files /dev/null and b/MRMobileRun/Assets.xcassets.zip differ diff --git a/MRMobileRun/Assets.xcassets/.DS_Store b/MRMobileRun/Assets.xcassets/.DS_Store new file mode 100644 index 0000000..4cacf4b Binary files /dev/null and b/MRMobileRun/Assets.xcassets/.DS_Store differ diff --git a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/Contents.json b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/Contents.json index 147cfbe..2150995 100755 --- a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,107 +1,105 @@ { "images" : [ { - "size" : "20x20", + "filename" : "资源 1 2.png", "idiom" : "iphone", - "filename" : "icon-20@2x.png", - "scale" : "2x" + "scale" : "2x", + "size" : "20x20" }, { - "size" : "20x20", + "filename" : "资源 2 2.png", "idiom" : "iphone", - "filename" : "icon-20@3x.png", - "scale" : "3x" + "scale" : "3x", + "size" : "20x20" }, { - "size" : "29x29", + "filename" : "资源 6-12.png", "idiom" : "iphone", - "filename" : "icon-29@2x.png", - "scale" : "2x" + "scale" : "2x", + "size" : "29x29" }, { - "size" : "29x29", + "filename" : "资源 6-13.png", "idiom" : "iphone", - "filename" : "icon-29@3x.png", - "scale" : "3x" + "scale" : "3x", + "size" : "29x29" }, { - "size" : "40x40", + "filename" : "资源 5 2.png", "idiom" : "iphone", - "filename" : "icon-40@2x.png", - "scale" : "2x" + "scale" : "2x", + "size" : "40x40" }, { - "size" : "40x40", + "filename" : "资源 6 2.png", "idiom" : "iphone", - "filename" : "icon-40@3x.png", - "scale" : "3x" + "scale" : "3x", + "size" : "40x40" }, { - "size" : "60x60", "idiom" : "iphone", - "filename" : "icon-60@2x.png", - "scale" : "2x" + "scale" : "2x", + "size" : "60x60" }, { - "size" : "60x60", "idiom" : "iphone", - "filename" : "icon-60@3x.png", - "scale" : "3x" + "scale" : "3x", + "size" : "60x60" }, { "idiom" : "ipad", - "size" : "20x20", - "scale" : "1x" + "scale" : "1x", + "size" : "20x20" }, { "idiom" : "ipad", - "size" : "20x20", - "scale" : "2x" + "scale" : "2x", + "size" : "20x20" }, { "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" + "scale" : "1x", + "size" : "29x29" }, { "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" + "scale" : "2x", + "size" : "29x29" }, { "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" + "scale" : "1x", + "size" : "40x40" }, { "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" + "scale" : "2x", + "size" : "40x40" }, { "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" + "scale" : "1x", + "size" : "76x76" }, { "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" + "scale" : "2x", + "size" : "76x76" }, { "idiom" : "ipad", - "size" : "83.5x83.5", - "scale" : "2x" + "scale" : "2x", + "size" : "83.5x83.5" }, { - "size" : "1024x1024", + "filename" : "资源 6-14.png", "idiom" : "ios-marketing", - "filename" : "icon2.jpg", - "scale" : "1x" + "scale" : "1x", + "size" : "1024x1024" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png deleted file mode 100755 index 6da536c..0000000 Binary files a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png and /dev/null differ diff --git a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png deleted file mode 100755 index a301b84..0000000 Binary files a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png and /dev/null differ diff --git a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png deleted file mode 100755 index dd4a776..0000000 Binary files a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png and /dev/null differ diff --git a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png deleted file mode 100755 index 59f7a25..0000000 Binary files a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png and /dev/null differ diff --git a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png deleted file mode 100755 index 9d3edec..0000000 Binary files a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png and /dev/null differ diff --git a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png deleted file mode 100755 index 4b9f894..0000000 Binary files a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png and /dev/null differ diff --git a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png deleted file mode 100755 index 4b9f894..0000000 Binary files a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png and /dev/null differ diff --git a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png deleted file mode 100755 index e137dc9..0000000 Binary files a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png and /dev/null differ diff --git a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon2.jpg b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon2.jpg deleted file mode 100644 index 613c86b..0000000 Binary files a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/icon2.jpg and /dev/null differ diff --git "a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 1 2.png" "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 1 2.png" new file mode 100644 index 0000000..3e21094 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 1 2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 2 2.png" "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 2 2.png" new file mode 100644 index 0000000..c8c987e Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 2 2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 5 2.png" "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 5 2.png" new file mode 100644 index 0000000..8025fa9 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 5 2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6 2.png" "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6 2.png" new file mode 100644 index 0000000..8f20b89 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6 2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6-12.png" "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6-12.png" new file mode 100644 index 0000000..8855e23 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6-13.png" "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6-13.png" new file mode 100644 index 0000000..826b453 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6-13.png" differ diff --git "a/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6-14.png" "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6-14.png" new file mode 100644 index 0000000..a0d50aa Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/AppIcon.appiconset/\350\265\204\346\272\220 6-14.png" differ diff --git a/MRMobileRun/Assets.xcassets/Contents.json b/MRMobileRun/Assets.xcassets/Contents.json old mode 100755 new mode 100644 diff --git a/MRMobileRun/Assets.xcassets/MyHistoryPage/histirypage_range.imageset/1.png b/MRMobileRun/Assets.xcassets/MyHistoryPage/histirypage_range.imageset/1.png new file mode 100644 index 0000000..a90a328 Binary files /dev/null and b/MRMobileRun/Assets.xcassets/MyHistoryPage/histirypage_range.imageset/1.png differ diff --git a/MRMobileRun/Assets.xcassets/MyHistoryPage/histirypage_range.imageset/Contents.json b/MRMobileRun/Assets.xcassets/MyHistoryPage/histirypage_range.imageset/Contents.json index 94d3c9e..c72eeef 100644 --- a/MRMobileRun/Assets.xcassets/MyHistoryPage/histirypage_range.imageset/Contents.json +++ b/MRMobileRun/Assets.xcassets/MyHistoryPage/histirypage_range.imageset/Contents.json @@ -1,23 +1,54 @@ { "images" : [ { - "idiom" : "universal", "filename" : "基本/路程.png", + "idiom" : "universal", "scale" : "1x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], "idiom" : "universal", + "scale" : "1x" + }, + { "filename" : "基本/路程@2x.png", + "idiom" : "universal", "scale" : "2x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], "idiom" : "universal", + "scale" : "2x" + }, + { "filename" : "基本/路程@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "1.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/Contents.json" new file mode 100644 index 0000000..6bb887f --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "基本/路程备份 2.1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "基本/路程备份 2.2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "基本/路程备份 2@2x.1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "基本/路程备份 2@2x.2.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "基本/路程备份 2@3x.1.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "基本/路程备份 2@3x.2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2.1.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2.1.png" new file mode 100644 index 0000000..819dc25 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2.1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2.2.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2.2.png" new file mode 100644 index 0000000..9e4aea5 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2.2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@2x.1.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@2x.1.png" new file mode 100644 index 0000000..8367d83 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@2x.1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@2x.2.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@2x.2.png" new file mode 100644 index 0000000..9ab8445 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@2x.2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@3x.1.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@3x.1.png" new file mode 100644 index 0000000..44edb82 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@3x.1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@3x.2.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@3x.2.png" new file mode 100644 index 0000000..b75f56c Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\345\215\203\345\215\241.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275 2@3x.2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/Contents.json" new file mode 100644 index 0000000..6fab6f2 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "基本/路程备份t1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "基本/路程备份t2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "基本/路程备份@2xt1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "基本/路程备份@2xt2.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "基本/路程备份@3xt1.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "基本/路程备份@3xt2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@2xt1.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@2xt1.png" new file mode 100644 index 0000000..2479b13 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@2xt1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@2xt2.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@2xt2.png" new file mode 100644 index 0000000..56777ea Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@2xt2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@3xt1.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@3xt1.png" new file mode 100644 index 0000000..0e1c651 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@3xt1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@3xt2.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@3xt2.png" new file mode 100644 index 0000000..33545bb Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275@3xt2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275t1.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275t1.png" new file mode 100644 index 0000000..b48d75d Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275t1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275t2.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275t2.png" new file mode 100644 index 0000000..c792e84 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\346\227\266\351\227\264.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213\345\244\207\344\273\275t2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/Contents.json" new file mode 100644 index 0000000..e348b3c --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "基本/路程2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "基本/路程1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "基本/路程@2x1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "基本/路程@2x2.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "基本/路程@3x1.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "基本/路程@3x2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\2131.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\2131.png" new file mode 100644 index 0000000..a90a328 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\2131.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\2132.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\2132.png" new file mode 100644 index 0000000..d36e1c6 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\2132.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@2x1.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@2x1.png" new file mode 100644 index 0000000..92fd052 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@2x1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@2x2.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@2x2.png" new file mode 100644 index 0000000..b39ecf6 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@2x2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@3x1.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@3x1.png" new file mode 100644 index 0000000..645cba4 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@3x1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@3x2.png" "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@3x2.png" new file mode 100644 index 0000000..6b92a29 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/MyHistoryPage/\350\267\257\347\250\213.imageset/\345\237\272\346\234\254\357\274\217\350\267\257\347\250\213@3x2.png" differ diff --git a/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/Contents.json b/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/Contents.json index 208921a..081a9d8 100644 --- a/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/Contents.json +++ b/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/Contents.json @@ -1,23 +1,56 @@ { "images" : [ { - "idiom" : "universal", "filename" : "排名/1.png", + "idiom" : "universal", "scale" : "1x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "图层 2.png", "idiom" : "universal", + "scale" : "1x" + }, + { "filename" : "排名/1@2x.png", + "idiom" : "universal", "scale" : "2x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "图层 2@2x.png", "idiom" : "universal", + "scale" : "2x" + }, + { "filename" : "排名/1@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "图层 2@3x.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/\345\233\276\345\261\202 2.png" "b/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/\345\233\276\345\261\202 2.png" new file mode 100644 index 0000000..3c0460a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/\345\233\276\345\261\202 2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/\345\233\276\345\261\202 2@2x.png" "b/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/\345\233\276\345\261\202 2@2x.png" new file mode 100644 index 0000000..24e14fa Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/\345\233\276\345\261\202 2@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/\345\233\276\345\261\202 2@3x.png" "b/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/\345\233\276\345\261\202 2@3x.png" new file mode 100644 index 0000000..ca40c56 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/Rank/rank_1.imageset/\345\233\276\345\261\202 2@3x.png" differ diff --git a/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/Contents.json b/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/Contents.json index 9c9c992..6f6e7f4 100644 --- a/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/Contents.json +++ b/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/Contents.json @@ -1,23 +1,56 @@ { "images" : [ { - "idiom" : "universal", "filename" : "排名/1备份.png", + "idiom" : "universal", "scale" : "1x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "图层 3.png", "idiom" : "universal", + "scale" : "1x" + }, + { "filename" : "排名/1备份@2x.png", + "idiom" : "universal", "scale" : "2x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "图层 3@3x.png", "idiom" : "universal", + "scale" : "2x" + }, + { "filename" : "排名/1备份@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "图层 3@2x.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/\345\233\276\345\261\202 3.png" "b/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/\345\233\276\345\261\202 3.png" new file mode 100644 index 0000000..3c11503 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/\345\233\276\345\261\202 3.png" differ diff --git "a/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/\345\233\276\345\261\202 3@2x.png" "b/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/\345\233\276\345\261\202 3@2x.png" new file mode 100644 index 0000000..e8bb6d1 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/\345\233\276\345\261\202 3@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/\345\233\276\345\261\202 3@3x.png" "b/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/\345\233\276\345\261\202 3@3x.png" new file mode 100644 index 0000000..6cd0cac Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/Rank/rank_2.imageset/\345\233\276\345\261\202 3@3x.png" differ diff --git a/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/Contents.json b/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/Contents.json index a930791..f0ce11c 100644 --- a/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/Contents.json +++ b/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/Contents.json @@ -1,23 +1,56 @@ { "images" : [ { - "idiom" : "universal", "filename" : "排名/1备份 2.png", + "idiom" : "universal", "scale" : "1x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "图层 4.png", "idiom" : "universal", + "scale" : "1x" + }, + { "filename" : "排名/1备份 2@2x.png", + "idiom" : "universal", "scale" : "2x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "图层 4@2x.png", "idiom" : "universal", + "scale" : "2x" + }, + { "filename" : "排名/1备份 2@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "图层 4@3x.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/\345\233\276\345\261\202 4.png" "b/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/\345\233\276\345\261\202 4.png" new file mode 100644 index 0000000..7074f98 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/\345\233\276\345\261\202 4.png" differ diff --git "a/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/\345\233\276\345\261\202 4@2x.png" "b/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/\345\233\276\345\261\202 4@2x.png" new file mode 100644 index 0000000..efb2870 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/\345\233\276\345\261\202 4@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/\345\233\276\345\261\202 4@3x.png" "b/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/\345\233\276\345\261\202 4@3x.png" new file mode 100644 index 0000000..fb7a945 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/Rank/rank_3.imageset/\345\233\276\345\261\202 4@3x.png" differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/3.png b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/3.png new file mode 100644 index 0000000..3765528 Binary files /dev/null and b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/3.png differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/Contents.json b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/Contents.json new file mode 100644 index 0000000..23866c2 --- /dev/null +++ b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "资源 2分享.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 3分享.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 4分享.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/\350\265\204\346\272\220 2\345\210\206\344\272\253.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/\350\265\204\346\272\220 2\345\210\206\344\272\253.png" new file mode 100644 index 0000000..78c7fe3 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/\350\265\204\346\272\220 2\345\210\206\344\272\253.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/\350\265\204\346\272\220 3\345\210\206\344\272\253.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/\350\265\204\346\272\220 3\345\210\206\344\272\253.png" new file mode 100644 index 0000000..f7f7bec Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/\350\265\204\346\272\220 3\345\210\206\344\272\253.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/\350\265\204\346\272\220 4\345\210\206\344\272\253.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/\350\265\204\346\272\220 4\345\210\206\344\272\253.png" new file mode 100644 index 0000000..fa39a9a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_about_dark.imageset/\350\265\204\346\272\220 4\345\210\206\344\272\253.png" differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/11.png b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/11.png new file mode 100644 index 0000000..e378dff Binary files /dev/null and b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/11.png differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/4.png b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/4.png new file mode 100644 index 0000000..214aa83 Binary files /dev/null and b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/4.png differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/Contents.json b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/Contents.json new file mode 100644 index 0000000..a842934 --- /dev/null +++ b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "资源 1 2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "11.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 5 2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/\350\265\204\346\272\220 1 2.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/\350\265\204\346\272\220 1 2.png" new file mode 100644 index 0000000..69ef849 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/\350\265\204\346\272\220 1 2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/\350\265\204\346\272\220 5 2.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/\350\265\204\346\272\220 5 2.png" new file mode 100644 index 0000000..7ae9811 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_authority_dark.imageset/\350\265\204\346\272\220 5 2.png" differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/6.png b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/6.png new file mode 100644 index 0000000..679eb33 Binary files /dev/null and b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/6.png differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/Contents.json b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/Contents.json new file mode 100644 index 0000000..656c60c --- /dev/null +++ b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "资源 4 2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 3 2.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 2分享.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/\350\265\204\346\272\220 2\345\210\206\344\272\253.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/\350\265\204\346\272\220 2\345\210\206\344\272\253.png" new file mode 100644 index 0000000..0e43636 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/\350\265\204\346\272\220 2\345\210\206\344\272\253.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/\350\265\204\346\272\220 3 2.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/\350\265\204\346\272\220 3 2.png" new file mode 100644 index 0000000..8b6d7cc Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/\350\265\204\346\272\220 3 2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/\350\265\204\346\272\220 4 2.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/\350\265\204\346\272\220 4 2.png" new file mode 100644 index 0000000..d74d83e Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_darkMode_dark.imageset/\350\265\204\346\272\220 4 2.png" differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/1.png b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/1.png new file mode 100644 index 0000000..75994d7 Binary files /dev/null and b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/1.png differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/Contents.json b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/Contents.json new file mode 100644 index 0000000..8a1f917 --- /dev/null +++ b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "资源 6 2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 5 2.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 1 2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/\350\265\204\346\272\220 1 2.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/\350\265\204\346\272\220 1 2.png" new file mode 100644 index 0000000..cf0d758 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/\350\265\204\346\272\220 1 2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/\350\265\204\346\272\220 5 2.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/\350\265\204\346\272\220 5 2.png" new file mode 100644 index 0000000..ad83b93 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/\350\265\204\346\272\220 5 2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/\350\265\204\346\272\220 6 2.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/\350\265\204\346\272\220 6 2.png" new file mode 100644 index 0000000..eb06ac8 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_icon_dark.imageset/\350\265\204\346\272\220 6 2.png" differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/7.png b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/7.png new file mode 100644 index 0000000..f2f0a0d Binary files /dev/null and b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/7.png differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/Contents.json b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/Contents.json new file mode 100644 index 0000000..720061f --- /dev/null +++ b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "资源 5 2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 4 2.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/\350\265\204\346\272\220 4 2.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/\350\265\204\346\272\220 4 2.png" new file mode 100644 index 0000000..15769b3 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/\350\265\204\346\272\220 4 2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/\350\265\204\346\272\220 5 2.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/\350\265\204\346\272\220 5 2.png" new file mode 100644 index 0000000..e4de029 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_nickname_dark.imageset/\350\265\204\346\272\220 5 2.png" differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/2.png b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/2.png new file mode 100644 index 0000000..0e83ce3 Binary files /dev/null and b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/2.png differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/Contents.json b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/Contents.json new file mode 100644 index 0000000..3d5ec3d --- /dev/null +++ b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "资源 4分享.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 2分享.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 1@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/\350\265\204\346\272\220 1@3x.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/\350\265\204\346\272\220 1@3x.png" new file mode 100644 index 0000000..45115d7 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/\350\265\204\346\272\220 1@3x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/\350\265\204\346\272\220 2\345\210\206\344\272\253.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/\350\265\204\346\272\220 2\345\210\206\344\272\253.png" new file mode 100644 index 0000000..98c77b5 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/\350\265\204\346\272\220 2\345\210\206\344\272\253.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/\350\265\204\346\272\220 4\345\210\206\344\272\253.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/\350\265\204\346\272\220 4\345\210\206\344\272\253.png" new file mode 100644 index 0000000..f1c5e2f Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_sign_dark.imageset/\350\265\204\346\272\220 4\345\210\206\344\272\253.png" differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/5.png b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/5.png new file mode 100644 index 0000000..aaac791 Binary files /dev/null and b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/5.png differ diff --git a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/Contents.json b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/Contents.json new file mode 100644 index 0000000..f8e4e75 --- /dev/null +++ b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "资源 4.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 3@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 2@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/\350\265\204\346\272\220 2@3x.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/\350\265\204\346\272\220 2@3x.png" new file mode 100644 index 0000000..4b1fe4d Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/\350\265\204\346\272\220 2@3x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/\350\265\204\346\272\220 3@2x.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/\350\265\204\346\272\220 3@2x.png" new file mode 100644 index 0000000..aea5874 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/\350\265\204\346\272\220 3@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/\350\265\204\346\272\220 4.png" "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/\350\265\204\346\272\220 4.png" new file mode 100644 index 0000000..cfd5d12 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/SettingViewIcon/setting_suggestion_dark.imageset/\350\265\204\346\272\220 4.png" differ diff --git a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/Contents.json b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/Contents.json index 73f73fc..7f57fc3 100644 --- a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/Contents.json +++ b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/Contents.json @@ -1,23 +1,59 @@ { "images" : [ { - "idiom" : "universal", "filename" : "我的.png", + "idiom" : "universal", "scale" : "1x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "我的-选中白.png", "idiom" : "universal", + "scale" : "1x" + }, + { "filename" : "我的@2x.png", + "idiom" : "universal", "scale" : "2x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "我的-选中白@2x.png", "idiom" : "universal", + "scale" : "2x" + }, + { "filename" : "我的@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "我的-选中白@3x.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/\346\210\221\347\232\204-\351\200\211\344\270\255\347\231\275.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/\346\210\221\347\232\204-\351\200\211\344\270\255\347\231\275.png" new file mode 100644 index 0000000..ffc9949 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/\346\210\221\347\232\204-\351\200\211\344\270\255\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/\346\210\221\347\232\204-\351\200\211\344\270\255\347\231\275@2x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/\346\210\221\347\232\204-\351\200\211\344\270\255\347\231\275@2x.png" new file mode 100644 index 0000000..174e308 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/\346\210\221\347\232\204-\351\200\211\344\270\255\347\231\275@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/\346\210\221\347\232\204-\351\200\211\344\270\255\347\231\275@3x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/\346\210\221\347\232\204-\351\200\211\344\270\255\347\231\275@3x.png" new file mode 100644 index 0000000..2cac3ff Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_highlighted.imageset/\346\210\221\347\232\204-\351\200\211\344\270\255\347\231\275@3x.png" differ diff --git a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/Contents.json b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/Contents.json index 73f73fc..18650bd 100644 --- a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/Contents.json +++ b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/Contents.json @@ -1,23 +1,26 @@ { "images" : [ { + "filename" : "未选中-16.png", "idiom" : "universal", - "filename" : "我的.png", "scale" : "1x" }, { + "filename" : "未选中-17.png", "idiom" : "universal", - "filename" : "我的@2x.png", "scale" : "2x" }, { + "filename" : "未选中-18.png", "idiom" : "universal", - "filename" : "我的@3x.png", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\210\221\347\232\204.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\210\221\347\232\204.png" deleted file mode 100644 index 57392ea..0000000 Binary files "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\210\221\347\232\204.png" and /dev/null differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\210\221\347\232\204@2x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\210\221\347\232\204@2x.png" deleted file mode 100644 index 3cb08b5..0000000 Binary files "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\210\221\347\232\204@2x.png" and /dev/null differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\210\221\347\232\204@3x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\210\221\347\232\204@3x.png" deleted file mode 100644 index 47c80bd..0000000 Binary files "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\210\221\347\232\204@3x.png" and /dev/null differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\234\252\351\200\211\344\270\255-16.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\234\252\351\200\211\344\270\255-16.png" new file mode 100644 index 0000000..75a26b8 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\234\252\351\200\211\344\270\255-16.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\234\252\351\200\211\344\270\255-17.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\234\252\351\200\211\344\270\255-17.png" new file mode 100644 index 0000000..1327bee Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\234\252\351\200\211\344\270\255-17.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\234\252\351\200\211\344\270\255-18.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\234\252\351\200\211\344\270\255-18.png" new file mode 100644 index 0000000..00428b1 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/MyView_normal.imageset/\346\234\252\351\200\211\344\270\255-18.png" differ diff --git a/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/Contents.json b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/Contents.json index 12c3054..12f81c4 100644 --- a/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/Contents.json +++ b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/Contents.json @@ -1,23 +1,73 @@ { "images" : [ { - "idiom" : "universal", "filename" : "首页.png", + "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "bottom" : 21, + "left" : 21, + "right" : 20, + "top" : 20 + }, + "center" : { + "height" : 1, + "mode" : "tile", + "width" : 1 + }, + "mode" : "9-part" + }, "scale" : "1x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "首页-选中白-1.png", "idiom" : "universal", + "scale" : "1x" + }, + { "filename" : "首页@2x.png", + "idiom" : "universal", "scale" : "2x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "首页-选中白@2x-1.png", "idiom" : "universal", + "scale" : "2x" + }, + { "filename" : "首页@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "首页-选中白@3x-1.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/\351\246\226\351\241\265-\351\200\211\344\270\255\347\231\275-1.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/\351\246\226\351\241\265-\351\200\211\344\270\255\347\231\275-1.png" new file mode 100644 index 0000000..81cb2ec Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/\351\246\226\351\241\265-\351\200\211\344\270\255\347\231\275-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/\351\246\226\351\241\265-\351\200\211\344\270\255\347\231\275@2x-1.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/\351\246\226\351\241\265-\351\200\211\344\270\255\347\231\275@2x-1.png" new file mode 100644 index 0000000..755a264 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/\351\246\226\351\241\265-\351\200\211\344\270\255\347\231\275@2x-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/\351\246\226\351\241\265-\351\200\211\344\270\255\347\231\275@3x-1.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/\351\246\226\351\241\265-\351\200\211\344\270\255\347\231\275@3x-1.png" new file mode 100644 index 0000000..f87a6c6 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_highlighted.imageset/\351\246\226\351\241\265-\351\200\211\344\270\255\347\231\275@3x-1.png" differ diff --git a/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/Contents.json b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/Contents.json new file mode 100644 index 0000000..f0df741 --- /dev/null +++ b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "首页-未选中-1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "首页-未选中-2.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "首页-未选中-3.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/\351\246\226\351\241\265-\346\234\252\351\200\211\344\270\255-1.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/\351\246\226\351\241\265-\346\234\252\351\200\211\344\270\255-1.png" new file mode 100644 index 0000000..df4eda3 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/\351\246\226\351\241\265-\346\234\252\351\200\211\344\270\255-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/\351\246\226\351\241\265-\346\234\252\351\200\211\344\270\255-2.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/\351\246\226\351\241\265-\346\234\252\351\200\211\344\270\255-2.png" new file mode 100644 index 0000000..9b18a1c Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/\351\246\226\351\241\265-\346\234\252\351\200\211\344\270\255-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/\351\246\226\351\241\265-\346\234\252\351\200\211\344\270\255-3.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/\351\246\226\351\241\265-\346\234\252\351\200\211\344\270\255-3.png" new file mode 100644 index 0000000..936a8de Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/mainView_normal.imageset/\351\246\226\351\241\265-\346\234\252\351\200\211\344\270\255-3.png" differ diff --git a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/Contents.json b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/Contents.json index b8a1e5f..452723c 100644 --- a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/Contents.json +++ b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/Contents.json @@ -1,23 +1,59 @@ { "images" : [ { - "idiom" : "universal", "filename" : "排行.png", + "idiom" : "universal", "scale" : "1x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "排行-选中白.png", "idiom" : "universal", + "scale" : "1x" + }, + { "filename" : "排行@2x.png", + "idiom" : "universal", "scale" : "2x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "排行-选中白@2x.png", "idiom" : "universal", + "scale" : "2x" + }, + { "filename" : "排行@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "排行-选中白@3x.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/\346\216\222\350\241\214-\351\200\211\344\270\255\347\231\275.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/\346\216\222\350\241\214-\351\200\211\344\270\255\347\231\275.png" new file mode 100644 index 0000000..a3a08fd Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/\346\216\222\350\241\214-\351\200\211\344\270\255\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/\346\216\222\350\241\214-\351\200\211\344\270\255\347\231\275@2x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/\346\216\222\350\241\214-\351\200\211\344\270\255\347\231\275@2x.png" new file mode 100644 index 0000000..3297c6a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/\346\216\222\350\241\214-\351\200\211\344\270\255\347\231\275@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/\346\216\222\350\241\214-\351\200\211\344\270\255\347\231\275@3x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/\346\216\222\350\241\214-\351\200\211\344\270\255\347\231\275@3x.png" new file mode 100644 index 0000000..7e8befb Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_highlighted.imageset/\346\216\222\350\241\214-\351\200\211\344\270\255\347\231\275@3x.png" differ diff --git a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/Contents.json b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/Contents.json index b8a1e5f..e7f2cbb 100644 --- a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/Contents.json +++ b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/Contents.json @@ -1,23 +1,26 @@ { "images" : [ { + "filename" : "排行-未选中-1.png", "idiom" : "universal", - "filename" : "排行.png", "scale" : "1x" }, { + "filename" : "排行-未选中-2.png", "idiom" : "universal", - "filename" : "排行@2x.png", "scale" : "2x" }, { + "filename" : "排行-未选中-3.png", "idiom" : "universal", - "filename" : "排行@3x.png", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214-\346\234\252\351\200\211\344\270\255-1.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214-\346\234\252\351\200\211\344\270\255-1.png" new file mode 100644 index 0000000..257a09f Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214-\346\234\252\351\200\211\344\270\255-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214-\346\234\252\351\200\211\344\270\255-2.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214-\346\234\252\351\200\211\344\270\255-2.png" new file mode 100644 index 0000000..64b8a40 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214-\346\234\252\351\200\211\344\270\255-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214-\346\234\252\351\200\211\344\270\255-3.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214-\346\234\252\351\200\211\344\270\255-3.png" new file mode 100644 index 0000000..66d21b4 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214-\346\234\252\351\200\211\344\270\255-3.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214.png" deleted file mode 100644 index eb533a2..0000000 Binary files "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214.png" and /dev/null differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214@2x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214@2x.png" deleted file mode 100644 index 117e04d..0000000 Binary files "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214@2x.png" and /dev/null differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214@3x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214@3x.png" deleted file mode 100644 index 0d54b5b..0000000 Binary files "a/MRMobileRun/Assets.xcassets/TabbarIcon/rank_nomal.imageset/\346\216\222\350\241\214@3x.png" and /dev/null differ diff --git a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/Contents.json b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/Contents.json index b4b3baf..cf93d81 100644 --- a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/Contents.json +++ b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/Contents.json @@ -1,23 +1,60 @@ { "images" : [ { - "idiom" : "universal", "filename" : "排行备份.png", + "idiom" : "universal", "scale" : "1x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "设置-选中白.png", "idiom" : "universal", + "scale" : "1x" + }, + { "filename" : "排行备份@2x.png", + "idiom" : "universal", "scale" : "2x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "设置-选中白@2x.png", "idiom" : "universal", + "scale" : "2x" + }, + { "filename" : "排行备份@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "设置-选中白@3x.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true, + "template-rendering-intent" : "original" } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/\350\256\276\347\275\256-\351\200\211\344\270\255\347\231\275.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/\350\256\276\347\275\256-\351\200\211\344\270\255\347\231\275.png" new file mode 100644 index 0000000..41b6adc Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/\350\256\276\347\275\256-\351\200\211\344\270\255\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/\350\256\276\347\275\256-\351\200\211\344\270\255\347\231\275@2x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/\350\256\276\347\275\256-\351\200\211\344\270\255\347\231\275@2x.png" new file mode 100644 index 0000000..52bd9fe Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/\350\256\276\347\275\256-\351\200\211\344\270\255\347\231\275@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/\350\256\276\347\275\256-\351\200\211\344\270\255\347\231\275@3x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/\350\256\276\347\275\256-\351\200\211\344\270\255\347\231\275@3x.png" new file mode 100644 index 0000000..c246360 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_highlighted.imageset/\350\256\276\347\275\256-\351\200\211\344\270\255\347\231\275@3x.png" differ diff --git a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/Contents.json b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/Contents.json index b4b3baf..7082863 100644 --- a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/Contents.json +++ b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/Contents.json @@ -1,23 +1,26 @@ { "images" : [ { + "filename" : "未选中-7.png", "idiom" : "universal", - "filename" : "排行备份.png", "scale" : "1x" }, { + "filename" : "未选中-8.png", "idiom" : "universal", - "filename" : "排行备份@2x.png", "scale" : "2x" }, { + "filename" : "未选中-9.png", "idiom" : "universal", - "filename" : "排行备份@3x.png", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\216\222\350\241\214\345\244\207\344\273\275.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\216\222\350\241\214\345\244\207\344\273\275.png" deleted file mode 100644 index e8dfe93..0000000 Binary files "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\216\222\350\241\214\345\244\207\344\273\275.png" and /dev/null differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\216\222\350\241\214\345\244\207\344\273\275@2x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\216\222\350\241\214\345\244\207\344\273\275@2x.png" deleted file mode 100644 index 11007a2..0000000 Binary files "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\216\222\350\241\214\345\244\207\344\273\275@2x.png" and /dev/null differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\216\222\350\241\214\345\244\207\344\273\275@3x.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\216\222\350\241\214\345\244\207\344\273\275@3x.png" deleted file mode 100644 index 7b3da5e..0000000 Binary files "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\216\222\350\241\214\345\244\207\344\273\275@3x.png" and /dev/null differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\234\252\351\200\211\344\270\255-7.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\234\252\351\200\211\344\270\255-7.png" new file mode 100644 index 0000000..089b4c3 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\234\252\351\200\211\344\270\255-7.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\234\252\351\200\211\344\270\255-8.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\234\252\351\200\211\344\270\255-8.png" new file mode 100644 index 0000000..253c6cd Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\234\252\351\200\211\344\270\255-8.png" differ diff --git "a/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\234\252\351\200\211\344\270\255-9.png" "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\234\252\351\200\211\344\270\255-9.png" new file mode 100644 index 0000000..a77a56f Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/TabbarIcon/setting_normal.imageset/\346\234\252\351\200\211\344\270\255-9.png" differ diff --git a/MRMobileRun/Assets.xcassets/userAnnotation.imageset/Contents.json b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/Contents.json new file mode 100644 index 0000000..a22eb5b --- /dev/null +++ b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/Contents.json @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "白.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "黑.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "白-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "黑-2.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "黑-1.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "黑-3.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\347\231\275-1.png" "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\347\231\275-1.png" new file mode 100644 index 0000000..aac90bb Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\347\231\275-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\347\231\275.png" "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\347\231\275.png" new file mode 100644 index 0000000..aac90bb Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221-1.png" "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221-1.png" new file mode 100644 index 0000000..fa5ba32 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221-2.png" "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221-2.png" new file mode 100644 index 0000000..fa5ba32 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221-3.png" "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221-3.png" new file mode 100644 index 0000000..fa5ba32 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221-3.png" differ diff --git "a/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221.png" "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221.png" new file mode 100644 index 0000000..fa5ba32 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/userAnnotation.imageset/\351\273\221.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/.DS_Store" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/.DS_Store" new file mode 100644 index 0000000..6db6dc1 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/.DS_Store" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/Contents.json" new file mode 100644 index 0000000..26a7d46 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "锁定白.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "锁定大.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "锁定白-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "锁定大-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "锁定白-2.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "锁定大-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\345\244\247-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\345\244\247-1.png" new file mode 100644 index 0000000..f304eaa Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\345\244\247-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\345\244\247-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\345\244\247-2.png" new file mode 100644 index 0000000..f304eaa Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\345\244\247-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\345\244\247.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\345\244\247.png" new file mode 100644 index 0000000..f304eaa Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\345\244\247.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\347\231\275-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\347\231\275-1.png" new file mode 100644 index 0000000..da94a3f Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\347\231\275-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\347\231\275-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\347\231\275-2.png" new file mode 100644 index 0000000..da94a3f Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\347\231\275-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\347\231\275.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\347\231\275.png" new file mode 100644 index 0000000..da94a3f Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BigLockBtnImage.imageset/\351\224\201\345\256\232\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BottomColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BottomColor.colorset/Contents.json" new file mode 100644 index 0000000..c5247a8 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BottomColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "255", + "alpha" : "1.000", + "blue" : "255", + "green" : "255" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "74", + "alpha" : "1.000", + "blue" : "82", + "green" : "77" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BottomUnitColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BottomUnitColor.colorset/Contents.json" new file mode 100644 index 0000000..24aef61 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/BottomUnitColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "100", + "alpha" : "1.000", + "blue" : "111", + "green" : "104" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "178", + "alpha" : "1.000", + "blue" : "178", + "green" : "178" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/ContinueTextColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/ContinueTextColor.colorset/Contents.json" new file mode 100644 index 0000000..c8bae13 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/ContinueTextColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "111", + "green" : "104", + "red" : "100" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/Contents 2.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/Contents 2.json" new file mode 100644 index 0000000..95674e7 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/Contents 2.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "辅助icon/爬梯备份.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "爬梯备份 2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "辅助icon/爬梯备份@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "爬梯备份 2-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "辅助icon/爬梯备份@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "爬梯备份 2-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/Contents.json" new file mode 100644 index 0000000..4b4cdc8 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "GPS(1).png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "GPS.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "GPS(1)-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "GPS-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "GPS(1)-2.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "GPS-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS(1)-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS(1)-1.png" new file mode 100644 index 0000000..02610f9 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS(1)-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS(1)-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS(1)-2.png" new file mode 100644 index 0000000..02610f9 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS(1)-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS(1).png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS(1).png" new file mode 100644 index 0000000..02610f9 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS(1).png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS-1.png" new file mode 100644 index 0000000..7398911 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS-2.png" new file mode 100644 index 0000000..7398911 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS.png" new file mode 100644 index 0000000..7398911 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/GPS.imageset/GPS.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/OverBtnBackColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/OverBtnBackColor.colorset/Contents.json" new file mode 100644 index 0000000..252c844 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/OverBtnBackColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "100", + "alpha" : "1.000", + "blue" : "111", + "green" : "104" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "220", + "alpha" : "1.000", + "blue" : "230", + "green" : "224" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/OverBtnColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/OverBtnColor.colorset/Contents.json" new file mode 100644 index 0000000..13471d1 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/OverBtnColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "1.000", + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "51", + "alpha" : "1.000", + "blue" : "57", + "green" : "55" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/RunBtnColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/RunBtnColor.colorset/Contents.json" new file mode 100644 index 0000000..db21784 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/RunBtnColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "111", + "green" : "104", + "red" : "100" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "230", + "green" : "224", + "red" : "220" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertColor.colorset/Contents.json" new file mode 100644 index 0000000..2d230fe --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "255", + "green" : "255", + "red" : "255" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "93", + "green" : "84", + "red" : "79" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertEndBtnTexteColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertEndBtnTexteColor.colorset/Contents.json" new file mode 100644 index 0000000..391c9bc --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertEndBtnTexteColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "1.000", + "green" : "1.000", + "red" : "1.000" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "60", + "green" : "58", + "red" : "55" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertTextColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertTextColor.colorset/Contents.json" new file mode 100644 index 0000000..91e60ae --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertTextColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "57", + "green" : "55", + "red" : "51" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "255", + "green" : "255", + "red" : "255" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertViewColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertViewColor.colorset/Contents.json" new file mode 100644 index 0000000..d195bbf --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SZHAlertViewColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "242", + "green" : "242", + "red" : "242" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.000", + "green" : "0.000", + "red" : "0.000" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SpeedNumberLblTextColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SpeedNumberLblTextColor.colorset/Contents.json" new file mode 100644 index 0000000..890e2b5 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/SpeedNumberLblTextColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "72", + "green" : "68", + "red" : "65" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "255", + "green" : "255", + "red" : "255" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/Contents.json" new file mode 100644 index 0000000..efa2182 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "小logo/白备份.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "小logo/白.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "小logo/白备份@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "小logo/白@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "小logo/白备份@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "小logo/白@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275.png" new file mode 100644 index 0000000..059007f Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275@2x.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275@2x.png" new file mode 100644 index 0000000..dc95e22 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275@3x.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275@3x.png" new file mode 100644 index 0000000..5a564a9 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275@3x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275\345\244\207\344\273\275.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275\345\244\207\344\273\275.png" new file mode 100644 index 0000000..fc792cd Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275\345\244\207\344\273\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275\345\244\207\344\273\275@2x.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275\345\244\207\344\273\275@2x.png" new file mode 100644 index 0000000..f09405a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275\345\244\207\344\273\275@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275\345\244\207\344\273\275@3x.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275\345\244\207\344\273\275@3x.png" new file mode 100644 index 0000000..b509927 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/begin.imageset/\345\260\217logo\357\274\217\347\231\275\345\244\207\344\273\275@3x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/bottomTitleColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/bottomTitleColor.colorset/Contents.json" new file mode 100644 index 0000000..8610ace --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/bottomTitleColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "65", + "alpha" : "1.000", + "blue" : "72", + "green" : "68" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "255", + "alpha" : "1.000", + "blue" : "255", + "green" : "255" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/Contents.json" new file mode 100644 index 0000000..79324e5 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "白.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "白-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "白-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/\347\231\275-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/\347\231\275-1.png" new file mode 100644 index 0000000..4f11ba1 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/\347\231\275-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/\347\231\275-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/\347\231\275-2.png" new file mode 100644 index 0000000..4f11ba1 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/\347\231\275-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/\347\231\275.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/\347\231\275.png" new file mode 100644 index 0000000..4f11ba1 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/continueBtnImage.imageset/\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/Contents.json" new file mode 100644 index 0000000..79324e5 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "白.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "白-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "白-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/\347\231\275-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/\347\231\275-1.png" new file mode 100644 index 0000000..2a1dac0 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/\347\231\275-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/\347\231\275-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/\347\231\275-2.png" new file mode 100644 index 0000000..2a1dac0 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/\347\231\275-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/\347\231\275.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/\347\231\275.png" new file mode 100644 index 0000000..2a1dac0 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endBtnImage.imageset/\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/Contents.json" new file mode 100644 index 0000000..c6bccd7 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "终.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "终-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "终-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/\347\273\210-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/\347\273\210-1.png" new file mode 100644 index 0000000..c0f7925 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/\347\273\210-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/\347\273\210-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/\347\273\210-2.png" new file mode 100644 index 0000000..c0f7925 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/\347\273\210-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/\347\273\210.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/\347\273\210.png" new file mode 100644 index 0000000..c0f7925 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/endPointImage.imageset/\347\273\210.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/grayColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/grayColor.colorset/Contents.json" new file mode 100644 index 0000000..252c844 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/grayColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "100", + "alpha" : "1.000", + "blue" : "111", + "green" : "104" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "220", + "alpha" : "1.000", + "blue" : "230", + "green" : "224" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/milesColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/milesColor.colorset/Contents.json" new file mode 100644 index 0000000..8610ace --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/milesColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "65", + "alpha" : "1.000", + "blue" : "72", + "green" : "68" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "255", + "alpha" : "1.000", + "blue" : "255", + "green" : "255" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/milesTextColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/milesTextColor.colorset/Contents.json" new file mode 100644 index 0000000..2d48fd8 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/milesTextColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "111", + "green" : "104", + "red" : "100" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "178", + "green" : "178", + "red" : "178" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/Contents.json" new file mode 100644 index 0000000..99d3328 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "白.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "黑.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "白-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "黑-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "白-2.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "黑-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\347\231\275-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\347\231\275-1.png" new file mode 100644 index 0000000..1ca272b Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\347\231\275-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\347\231\275-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\347\231\275-2.png" new file mode 100644 index 0000000..1ca272b Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\347\231\275-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\347\231\275.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\347\231\275.png" new file mode 100644 index 0000000..1ca272b Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\351\273\221-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\351\273\221-1.png" new file mode 100644 index 0000000..6fe0b19 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\351\273\221-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\351\273\221-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\351\273\221-2.png" new file mode 100644 index 0000000..6fe0b19 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\351\273\221-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\351\273\221.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\351\273\221.png" new file mode 100644 index 0000000..6fe0b19 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/pauseBtnImage.imageset/\351\273\221.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/Contents.json" new file mode 100644 index 0000000..e7b1dee --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "锁定黑.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "灰.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "锁定黑-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "灰-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "锁定黑-2.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "灰-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\347\201\260-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\347\201\260-1.png" new file mode 100644 index 0000000..838e28a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\347\201\260-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\347\201\260-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\347\201\260-2.png" new file mode 100644 index 0000000..838e28a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\347\201\260-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\347\201\260.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\347\201\260.png" new file mode 100644 index 0000000..838e28a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\347\201\260.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\351\224\201\345\256\232\351\273\221-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\351\224\201\345\256\232\351\273\221-1.png" new file mode 100644 index 0000000..b4871dc Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\351\224\201\345\256\232\351\273\221-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\351\224\201\345\256\232\351\273\221-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\351\224\201\345\256\232\351\273\221-2.png" new file mode 100644 index 0000000..b4871dc Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\351\224\201\345\256\232\351\273\221-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\351\224\201\345\256\232\351\273\221.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\351\224\201\345\256\232\351\273\221.png" new file mode 100644 index 0000000..b4871dc Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/smallLockImage.imageset/\351\224\201\345\256\232\351\273\221.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/Contents.json" new file mode 100644 index 0000000..bebf18e --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "始.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "始-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "始-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/\345\247\213-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/\345\247\213-1.png" new file mode 100644 index 0000000..1132a28 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/\345\247\213-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/\345\247\213-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/\345\247\213-2.png" new file mode 100644 index 0000000..1132a28 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/\345\247\213-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/\345\247\213.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/\345\247\213.png" new file mode 100644 index 0000000..1132a28 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/startPointImage.imageset/\345\247\213.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/whiteColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/whiteColor.colorset/Contents.json" new file mode 100644 index 0000000..649c294 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/whiteColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "255", + "alpha" : "1.000", + "blue" : "255", + "green" : "255" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "60", + "alpha" : "1.000", + "blue" : "67", + "green" : "63" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/Contents.json" new file mode 100644 index 0000000..e7c52cb --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "资源 7.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 7-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 7-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/\350\265\204\346\272\220 7-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/\350\265\204\346\272\220 7-1.png" new file mode 100644 index 0000000..d375a8d Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/\350\265\204\346\272\220 7-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/\350\265\204\346\272\220 7-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/\350\265\204\346\272\220 7-2.png" new file mode 100644 index 0000000..d375a8d Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/\350\265\204\346\272\220 7-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/\350\265\204\346\272\220 7.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/\350\265\204\346\272\220 7.png" new file mode 100644 index 0000000..d375a8d Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\200\346\240\274.imageset/\350\265\204\346\272\220 7.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/Contents.json" new file mode 100644 index 0000000..3446748 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "资源 6.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 6-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 6-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/\350\265\204\346\272\220 6-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/\350\265\204\346\272\220 6-1.png" new file mode 100644 index 0000000..c2b056c Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/\350\265\204\346\272\220 6-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/\350\265\204\346\272\220 6-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/\350\265\204\346\272\220 6-2.png" new file mode 100644 index 0000000..c2b056c Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/\350\265\204\346\272\220 6-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/\350\265\204\346\272\220 6.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/\350\265\204\346\272\220 6.png" new file mode 100644 index 0000000..c2b056c Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\270\211\346\240\274.imageset/\350\265\204\346\272\220 6.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/Contents.json" new file mode 100644 index 0000000..72685ba --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "资源 5.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 5-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 5-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/\350\265\204\346\272\220 5-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/\350\265\204\346\272\220 5-1.png" new file mode 100644 index 0000000..bbc236a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/\350\265\204\346\272\220 5-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/\350\265\204\346\272\220 5-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/\350\265\204\346\272\220 5-2.png" new file mode 100644 index 0000000..bbc236a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/\350\265\204\346\272\220 5-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/\350\265\204\346\272\220 5.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/\350\265\204\346\272\220 5.png" new file mode 100644 index 0000000..bbc236a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\344\277\241\345\217\267\344\272\214\346\240\274.imageset/\350\265\204\346\272\220 5.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/Contents.json" new file mode 100644 index 0000000..9accf42 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "分享 1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 8-12.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 7-12.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/\345\210\206\344\272\253 1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/\345\210\206\344\272\253 1.png" new file mode 100644 index 0000000..2332699 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/\345\210\206\344\272\253 1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/\350\265\204\346\272\220 7-12.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/\350\265\204\346\272\220 7-12.png" new file mode 100644 index 0000000..839df5a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/\350\265\204\346\272\220 7-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/\350\265\204\346\272\220 8-12.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/\350\265\204\346\272\220 8-12.png" new file mode 100644 index 0000000..a200fa5 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2531.imageset/\350\265\204\346\272\220 8-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/Contents.json" new file mode 100644 index 0000000..5090e33 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "分享2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 14-12.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 13-12.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/\345\210\206\344\272\2532.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/\345\210\206\344\272\2532.png" new file mode 100644 index 0000000..f717256 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/\345\210\206\344\272\2532.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/\350\265\204\346\272\220 13-12.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/\350\265\204\346\272\220 13-12.png" new file mode 100644 index 0000000..0ea8870 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/\350\265\204\346\272\220 13-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/\350\265\204\346\272\220 14-12.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/\350\265\204\346\272\220 14-12.png" new file mode 100644 index 0000000..61a276b Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2532.imageset/\350\265\204\346\272\220 14-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/Contents.json" new file mode 100644 index 0000000..58c50e3 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "分享3.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 11-12.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 12-12.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/\345\210\206\344\272\2533.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/\345\210\206\344\272\2533.png" new file mode 100644 index 0000000..e0e2554 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/\345\210\206\344\272\2533.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/\350\265\204\346\272\220 11-12.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/\350\265\204\346\272\220 11-12.png" new file mode 100644 index 0000000..67adff7 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/\350\265\204\346\272\220 11-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/\350\265\204\346\272\220 12-12.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/\350\265\204\346\272\220 12-12.png" new file mode 100644 index 0000000..c8c4435 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2533.imageset/\350\265\204\346\272\220 12-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/Contents.json" new file mode 100644 index 0000000..73909cc --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "分享4.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 5-12.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 6-12.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/\345\210\206\344\272\2534.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/\345\210\206\344\272\2534.png" new file mode 100644 index 0000000..a242347 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/\345\210\206\344\272\2534.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/\350\265\204\346\272\220 5-12.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/\350\265\204\346\272\220 5-12.png" new file mode 100644 index 0000000..dc1dff2 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/\350\265\204\346\272\220 5-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/\350\265\204\346\272\220 6-12.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/\350\265\204\346\272\220 6-12.png" new file mode 100644 index 0000000..edf70a2 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2534.imageset/\350\265\204\346\272\220 6-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/Contents.json" new file mode 100644 index 0000000..3684793 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "分享5.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 2-12.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 1-12.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/\345\210\206\344\272\2535.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/\345\210\206\344\272\2535.png" new file mode 100644 index 0000000..ea2de66 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/\345\210\206\344\272\2535.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/\350\265\204\346\272\220 1-12.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/\350\265\204\346\272\220 1-12.png" new file mode 100644 index 0000000..d6a0b9b Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/\350\265\204\346\272\220 1-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/\350\265\204\346\272\220 2-12.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/\350\265\204\346\272\220 2-12.png" new file mode 100644 index 0000000..63ab945 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\206\344\272\2535.imageset/\350\265\204\346\272\220 2-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/Contents.json" new file mode 100644 index 0000000..233aeea --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "资源 1-8(1).png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 1-8(1)-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 1-8(1)-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-8(1)-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-8(1)-1.png" new file mode 100644 index 0000000..d2f9a12 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-8(1)-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-8(1)-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-8(1)-2.png" new file mode 100644 index 0000000..d2f9a12 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-8(1)-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-8(1).png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-8(1).png" new file mode 100644 index 0000000..d2f9a12 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\210\235\345\247\213\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-8(1).png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\215\203\345\215\241\347\201\260\350\211\262.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\215\203\345\215\241\347\201\260\350\211\262.imageset/Contents.json" new file mode 100644 index 0000000..18e425c --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\215\203\345\215\241\347\201\260\350\211\262.imageset/Contents.json" @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "千卡灰色@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "千卡灰色@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\215\203\345\215\241\347\201\260\350\211\262.imageset/\345\215\203\345\215\241\347\201\260\350\211\262@2x.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\215\203\345\215\241\347\201\260\350\211\262.imageset/\345\215\203\345\215\241\347\201\260\350\211\262@2x.png" new file mode 100644 index 0000000..b479e6b Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\215\203\345\215\241\347\201\260\350\211\262.imageset/\345\215\203\345\215\241\347\201\260\350\211\262@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\215\203\345\215\241\347\201\260\350\211\262.imageset/\345\215\203\345\215\241\347\201\260\350\211\262@3x.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\215\203\345\215\241\347\201\260\350\211\262.imageset/\345\215\203\345\215\241\347\201\260\350\211\262@3x.png" new file mode 100644 index 0000000..90727b2 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\215\203\345\215\241\347\201\260\350\211\262.imageset/\345\215\203\345\215\241\347\201\260\350\211\262@3x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/Contents.json" new file mode 100644 index 0000000..4442bd4 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/Contents.json" @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "资源 1-9.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "资源 1-10.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "资源 1-11.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-10.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-10.png" new file mode 100644 index 0000000..ac39685 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-10.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-11.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-11.png" new file mode 100644 index 0000000..ac39685 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-11.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-9.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-9.png" new file mode 100644 index 0000000..ac39685 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\345\272\225\351\203\250\344\275\215\347\275\256.imageset/\350\265\204\346\272\220 1-9.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\227\266\351\227\264\347\201\260.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\227\266\351\227\264\347\201\260.imageset/Contents.json" new file mode 100644 index 0000000..d6d4402 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\227\266\351\227\264\347\201\260.imageset/Contents.json" @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "时间灰@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "时间灰@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\227\266\351\227\264\347\201\260.imageset/\346\227\266\351\227\264\347\201\260@2x.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\227\266\351\227\264\347\201\260.imageset/\346\227\266\351\227\264\347\201\260@2x.png" new file mode 100644 index 0000000..579fde1 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\227\266\351\227\264\347\201\260.imageset/\346\227\266\351\227\264\347\201\260@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\227\266\351\227\264\347\201\260.imageset/\346\227\266\351\227\264\347\201\260@3x.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\227\266\351\227\264\347\201\260.imageset/\346\227\266\351\227\264\347\201\260@3x.png" new file mode 100644 index 0000000..1177764 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\227\266\351\227\264\347\201\260.imageset/\346\227\266\351\227\264\347\201\260@3x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/Contents.json" new file mode 100644 index 0000000..c24282d --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "晴黑.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "晴白.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "晴黑-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "晴白-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "晴黑-2.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "晴白-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\347\231\275-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\347\231\275-1.png" new file mode 100644 index 0000000..6ea7017 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\347\231\275-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\347\231\275-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\347\231\275-2.png" new file mode 100644 index 0000000..6ea7017 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\347\231\275-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\347\231\275.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\347\231\275.png" new file mode 100644 index 0000000..6ea7017 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\351\273\221-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\351\273\221-1.png" new file mode 100644 index 0000000..a0a4679 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\351\273\221-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\351\273\221-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\351\273\221-2.png" new file mode 100644 index 0000000..a0a4679 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\351\273\221-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\351\273\221.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\351\273\221.png" new file mode 100644 index 0000000..a0a4679 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\346\231\264\347\231\275.imageset/\346\231\264\351\273\221.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\347\273\223\346\235\237\346\214\211\351\222\256.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\347\273\223\346\235\237\346\214\211\351\222\256.imageset/Contents.json" index a713e5b..5a5cc2c 100755 --- "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\347\273\223\346\235\237\346\214\211\351\222\256.imageset/Contents.json" +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\347\273\223\346\235\237\346\214\211\351\222\256.imageset/Contents.json" @@ -1,8 +1,8 @@ { "images" : [ { - "idiom" : "universal", "filename" : "结束按钮副本2.png", + "idiom" : "universal", "scale" : "1x" }, { @@ -15,7 +15,7 @@ } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\205\215\351\200\237\347\201\260.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\205\215\351\200\237\347\201\260.imageset/Contents.json" new file mode 100644 index 0000000..70c4961 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\205\215\351\200\237\347\201\260.imageset/Contents.json" @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "配速灰@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "配速灰@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\205\215\351\200\237\347\201\260.imageset/\351\205\215\351\200\237\347\201\260@2x.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\205\215\351\200\237\347\201\260.imageset/\351\205\215\351\200\237\347\201\260@2x.png" new file mode 100644 index 0000000..aa2713e Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\205\215\351\200\237\347\201\260.imageset/\351\205\215\351\200\237\347\201\260@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\205\215\351\200\237\347\201\260.imageset/\351\205\215\351\200\237\347\201\260@3x.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\205\215\351\200\237\347\201\260.imageset/\351\205\215\351\200\237\347\201\260@3x.png" new file mode 100644 index 0000000..9f9d2b5 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\205\215\351\200\237\347\201\260.imageset/\351\205\215\351\200\237\347\201\260@3x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/Contents.json" new file mode 100644 index 0000000..2cdbf90 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "阴黑.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "阴天白.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "阴黑-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "阴天白-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "阴黑-2.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "阴天白-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\345\244\251\347\231\275-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\345\244\251\347\231\275-1.png" new file mode 100644 index 0000000..e468926 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\345\244\251\347\231\275-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\345\244\251\347\231\275-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\345\244\251\347\231\275-2.png" new file mode 100644 index 0000000..e468926 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\345\244\251\347\231\275-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\345\244\251\347\231\275.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\345\244\251\347\231\275.png" new file mode 100644 index 0000000..e468926 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\345\244\251\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\351\273\221-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\351\273\221-1.png" new file mode 100644 index 0000000..b8f1a58 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\351\273\221-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\351\273\221-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\351\273\221-2.png" new file mode 100644 index 0000000..b8f1a58 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\351\273\221-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\351\273\221.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\351\273\221.png" new file mode 100644 index 0000000..b8f1a58 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\230\264\345\244\251\347\231\275.imageset/\351\230\264\351\273\221.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/Contents.json" new file mode 100644 index 0000000..7954a51 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "雨黑.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "雨白.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "雨黑-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "雨白-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "雨黑-2.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "雨白-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\347\231\275-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\347\231\275-1.png" new file mode 100644 index 0000000..262ba21 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\347\231\275-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\347\231\275-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\347\231\275-2.png" new file mode 100644 index 0000000..262ba21 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\347\231\275-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\347\231\275.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\347\231\275.png" new file mode 100644 index 0000000..262ba21 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\351\273\221-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\351\273\221-1.png" new file mode 100644 index 0000000..79e9853 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\351\273\221-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\351\273\221-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\351\273\221-2.png" new file mode 100644 index 0000000..79e9853 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\351\273\221-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\351\273\221.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\351\273\221.png" new file mode 100644 index 0000000..79e9853 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\250\347\231\275.imageset/\351\233\250\351\273\221.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/Contents.json" new file mode 100644 index 0000000..78c291d --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "雪黑.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "雪白.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "雪黑-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "雪白-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "雪黑-2.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "雪白-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\347\231\275-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\347\231\275-1.png" new file mode 100644 index 0000000..883ddd1 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\347\231\275-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\347\231\275-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\347\231\275-2.png" new file mode 100644 index 0000000..883ddd1 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\347\231\275-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\347\231\275.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\347\231\275.png" new file mode 100644 index 0000000..883ddd1 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\351\273\221-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\351\273\221-1.png" new file mode 100644 index 0000000..c39716a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\351\273\221-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\351\273\221-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\351\273\221-2.png" new file mode 100644 index 0000000..c39716a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\351\273\221-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\351\273\221.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\351\273\221.png" new file mode 100644 index 0000000..c39716a Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\252\347\231\275.imageset/\351\233\252\351\273\221.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/Contents.json" new file mode 100644 index 0000000..3327f10 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "雷阵雨黑.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "雷阵雨白.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "雷阵雨黑-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "雷阵雨白-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "雷阵雨黑-2.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "雷阵雨白-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\347\231\275-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\347\231\275-1.png" new file mode 100644 index 0000000..786d5dd Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\347\231\275-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\347\231\275-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\347\231\275-2.png" new file mode 100644 index 0000000..786d5dd Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\347\231\275-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\347\231\275.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\347\231\275.png" new file mode 100644 index 0000000..786d5dd Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\347\231\275.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\351\273\221-1.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\351\273\221-1.png" new file mode 100644 index 0000000..5faa0f9 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\351\273\221-1.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\351\273\221-2.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\351\273\221-2.png" new file mode 100644 index 0000000..5faa0f9 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\351\273\221-2.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\351\273\221.png" "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\351\273\221.png" new file mode 100644 index 0000000..5faa0f9 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\345\274\200\345\247\213\350\267\221\346\255\245/\351\233\267\351\230\265\351\233\250\347\231\275.imageset/\351\233\267\351\230\265\351\233\250\351\273\221.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/Contents.json" "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/Contents.json" new file mode 100644 index 0000000..da4a164 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/Contents.json" @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDColor-1.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDColor-1.colorset/Contents.json" new file mode 100644 index 0000000..c5247a8 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDColor-1.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "255", + "alpha" : "1.000", + "blue" : "255", + "green" : "255" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "74", + "alpha" : "1.000", + "blue" : "82", + "green" : "77" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDColor-2.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDColor-2.colorset/Contents.json" new file mode 100644 index 0000000..c9851ff --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDColor-2.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "136", + "alpha" : "0.050", + "blue" : "181", + "green" : "154" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "60", + "alpha" : "1.000", + "blue" : "67", + "green" : "63" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDColor-3.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDColor-3.colorset/Contents.json" new file mode 100644 index 0000000..b50c551 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDColor-3.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "252", + "alpha" : "1.000", + "blue" : "252", + "green" : "252" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "60", + "alpha" : "1.000", + "blue" : "67", + "green" : "63" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDDataColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDDataColor.colorset/Contents.json" new file mode 100644 index 0000000..e372be2 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDDataColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "255", + "alpha" : "1.000", + "blue" : "255", + "green" : "255" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "255", + "alpha" : "1.000", + "blue" : "255", + "green" : "255" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDDividerColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDDividerColor.colorset/Contents.json" new file mode 100644 index 0000000..a743e3f --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDDividerColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "237", + "alpha" : "1.000", + "blue" : "237", + "green" : "237" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "97", + "alpha" : "1.000", + "blue" : "104", + "green" : "100" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDLineColor-1.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDLineColor-1.colorset/Contents.json" new file mode 100644 index 0000000..7509f9a --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDLineColor-1.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "237", + "alpha" : "1.000", + "blue" : "237", + "green" : "237" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "98", + "alpha" : "1.000", + "blue" : "98", + "green" : "98" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDLineColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDLineColor.colorset/Contents.json" new file mode 100644 index 0000000..ae4c449 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDLineColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "65", + "alpha" : "1.000", + "blue" : "72", + "green" : "68" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "98", + "alpha" : "1.000", + "blue" : "98", + "green" : "98" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDTextColor-1.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDTextColor-1.colorset/Contents.json" new file mode 100644 index 0000000..a0284dc --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDTextColor-1.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "51", + "alpha" : "1.000", + "blue" : "57", + "green" : "55" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "255", + "alpha" : "1.000", + "blue" : "255", + "green" : "255" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDTextColor-2.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDTextColor-2.colorset/Contents.json" new file mode 100644 index 0000000..4477165 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDTextColor-2.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "65", + "alpha" : "1.000", + "blue" : "72", + "green" : "68" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "178", + "alpha" : "1.000", + "blue" : "178", + "green" : "178" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDTextXColor.colorset/Contents.json" "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDTextXColor.colorset/Contents.json" new file mode 100644 index 0000000..535769e --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\346\210\221\347\232\204/MGDTextXColor.colorset/Contents.json" @@ -0,0 +1,38 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "51", + "alpha" : "1.000", + "blue" : "57", + "green" : "55" + } + } + }, + { + "idiom" : "universal", + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "178", + "alpha" : "1.000", + "blue" : "178", + "green" : "178" + } + } + } + ] +} \ No newline at end of file diff --git "a/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/Contents.json" new file mode 100644 index 0000000..cf82c05 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/Contents.json" @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "filename" : "矩形.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "资源 1-10.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "矩形@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "资源 2-11.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "矩形@3x.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "资源 3-12.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\347\237\251\345\275\242.png" "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\347\237\251\345\275\242.png" new file mode 100644 index 0000000..a3ee530 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\347\237\251\345\275\242.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\347\237\251\345\275\242@2x.png" "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\347\237\251\345\275\242@2x.png" new file mode 100644 index 0000000..980a303 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\347\237\251\345\275\242@2x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\347\237\251\345\275\242@3x.png" "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\347\237\251\345\275\242@3x.png" new file mode 100644 index 0000000..c3aebbb Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\347\237\251\345\275\242@3x.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\350\265\204\346\272\220 1-10.png" "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\350\265\204\346\272\220 1-10.png" new file mode 100644 index 0000000..a39ac09 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\350\265\204\346\272\220 1-10.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\350\265\204\346\272\220 2-11.png" "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\350\265\204\346\272\220 2-11.png" new file mode 100644 index 0000000..c794ffb Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\350\265\204\346\272\220 2-11.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\350\265\204\346\272\220 3-12.png" "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\350\265\204\346\272\220 3-12.png" new file mode 100644 index 0000000..927e30d Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\347\237\251\345\275\242.imageset/\350\265\204\346\272\220 3-12.png" differ diff --git "a/MRMobileRun/Assets.xcassets/\347\272\246\350\267\221.imageset/Contents.json" "b/MRMobileRun/Assets.xcassets/\347\272\246\350\267\221.imageset/Contents.json" new file mode 100644 index 0000000..703f191 --- /dev/null +++ "b/MRMobileRun/Assets.xcassets/\347\272\246\350\267\221.imageset/Contents.json" @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "{8CEA9EA9-D0C9-0C09-E950-3359B087960D}.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/MRMobileRun/Assets.xcassets/\347\272\246\350\267\221.imageset/{8CEA9EA9-D0C9-0C09-E950-3359B087960D}.png" "b/MRMobileRun/Assets.xcassets/\347\272\246\350\267\221.imageset/{8CEA9EA9-D0C9-0C09-E950-3359B087960D}.png" new file mode 100644 index 0000000..599d722 Binary files /dev/null and "b/MRMobileRun/Assets.xcassets/\347\272\246\350\267\221.imageset/{8CEA9EA9-D0C9-0C09-E950-3359B087960D}.png" differ diff --git a/MRMobileRun/Base.lproj/.DS_Store b/MRMobileRun/Base.lproj/.DS_Store deleted file mode 100644 index 11be8d2..0000000 Binary files a/MRMobileRun/Base.lproj/.DS_Store and /dev/null differ diff --git a/MRMobileRun/HTTPClient/HttpClient.h b/MRMobileRun/HTTPClient/HttpClient.h index ca09f00..11d65f2 100755 --- a/MRMobileRun/HTTPClient/HttpClient.h +++ b/MRMobileRun/HTTPClient/HttpClient.h @@ -19,6 +19,8 @@ typedef void (^PrepareExecuteBlock)(void); @interface HttpClient : NSObject + (HttpClient *)defaultClient; ++ (id)shareAFNManager;//单例AFN + - (void)requestWithHead:(NSString *)url method:(NSInteger)method parameters:(id)parameters diff --git a/MRMobileRun/HTTPClient/HttpClient.m b/MRMobileRun/HTTPClient/HttpClient.m index ee2cd22..edc13ee 100755 --- a/MRMobileRun/HTTPClient/HttpClient.m +++ b/MRMobileRun/HTTPClient/HttpClient.m @@ -8,6 +8,7 @@ #import "HttpClient.h" @implementation HttpClient +static AFHTTPSessionManager *manager; + (HttpClient *)defaultClient { @@ -19,6 +20,14 @@ + (HttpClient *)defaultClient return instance; } ++ (id)shareAFNManager{ + static AFHTTPSessionManager *manager; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + manager = [AFHTTPSessionManager manager]; + }); + return manager; +} - (void)requestWithPath:(NSString *)url method:(NSInteger)method @@ -65,6 +74,7 @@ - (void)requestWithPathInHEAD:(NSString *)url success:(void (^)(NSURLSessionDataTask *task))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure{ AFHTTPSessionManager *manger = [AFHTTPSessionManager manager]; + manger.responseSerializer = [AFHTTPResponseSerializer serializer]; [manger HEAD:url parameters:parameters success:success failure:failure]; } diff --git a/MRMobileRun/Info.plist b/MRMobileRun/Info.plist index 44986d8..17f0a70 100644 --- a/MRMobileRun/Info.plist +++ b/MRMobileRun/Info.plist @@ -2,10 +2,6 @@ - NSHealthUpdateUsageDescription - 重邮约跑需要您的同意,才能访问健康更新,给您带来更好的服务 - NSHealthShareUsageDescription - 重邮约跑需要您的同意,才能访问健康更新,给您带来更好的服务 CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -14,6 +10,10 @@ CFBundleExecutable $(EXECUTABLE_NAME) + CFBundleIconFile + This app is not allowed to query for scheme mqqapi + CFBundleIconName + CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion @@ -24,10 +24,18 @@ APPL CFBundleShortVersionString 1.0 + CFBundleSignature + This app is not allowed to query for scheme mqqapi CFBundleVersion 1.5 + LS + LSApplicationCategoryType + LSApplicationQueriesSchemes + + mqqapi + LSRequiresIPhoneOS NSAppTransportSecurity @@ -39,16 +47,30 @@ 用来获取照片作为头像 NSContactsUsageDescription + NSHealthShareUsageDescription + 重邮约跑需要您的同意,才能访问健康更新,给您带来更好的服务 + NSHealthUpdateUsageDescription + 重邮约跑需要您的同意,才能访问健康更新,给您带来更好的服务 + NSHumanReadableCopyright + This app is not allowed to query for scheme mqqapi + NSLocationAlwaysAndWhenInUseUsageDeion + VUP需要您的允许才能持续定位,并记录您的轨迹。 NSLocationAlwaysAndWhenInUseUsageDescription 用来在后台时获取用户跑步时路线画路线图 + NSLocationWhenInUseUsageDeion + VUP需要您的允许才能持续定位,并记录您的轨迹。 NSLocationWhenInUseUsageDescription 用来获取用户跑步时路线画路线图 NSMicrophoneUsageDescription NSMotionUsageDescription 用来获取用户跑步状态 - NSPhotoLibraryUsageDescription - 用来获取图片来设置头像 + NSPhotoLibraryAddUsageDescription + 保存到系统相册 + UIAppFonts + + Impact.ttf + UIBackgroundModes location diff --git a/MRMobileRun/MRInviteView/.DS_Store b/MRMobileRun/MRInviteView/.DS_Store deleted file mode 100644 index a00ea7f..0000000 Binary files a/MRMobileRun/MRInviteView/.DS_Store and /dev/null differ diff --git a/MRMobileRun/MRInviteView/LJJInviteRunVC.m b/MRMobileRun/MRInviteView/LJJInviteRunVC.m index ef90b52..a339751 100755 --- a/MRMobileRun/MRInviteView/LJJInviteRunVC.m +++ b/MRMobileRun/MRInviteView/LJJInviteRunVC.m @@ -104,7 +104,7 @@ - (void)setTheFlowBallsAndBoard:(LJJInviteRunView *)VC } - (void)viewWillAppear:(BOOL)animated{ - [[NSNotificationCenter defaultCenter] postNotificationName:@"hideTabBar" object:nil]; + self.tabBarController.tabBar.hidden = YES; } - (void)pressBtn { diff --git a/MRMobileRun/MRInviteView/LJJInviteSearchVC.m b/MRMobileRun/MRInviteView/LJJInviteSearchVC.m index e441925..d816aa6 100644 --- a/MRMobileRun/MRInviteView/LJJInviteSearchVC.m +++ b/MRMobileRun/MRInviteView/LJJInviteSearchVC.m @@ -29,7 +29,7 @@ - (void)viewDidLoad { } - (void)viewWillAppear:(BOOL)animated{ - [[NSNotificationCenter defaultCenter] postNotificationName:@"hideTabBar" object:nil]; + self.tabBarController.tabBar.hidden = YES; } - (void)pressBtn { diff --git a/MRMobileRun/MRLogin/.DS_Store b/MRMobileRun/MRLogin/.DS_Store deleted file mode 100644 index 733a305..0000000 Binary files a/MRMobileRun/MRLogin/.DS_Store and /dev/null differ diff --git a/MRMobileRun/MRLogin/MRLoginModel.m b/MRMobileRun/MRLogin/MRLoginModel.m index 9f97bcd..3930700 100755 --- a/MRMobileRun/MRLogin/MRLoginModel.m +++ b/MRMobileRun/MRLogin/MRLoginModel.m @@ -10,7 +10,7 @@ #import #import "MRLoginViewController.h" @implementation MRLoginModel - +//重写登陆的post请求,因为后端改成golang后返回的字段与java版本不同,此处按照postman返回的字段来写的 //登录的post请求 - (NSMutableDictionary *)postRequestWithStudentID:(NSString *)studentID andPassword:(NSString *)password { @@ -18,7 +18,7 @@ - (NSMutableDictionary *)postRequestWithStudentID:(NSString *)studentID andPassw if ([studentID isEqual: @""] || [password isEqual: @""]) { NSLog(@"账号密码为空"); - [[NSNotificationCenter defaultCenter] postNotificationName:@"isLoginFail" object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"isLoginFailNoData" object:nil]; } else { @@ -34,106 +34,111 @@ - (NSMutableDictionary *)postRequestWithStudentID:(NSString *)studentID andPassw } progress:^(NSProgress *progress) { // } success:^(NSURLSessionDataTask *task, id responseObject) { - if ([[responseObject objectForKey:@"status"] isEqual:@-2]) - { - [[NSNotificationCenter defaultCenter] postNotificationName:@"isLoginFail" object:nil]; - } - else - { - + if ([[responseObject objectForKey:@"status"] isEqual:@401]) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"isLoginFailErrorData" object:nil]; + } else { NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; - - [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"student_id"] forKey:@"studentID"]; - - [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"token"] forKey:@"token"]; - //存储学号 - [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"class_id"] forKey:@"class_id"]; - //储存班级号 - - [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"nickname"] forKey:@"nickname"]; + [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"StudentId"] forKey:@"studentID"]; + [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"Token"] forKey:@"token"]; + + [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"Nickname"] forKey:@"nickname"]; //存储昵称 - [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"avatar_url"] forKey:@"avatar_url"]; -// 存储头像 - [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"signature"] forKey:@"signature"]; -// 存储个性签名 + + [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"AvatarUrl"] forKey:@"avatar_url"]; + // 存储头像 + [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"Signature"] forKey:@"signature"]; + // 存储个性签名 [user setObject:password forKey:@"password"]; + [user setBool:NO forKey:@"MoreIsCache"]; + [user setBool:YES forKey:@"MoreIsFirst"]; + [user setBool:NO forKey:@"MineIsCache"]; + [user setBool:YES forKey:@"MineIsFirst"]; [user synchronize]; - //请求成功时发送广播 - [[NSNotificationCenter defaultCenter] postNotificationName:@"isLoginSuccess" object:nil]; - NSLog(@"the data is JJ EDC Michael %@",responseObject); - self->_threadTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(cycleToNetWork) userInfo:nil repeats:YES]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(invalidateTimer) name:@"turnOffTimer" object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopTimer) name:@"offTimer" object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keepTimer) name:@"keepTimer" object:nil]; - } - } failure:^(NSURLSessionDataTask *task, NSError *error) { - NSLog(@"the error is %@",error); - [[NSNotificationCenter defaultCenter] postNotificationName:@"isLoginFail" object:error]; - }]; + //请求成功时发送广播 + [[NSNotificationCenter defaultCenter] postNotificationName:@"isLoginSuccess" object:nil]; + NSLog(@"the data is JJ EDC Michael %@",responseObject); + //self->_threadTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(cycleToNetWork) userInfo:nil repeats:YES]; +// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(invalidateTimer) name:@"turnOffTimer" object:nil]; +// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopTimer) name:@"offTimer" object:nil]; +// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keepTimer) name:@"keepTimer" object:nil]; + } + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSLog(@"the error is %@",error); + if (error.code == -1001) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"isLoginFailTimeOut" object:nil]; + }else { + [[NSNotificationCenter defaultCenter] postNotificationName:@"isLoginFailNoClient" object:nil]; + } + }]; } return dic; } -- (void)invalidateTimer -{ - [_threadTimer invalidate]; -} +//- (void)invalidateTimer +//{ +// [_threadTimer invalidate]; +//} +// +//- (void)keepTimer +//{ +// [_threadTimer setFireDate:[NSDate distantPast]]; +//} +// +//- (void)stopTimer +//{ +// NSLog(@"定时器关闭定时器关闭定时器关闭"); +// [_threadTimer setFireDate:[NSDate distantFuture]]; +//} +// +//- (void)cycleToNetWork +//{ +// NSLog(@"repeat"); +// //轮询是否收到邀约网络请求 +// NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; +// HttpClient *client = [HttpClient defaultClient]; +// NSMutableDictionary *dic = [[NSMutableDictionary alloc] init]; +// [dic setObject:[user objectForKey:@"studentID"] forKey:@"student_id"]; +// NSDictionary *head = @{@"Content-Type":@"application/x-www-form-urlencoded",@"token":[user objectForKey:@"token"]}; +// [client requestWithHead:kCycleYesOrNoInviteSuccess method:HttpRequestGet parameters:dic head:head prepareExecute:^ +// { +// // +// } progress:^(NSProgress *progress) +// { +// // +// } success:^(NSURLSessionDataTask *task, id responseObject) +// { +// NSLog(@"the responseObject is %@",responseObject); +// MRLoginViewController *vc = [[MRLoginViewController alloc] init]; +// NSString *status = [responseObject objectForKey:@"status"]; +// NSLog(@"stasus is %@",status); +// NSString *codeStr = [NSString stringWithFormat:@"%@",status]; +// vc.invitedID = [[responseObject objectForKey:@"data"] objectForKey:@"invited_id"]; +// NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; +// [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"invited_id"] forKey:@"invite_ID"]; +// if ([codeStr isEqualToString:@"200"]) +// { +// NSLog(@"发射成功"); +// NSLog(@"%@",responseObject); +// //设置弹窗效果 +// vc.nickName = [[responseObject objectForKey:@"data"] objectForKey:@"nickname"]; +// //NSLog(@"nickName == %@",vc.nickName); +// if (![vc.nickName isEqualToString:[user objectForKey:@"nickname"]]) +// { +// [self stopTimer]; +// [vc setTheSpringWindow]; +// } +// } +// else +// { +// NSLog(@"发射失败"); +// NSLog(@"%@",responseObject); +// } +// } failure:nil]; +// +//} +@end + + -- (void)keepTimer -{ - [_threadTimer setFireDate:[NSDate distantPast]]; -} -- (void)stopTimer -{ - NSLog(@"定时器关闭定时器关闭定时器关闭"); - [_threadTimer setFireDate:[NSDate distantFuture]]; -} -- (void)cycleToNetWork -{ - NSLog(@"repeat"); - //轮询是否收到邀约网络请求 - NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; - HttpClient *client = [HttpClient defaultClient]; - NSMutableDictionary *dic = [[NSMutableDictionary alloc] init]; - [dic setObject:[user objectForKey:@"studentID"] forKey:@"student_id"]; - NSDictionary *head = @{@"Content-Type":@"application/x-www-form-urlencoded",@"token":[user objectForKey:@"token"]}; - [client requestWithHead:kCycleYesOrNoInviteSuccess method:HttpRequestGet parameters:dic head:head prepareExecute:^ - { - // - } progress:^(NSProgress *progress) - { - // - } success:^(NSURLSessionDataTask *task, id responseObject) - { - NSLog(@"the responseObject is %@",responseObject); - MRLoginViewController *vc = [[MRLoginViewController alloc] init]; - NSString *status = [responseObject objectForKey:@"status"]; - NSLog(@"stasus is %@",status); - NSString *codeStr = [NSString stringWithFormat:@"%@",status]; - vc.invitedID = [[responseObject objectForKey:@"data"] objectForKey:@"invited_id"]; - NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; - [user setObject:[[responseObject objectForKey:@"data"] objectForKey:@"invited_id"] forKey:@"invite_ID"]; - if ([codeStr isEqualToString:@"200"]) - { - NSLog(@"发射成功"); - NSLog(@"%@",responseObject); - //设置弹窗效果 - vc.nickName = [[responseObject objectForKey:@"data"] objectForKey:@"nickname"]; - //NSLog(@"nickName == %@",vc.nickName); - if (![vc.nickName isEqualToString:[user objectForKey:@"nickname"]]) - { - [self stopTimer]; - [vc setTheSpringWindow]; - } - } - else - { - NSLog(@"发射失败"); - NSLog(@"%@",responseObject); - } - } failure:nil]; - -} -@end diff --git a/MRMobileRun/MRLogin/MRMineView/Model/MGDSportData.h b/MRMobileRun/MRLogin/MRMineView/Model/MGDSportData.h new file mode 100644 index 0000000..9494490 --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/Model/MGDSportData.h @@ -0,0 +1,46 @@ +// +// MGDSportData.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/31. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDSportData : NSObject + +@property (nonatomic, strong) NSString *distance; + +@property (nonatomic, strong) NSString *totalTime; + +@property (nonatomic, strong) NSString *cal; + +@property (nonatomic, strong) NSString *AverageSpeed; + +@property (nonatomic, strong) NSString *AverageStepFrequency; + +@property (nonatomic, strong) NSString *MaxSpeed; + +@property (nonatomic, strong) NSString *MaxStepFrequency; + +@property (nonatomic, strong) NSString *FinishDate; + +@property (nonatomic, strong) NSString *Weather; + +@property (nonatomic, strong) NSString *Temperature; + +@property (nonatomic, strong) NSArray *StepFrequencyArray; + +@property (nonatomic, strong) NSArray *SpeedArray; + +@property (nonatomic, strong) NSArray *pathArray; + +-(instancetype)initWithDic:(NSDictionary *)dict; + ++(instancetype)SportDataWithDict:(NSDictionary *)dict; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRLogin/MRMineView/Model/MGDSportData.m b/MRMobileRun/MRLogin/MRMineView/Model/MGDSportData.m new file mode 100644 index 0000000..bde2c7f --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/Model/MGDSportData.m @@ -0,0 +1,35 @@ +// +// MGDSportData.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/31. +// + +#import "MGDSportData.h" + +@implementation MGDSportData + +-(instancetype)initWithDic:(NSDictionary *)dict { + if (self = [super init]) { + self.totalTime = dict[@"Duration"]; + self.distance = dict[@"Mileage"]; + self.cal = dict[@"Kcal"]; + self.FinishDate = dict[@"FinishDate"]; + self.AverageSpeed = dict[@"AverageSpeed"]; + self.AverageStepFrequency = dict[@"AverageStepFrequency"]; + self.MaxSpeed = dict[@"MaxSpeed"]; + self.MaxStepFrequency = dict[@"MaxStepFrequency"]; + self.Temperature = dict[@"Temperature"]; + self.Weather = dict[@"Weather"]; + self.StepFrequencyArray = dict[@"StepFrequency"]; + self.SpeedArray = dict[@"Speed"]; + self.pathArray = dict[@"path"]; + } + return self; +} + ++(instancetype)SportDataWithDict:(NSDictionary *)dict { + return [[self alloc] initWithDic:dict]; +} + +@end diff --git a/MRMobileRun/MRLogin/MRMineView/Model/MGDUserData.h b/MRMobileRun/MRLogin/MRMineView/Model/MGDUserData.h new file mode 100644 index 0000000..8bae4e2 --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/Model/MGDUserData.h @@ -0,0 +1,22 @@ +// +// mgduserdata.h +// MRMobileRun +// +// Created by 阿栋 on 2020/8/1. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDUserData : NSObject + +@property (nonatomic, copy) NSString *distance; +@property (nonatomic, copy) NSString *duration; +@property (nonatomic, copy) NSString *consume; + +-(instancetype)initWithDic:(NSDictionary *)dict; ++ (instancetype)DataWithDict:(NSDictionary *)dict; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRLogin/MRMineView/Model/MGDUserData.m b/MRMobileRun/MRLogin/MRMineView/Model/MGDUserData.m new file mode 100644 index 0000000..077452f --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/Model/MGDUserData.m @@ -0,0 +1,25 @@ +// +// mgduserdata.m +// MRMobileRun +// +// Created by 阿栋 on 2020/8/1. +// + +#import "MGDUserData.h" + +@implementation MGDUserData + +- (instancetype)initWithDic:(NSDictionary *)dict { + if (self = [super init]) { + self.distance = dict[@"TotalDistance"]; + self.duration = dict[@"TotalDuration"]; + self.consume = dict[@"TotalConsume"]; + } + return self; +} + ++ (instancetype)DataWithDict:(NSDictionary *)dict { + return [[self alloc] initWithDic:dict]; +} + +@end diff --git a/MRMobileRun/MRLogin/MRMineView/Model/MGDUserInfo.h b/MRMobileRun/MRLogin/MRMineView/Model/MGDUserInfo.h new file mode 100644 index 0000000..cede3ef --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/Model/MGDUserInfo.h @@ -0,0 +1,28 @@ +// +// MGDUserInfo.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/16. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDUserInfo : NSObject + +@property (nonatomic, strong) NSString *userName; + +@property (nonatomic, strong) NSString *userSign; + +@property (nonatomic, strong) NSString *userIcon; + +@property (nonatomic, strong) NSString *name; + +-(instancetype)initWithDic:(NSDictionary *)dict; + ++(instancetype)InfoWithDict:(NSDictionary *)dict; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRLogin/MRMineView/Model/MGDUserInfo.m b/MRMobileRun/MRLogin/MRMineView/Model/MGDUserInfo.m new file mode 100644 index 0000000..943bcce --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/Model/MGDUserInfo.m @@ -0,0 +1,24 @@ +// +// MGDUserInfo.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/16. +// + +#import "MGDUserInfo.h" + +@implementation MGDUserInfo +- (instancetype)initWithDic:(NSDictionary *)dict { + if (self = [super init]) { + self.userName = dict[@"Nickname"]; + self.userSign = dict[@"Signature"]; + self.userIcon = dict[@"AvatarUrl"]; + } + return self; +} + ++ (instancetype)InfoWithDict:(NSDictionary *)dict { + return [[self alloc] initWithDic:dict]; +} + +@end diff --git a/MRMobileRun/MRLogin/MRMineView/Model/TestModel.h b/MRMobileRun/MRLogin/MRMineView/Model/TestModel.h new file mode 100644 index 0000000..200d8fb --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/Model/TestModel.h @@ -0,0 +1,16 @@ +// +// TestModel.h +// MRMobileRun +// +// Created by 阿栋 on 2020/8/1. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface TestModel : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRLogin/MRMineView/Model/TestModel.m b/MRMobileRun/MRLogin/MRMineView/Model/TestModel.m new file mode 100644 index 0000000..f954bcd --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/Model/TestModel.m @@ -0,0 +1,12 @@ +// +// TestModel.m +// MRMobileRun +// +// Created by 阿栋 on 2020/8/1. +// + +#import "TestModel.h" + +@implementation TestModel + +@end diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDBaseInfoView.h b/MRMobileRun/MRLogin/MRMineView/View/MGDBaseInfoView.h new file mode 100644 index 0000000..e58a84a --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDBaseInfoView.h @@ -0,0 +1,36 @@ +// +// MGDBaseInfoView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/9. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDBaseInfoView : UIView + +@property(nonatomic,strong) UIView *backView; + +@property(nonatomic,strong) UIImageView *KmImage; + +@property(nonatomic,strong) UILabel *Kmlab; + +@property(nonatomic,strong) UILabel *kilometre; + +@property(nonatomic,strong) UIImageView *MinImage; + +@property(nonatomic,strong) UILabel *MinLab; + +@property(nonatomic,strong) UILabel *minus; + +@property(nonatomic,strong) UIImageView *calImage; + +@property(nonatomic,strong) UILabel *CalLab; + +@property(nonatomic,strong) UILabel *calories; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDBaseInfoView.m b/MRMobileRun/MRLogin/MRMineView/View/MGDBaseInfoView.m new file mode 100644 index 0000000..d2a7ea1 --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDBaseInfoView.m @@ -0,0 +1,181 @@ +// +// MGDBaseInfoView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/9. +// + +#import "MGDBaseInfoView.h" +#import + +#define NUMBERTEXTCOLOR [UIColor colorWithRed:65/255.0 green:68/255.0 blue:72/255.0 alpha:1.0] +#define UNITTEXTCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] + +@implementation MGDBaseInfoView + +-(instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + + UIView *backView = [[UIView alloc] init]; + self.backView = backView; + self.backView.backgroundColor = [UIColor clearColor]; + [self addSubview:backView]; + + UIImageView *KmImage = [[UIImageView alloc] init]; + self.KmImage = KmImage; + [self.backView addSubview:KmImage]; + _KmImage.image = [UIImage imageNamed:@"homepage_kilometer"]; + _KmImage.contentMode = UIViewContentModeScaleAspectFit; + + UIImageView *MinImage = [[UIImageView alloc] init]; + self.MinImage = MinImage; + [self.backView addSubview:MinImage]; + _MinImage.image = [UIImage imageNamed:@"homepage_time"]; + _MinImage.contentMode = UIViewContentModeScaleAspectFit; + + UIImageView *CalImage = [[UIImageView alloc] init]; + self.calImage = CalImage; + [self.backView addSubview:CalImage]; + //测试用数据 + _calImage.image = [UIImage imageNamed:@"homepage_consume"]; + _calImage.contentMode = UIViewContentModeScaleAspectFit; + + UILabel *KmLab = [[UILabel alloc] init]; + self.Kmlab = KmLab; + [self.backView addSubview:KmLab]; + _Kmlab.textAlignment = NSTextAlignmentCenter; + _Kmlab.numberOfLines = 0; + //字体不同,需要修改 + _Kmlab.font = [UIFont fontWithName:@"Impact" size: 24]; + + UILabel *MinLab = [[UILabel alloc] init]; + self.MinLab = MinLab; + [self.backView addSubview:MinLab]; + _MinLab.textAlignment = NSTextAlignmentCenter; + _MinLab.numberOfLines = 0; + //字体不同,需要修改 + _MinLab.font = [UIFont fontWithName:@"Impact" size: 24]; + + UILabel *CalLab = [[UILabel alloc] init]; + self.CalLab = CalLab; + [self addSubview:CalLab]; + _CalLab.textAlignment = NSTextAlignmentCenter; + _CalLab.numberOfLines = 0; + //字体不同,需要修改 + _CalLab.font = [UIFont fontWithName:@"Impact" size: 24]; + + UILabel *kilometre = [[UILabel alloc] init]; + self.kilometre = kilometre; + [self.backView addSubview:kilometre]; + _kilometre.text = @"公里"; + _kilometre.textAlignment = NSTextAlignmentCenter; + _kilometre.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 16]; + _kilometre.numberOfLines = 0; + _kilometre.textColor = UNITTEXTCOLOR; + + UILabel *minus = [[UILabel alloc] init]; + self.minus = minus; + [self.backView addSubview:minus]; + _minus.text = @"分"; + _minus.textAlignment = NSTextAlignmentCenter; + _minus.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 16]; + _minus.numberOfLines = 0; + _minus.textColor = UNITTEXTCOLOR; + + UILabel *calories = [[UILabel alloc] init]; + self.calories = calories; + [self.backView addSubview:calories]; + _calories.text = @"千卡"; + _calories.textAlignment = NSTextAlignmentCenter; + _calories.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 16]; + _calories.numberOfLines = 0; + _calories.textColor = UNITTEXTCOLOR; + + + if (@available(iOS 11.0, *)) { + self.Kmlab.textColor = MGDTextColor1; + self.MinLab.textColor = MGDTextColor1; + self.CalLab.textColor = MGDTextColor1; + } else { + // Fallback on earlier versions + } + } + return self; +} + + +- (void)layoutSubviews { + [super layoutSubviews]; + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth * 0.1441); + make.width.mas_equalTo(screenWidth); + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + }]; + + [_KmImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@40); + make.width.equalTo(@40); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(55); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(16); + }]; + + [_Kmlab mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@28); + make.width.equalTo(@90); + make.top.lessThanOrEqualTo(self.backView.mas_top).mas_offset(49); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(29); + }]; + + [_kilometre mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@18); + make.width.equalTo(@36); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(57); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(76); + }]; + + [_MinImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@40); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(167); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(16); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-168); + }]; + + [_MinLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@28); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(143); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(49); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-142); + }]; + + [_minus mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@18); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(170); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(76); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-169); + }]; + + [_calImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@40); + make.width.equalTo(@40); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-56); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(16); + }]; + + [_CalLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@28); + make.width.equalTo(@90); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(49); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-31); + }]; + + [_calories mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@18); + make.width.equalTo(@36); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(76); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-58); + }]; + +} + +@end diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDColumnChartView.h b/MRMobileRun/MRLogin/MRMineView/View/MGDColumnChartView.h new file mode 100644 index 0000000..4d0e62d --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDColumnChartView.h @@ -0,0 +1,35 @@ +// +// MGDColumnChartView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/18. +// + +#import + +NS_ASSUME_NONNULL_BEGIN +@class MGDColumnChartView; + +//协议 +@protocol MGDColumnChartViewDelegate + +//协议方法 +- (NSArray *_Nullable)columnChartTitleArrayYear:(NSString *_Nullable)year; + +- (NSArray *_Nullable)columnChartNumberArrayFor:(NSString *_Nullable)itemName index:(NSInteger)index year:(NSString *_Nonnull)year; + +- (void)changeYearClick:(MGDColumnChartView *_Nullable)chartView sender:(UIButton *_Nullable)sender; + +@end + +@interface MGDColumnChartView : UIView + +@property (nonatomic, weak) id delegate; + +@property (nonatomic, strong) NSString *yearName; + +- (void)reloadData; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDColumnChartView.m b/MRMobileRun/MRLogin/MRMineView/View/MGDColumnChartView.m new file mode 100644 index 0000000..a859f8e --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDColumnChartView.m @@ -0,0 +1,449 @@ +// +// MGDColumnChartView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/18. +// + +#import "MGDColumnChartView.h" +#import + +#define LINECOLOR [UIColor colorWithRed:85/255.0 green:213/255.0 blue:226/255.0 alpha:1.0] +#define BACKGROUNDCOLOR [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0] +#define COLUMNCHARTCOLOR [UIColor colorWithRed:255/255.0 green:92/255.0 blue:119/255.0 alpha:1.0] +#define XLABELCOLOR [UIColor colorWithRed:51/255.0 green:55/255.0 blue:57/255.0 alpha:1.0] +#define YLABELCOLOR [UIColor colorWithRed:136/255.0 green:136/255.0 blue:136/255.0 alpha:1.0] +#define topMargin 40 +#define leftMargin 25 +#define bottomMargin 25 +#define XLen screenWidth - 23 - 26 +#define YLen 163 + + + + +@interface MGDColumnChartView () { + CGFloat _itemBottomY; + CGFloat _oneItemH; + NSArray *_currentHeaderItem; + NSInteger _firstIndex; + bool _isLayoutChart; +} + +//月份滑动 +@property (nonatomic, strong) UIScrollView *headerView; +//月份按钮 +@property (nonatomic, strong) NSMutableArray *headerBtns; +//下划线 +@property (nonatomic, strong) UIView *linePointView; +//下划线宽度 +@property (nonatomic, assign) CGFloat linePointW; +//月份滑动高度 +@property (nonatomic, assign) CGFloat headerH; +//年份选择 +@property (nonatomic, strong) UIButton *yearLabel; +//柱形图滑动 +@property (nonatomic, strong) UIScrollView *ChartScrollView; +//柱形图 +@property (nonatomic, strong) UIView *chartView; +//柱形图柱子数组 +@property (nonatomic, strong) NSMutableArray *chartItems; + +@end + +@implementation MGDColumnChartView + +- (UIView *)linePointView +{ + if (_linePointView == nil) { + _linePointView = [[UIView alloc] init]; + _linePointView.frame = CGRectMake(0, 25, _linePointW, 4); + _linePointView.backgroundColor = LINECOLOR; + _linePointView.layer.cornerRadius = 2.0; + [self.headerView addSubview:_linePointView]; + } + return _linePointView; +} + +- (NSMutableArray *)headerBtns +{ + if (_headerBtns == nil) { + _headerBtns = [NSMutableArray array]; + } + return _headerBtns; +} + +- (NSMutableArray *)chartItems +{ + if (_chartItems == nil) { + _chartItems = [NSMutableArray array]; + } + return _chartItems; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + [self initChild]; + } + return self; +} + +- (void)initChild { + _linePointW = 42; + _isLayoutChart = false; + + _yearLabel = [UIButton buttonWithType:UIButtonTypeCustom]; + if (@available(iOS 11.0, *)) { + [_yearLabel setTitleColor:MGDtextXColor forState:UIControlStateNormal]; + } else { + // Fallback on earlier versions + } + _yearLabel.titleLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 15]; + [_yearLabel setImage:[UIImage imageNamed:@"矩形"] forState:UIControlStateNormal]; + _yearLabel.imageView.contentMode = UIViewContentModeScaleAspectFit; + _yearLabel.backgroundColor = [UIColor clearColor]; + [_yearLabel setTitleEdgeInsets:UIEdgeInsetsMake(0, -15, 0, 14)]; + [_yearLabel setImageEdgeInsets:UIEdgeInsetsMake(8, 36, 6, 0)]; + _yearLabel.backgroundColor = [UIColor clearColor]; + [_yearLabel addTarget:self action:@selector(yearClick:) forControlEvents:UIControlEventTouchUpInside]; + + _headerView = [[UIScrollView alloc] init]; + _headerView.backgroundColor = [UIColor clearColor]; + _headerView.showsHorizontalScrollIndicator = NO; + _headerView.showsVerticalScrollIndicator = NO; + _headerView.pagingEnabled = NO; + + _chartView = [[UIView alloc] init]; + _chartView.backgroundColor = [UIColor clearColor]; + + + _ChartScrollView = [[UIScrollView alloc] init]; + _ChartScrollView.decelerationRate = 0.15f; + _ChartScrollView.backgroundColor = [UIColor clearColor]; + _ChartScrollView.bounces = NO; + _ChartScrollView.showsHorizontalScrollIndicator = NO; + + if (@available(iOS 11.0, *)) { + self.backgroundColor = MGDColor1; + self.chartView.backgroundColor = MGDColor1; + } else { + // Fallback on earlier versions + } + + [self addSubview:_headerView]; + [self addSubview:_yearLabel]; + [self addSubview:_chartView]; + [self.chartView addSubview:_ChartScrollView]; + [self setFrame]; +} + +- (void)setFrame { + _yearLabel.frame = CGRectMake(screenWidth - 69, 5, 48, 21); + _headerView.frame = CGRectMake(0, 0, screenWidth - 218, 30); + _chartView.frame = CGRectMake(0, 30, screenWidth, 228); + _ChartScrollView.frame = CGRectMake(leftMargin + 1, 0, XLen, 228); + _ChartScrollView.contentSize = CGSizeMake(480, _ChartScrollView.frame.size.height); +} + + +- (void)yearClick:(UIButton *)sender +{ + if ([_delegate respondsToSelector:@selector(changeYearClick:sender:)]) { + [_delegate changeYearClick:self sender:sender]; + } +} + +- (void)setDelegate:(id)delegate { + _delegate = delegate; + + [self layoutHeaderItem]; + [self layoutChartView]; + [self clickItemIndex:_firstIndex]; +} + +- (void)setYearName:(NSString *)yearName +{ + _yearName = yearName; + [_yearLabel setTitle:yearName forState:UIControlStateNormal]; +} + +//------- 布局header +- (void)layoutHeaderItem +{ + if ([_delegate respondsToSelector:@selector(columnChartTitleArrayYear:)]) { + NSArray *items = [_delegate columnChartTitleArrayYear:_yearName]; + UIButton *lastBtn = nil; + NSInteger currentItem = 0; + if (items.count > 0) { + for (NSInteger i = 0; i < items.count; i++) { + UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; + [btn setTitle:items[i] forState:UIControlStateNormal]; + CGFloat btnx = lastBtn == nil ? 3 : CGRectGetMaxX(lastBtn.frame); + btn.frame = CGRectMake(btnx, 0, btn.frame.size.width + screenWidth * 0.143 , 30); + [self.headerView addSubview:btn]; + + lastBtn = btn; + [btn addTarget:self action:@selector(headerItemClick:) forControlEvents:UIControlEventTouchUpInside]; + if ([@"本月" isEqualToString:items[i]]) { + currentItem = i; + } + btn.tag = i; + [self.headerBtns addObject:btn]; + } + } + + self.headerView.contentSize = CGSizeMake(CGRectGetMaxX(lastBtn.frame), _headerH); + [self setSelectItem:self.headerBtns[currentItem] isAnima:NO]; + + _firstIndex = currentItem; + _currentHeaderItem = items; + } +} + +- (void)headerItemClick:(UIButton *)sender +{ + [self setSelectItem:sender isAnima:true]; +} + +- (void)clickItemIndex:(NSInteger)index +{ + UIButton *sender = self.headerBtns[index]; + [sender sendActionsForControlEvents:UIControlEventTouchUpInside]; +} + +- (void)setSelectItem:(UIButton *)sender isAnima:(BOOL)isAnima +{ + for (UIButton *senderTemp in self.headerBtns) { + [senderTemp setTitleColor:YLABELCOLOR forState:UIControlStateNormal]; + senderTemp.titleLabel.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 16]; + } + + CGFloat senderX = CGRectGetMinX(sender.frame); + CGFloat itemX = senderX + (sender.frame.size.width - _linePointW) * 0.5; + + CGRect lineFrame = self.linePointView.frame; + lineFrame.origin.x = itemX; + + if (isAnima) { + [UIView animateWithDuration:0.2 animations:^{ + self.linePointView.frame = lineFrame; + if (@available(iOS 11.0, *)) { + [sender setTitleColor:MGDTextColor1 forState:UIControlStateNormal]; + } else { + // Fallback on earlier versions + } + sender.titleLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 18]; + }]; + }else { + self.linePointView.frame = lineFrame; + [sender setTitleColor:XLABELCOLOR forState:UIControlStateNormal]; + } + + //停留的位置 + CGFloat senderCenterX = CGRectGetMidX(sender.frame); + + if (senderCenterX < self.headerView.frame.size.width * 0.5) { + [self.headerView setContentOffset:CGPointMake(0, 0) animated:isAnima]; + + }else if (senderCenterX > (self.headerView.contentSize.width - self.headerView.frame.size.width * 0.5)) { + [self.headerView setContentOffset:CGPointMake(self.headerView.contentSize.width - self.headerView.frame.size.width, 0) animated:isAnima]; + + }else { + CGFloat offsetX = senderCenterX - (self.headerView.frame.size.width * 0.5); + [self.headerView setContentOffset:CGPointMake(offsetX, 0) animated:isAnima]; + } + + [self changeChartShowName:sender.currentTitle index:sender.tag]; +} + +//------- 布局chart +- (void)layoutChartView +{ + CGFloat chartSizeH = self.chartView.frame.size.height; + CGFloat itemXMargin = screenWidth * 0.016; + CGFloat itemCountX = 31; + CGFloat itemCountY = 5; + CGFloat itemYH = (YLen - 6) / itemCountY; + CGFloat itemXW = screenWidth * 0.0213; + CGFloat YlabMargin = 15; + + //X轴 + CALayer *axisX = [self getSubLine:CGRectMake(leftMargin, topMargin + YLen, XLen , 1)]; + if (@available(iOS 11.0, *)) { + axisX.backgroundColor = MGDlineColor.CGColor; + } else { + // Fallback on earlier versions + } + [self.chartView.layer addSublayer:axisX]; + + //Y轴 + CALayer *axisY = [self getSubLine:CGRectMake(leftMargin, topMargin, 1, YLen)]; + if (@available(iOS 11.0, *)) { + axisY.backgroundColor = MGDlineColor.CGColor; + } else { + // Fallback on earlier versions + } + [self.chartView.layer addSublayer:axisY]; + + for (NSInteger i = 0; i < itemCountY; i++) { + //Y轴的灰色准线 + CALayer *itemY = [self getSubLine:CGRectMake(0, CGRectGetMinY(axisX.frame) - itemYH * (i + 1), _ChartScrollView.contentSize.width, 1)]; + [self.ChartScrollView.layer addSublayer:itemY]; + + //Y轴文字 + CATextLayer *labelY = [self getYLabel:[NSString stringWithFormat:@"%ld",(long)i+1] font:8 frame:CGRectMake(YlabMargin, itemY.frame.origin.y - 11, 5, 11)]; + [self.chartView.layer addSublayer:labelY]; + } + + NSArray *showXArr = @[@"1", @"5", @"10",@"20",@"15",@"25",@"30"]; + for (NSInteger i = 0; i < itemCountX; i++) { + //X轴的柱形 + CALayer *itemX = [self getLayer:COLUMNCHARTCOLOR frame:CGRectMake( 9 + (itemXMargin + itemXW) * i, 300, itemXW, CGRectGetMinY(axisX.frame))]; + itemX.cornerRadius = 2.0; + [self.ChartScrollView.layer addSublayer:itemX]; + + //X轴的文字 + NSString *currentIndex = [NSString stringWithFormat:@"%ld",(long)i+1]; + if ([showXArr containsObject: currentIndex]) { + CATextLayer *labelX = [self getXLabel:currentIndex font:8 frame:CGRectMake(itemX.frame.origin.x - 2, axisX.frame.origin.y + 1, 10, 11)]; + if (@available(iOS 11.0, *)) { + labelX.foregroundColor = MGDtextXColor.CGColor; + } else { + // Fallback on earlier versions + } + [self.ChartScrollView.layer addSublayer:labelX]; + } + + [self.chartItems addObject:itemX]; + } + + _itemBottomY = chartSizeH - leftMargin; + _oneItemH = itemYH; + + + CATextLayer *pointZero = [self getYLabel:@"0" font:8 frame:CGRectMake(15,196,5,11)]; + + CATextLayer *messageX = [self getData:@"日期" font:8 frame:CGRectMake(screenWidth - 31, CGRectGetMaxY(axisX.frame) + 1,16,11)]; + + CATextLayer *messageY = [self getYLabel:@"千米" font:11 frame:CGRectMake(15,14,22,16)]; + + [self.chartView.layer addSublayer:pointZero]; + [self.chartView.layer addSublayer:messageX]; + [self.chartView.layer addSublayer:messageY]; +} + + +- (CATextLayer *)getYLabel:(NSString *)str font:(NSInteger)font frame:(CGRect)frame { + CATextLayer *label = [[CATextLayer alloc] init]; + label.string = str; + label.font = (__bridge CFTypeRef _Nullable)@"PingFangSC-Regular"; + label.fontSize = font; + label.frame = frame; + label.alignmentMode = @"center"; + label.contentsScale = 3; + label.foregroundColor = YLABELCOLOR.CGColor; + return label; +} + +- (CATextLayer *)getXLabel:(NSString *)str font:(NSInteger)font frame:(CGRect)frame { + CATextLayer *label = [[CATextLayer alloc] init]; + label.string = str; + label.font = (__bridge CFTypeRef _Nullable)@"PingFangSC-Medium"; + label.fontSize = font; + label.frame = frame; + label.alignmentMode = @"center"; + label.contentsScale = 3; + if (@available(iOS 11.0, *)) { + label.foregroundColor = MGDtextXColor.CGColor; + } else { + // Fallback on earlier versions + } + return label; +} + +- (CATextLayer *)getData:(NSString *)str font:(NSInteger)font frame:(CGRect)frame { + CATextLayer *label = [[CATextLayer alloc] init]; + label.string = str; + label.font = (__bridge CFTypeRef _Nullable)@"PingFangSC-Medium"; + label.fontSize = font; + label.frame = frame; + label.alignmentMode = @"center"; + label.contentsScale = 3; + if (@available(iOS 11.0, *)) { + label.backgroundColor = MGDColor1.CGColor; + label.foregroundColor = MGDtextXColor.CGColor; + } else { + // Fallback on earlier versions + } + return label; +} + +- (CALayer *)getLayer:(UIColor *)color frame:(CGRect)frame { + CALayer *layer = [[CALayer alloc] init]; + layer.backgroundColor = color.CGColor; + layer.frame = frame; + return layer; +} + +- (CALayer *)getSubLine:(CGRect)frame { + CALayer *layer = [[CALayer alloc] init]; + if (@available(iOS 11.0, *)) { + layer.backgroundColor = MGDLineColor1.CGColor; + } else { + // Fallback on earlier versions + } + layer.frame = frame; + return layer; +} + + +- (CGFloat)getChartH:(CGFloat)chartH +{ + CGFloat itemH = _oneItemH * chartH; + if (chartH > 5.3) { + itemH = _oneItemH * 5.3; + } + return itemH; +} + +- (void)changeChartShowName:(NSString *)name index:(NSInteger) index +{ + if (!_isLayoutChart && [_delegate respondsToSelector:@selector(columnChartNumberArrayFor:index:year:)]) { + NSArray *arr = [_delegate columnChartNumberArrayFor:name index:index year:_yearName]; + if (self.chartItems.count > 0) { + _isLayoutChart = YES; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + self->_isLayoutChart = NO; + }); + [UIView animateWithDuration:0.1 animations:^{ + NSInteger cnt = arr.count; + NSInteger indexTemp = 0; + for (CALayer *item in self.chartItems) { + if (indexTemp <= cnt) { + CGFloat itemH = [self getChartH:[arr[indexTemp] floatValue]]; + item.frame = CGRectMake(item.frame.origin.x, self->_itemBottomY - itemH, item.frame.size.width, itemH); + }else { + //高度设置为0 + CGFloat itemH = [self getChartH:0]; + item.frame = CGRectMake(item.frame.origin.x, self->_itemBottomY - itemH, item.frame.size.width, itemH); + } + indexTemp++; + } + } completion:^(BOOL finished) { + }]; + } + } +} +//换页面时重新显示 +- (void)reloadData +{ + [[self.headerView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; + [self.headerView addSubview:self.linePointView]; + [self.headerBtns removeAllObjects]; + [self layoutHeaderItem]; + [self clickItemIndex:_firstIndex]; +} + +@end + diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDMiddleView.h b/MRMobileRun/MRLogin/MRMineView/View/MGDMiddleView.h new file mode 100644 index 0000000..a70cfa7 --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDMiddleView.h @@ -0,0 +1,24 @@ +// +// MGDMiddleView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDMiddleView : UIView + +@property(nonatomic,strong) UIView *backView; + +@property(nonatomic,strong) UIView *dotView; + +@property(nonatomic,strong) UILabel *recordLab; + +@property(nonatomic,strong) UIButton *moreBtn; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDMiddleView.m b/MRMobileRun/MRLogin/MRMineView/View/MGDMiddleView.m new file mode 100644 index 0000000..4e6389c --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDMiddleView.m @@ -0,0 +1,102 @@ +// +// MGDMiddleView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import "MGDMiddleView.h" +#import + +#define DOTCOLOR [UIColor colorWithRed:123/255.0 green:183/255.0 blue:196/255.0 alpha:1.0] +#define RECORDCOLOR [UIColor colorWithRed:65/255.0 green:68/255.0 blue:72/255.0 alpha:1.0] +#define BTNCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] + +@implementation MGDMiddleView + +-(instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + + UIView *backView = [[UIView alloc] init]; + self.backView = backView; + [self addSubview:backView]; + + UIView *dotView = [[UIView alloc] init]; + self.dotView = dotView; + _dotView.backgroundColor = DOTCOLOR; + self.dotView.layer.masksToBounds = YES; + self.dotView.layer.cornerRadius = 4.0; + [self.backView addSubview:dotView]; + + UILabel *recordLab = [[UILabel alloc] init]; + self.recordLab = recordLab; + [self.backView addSubview:recordLab]; + + //测试用 + _recordLab.text = @"运动记录"; + + _recordLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _recordLab.textAlignment = NSTextAlignmentLeft; + if (@available(iOS 11.0, *)) { + self.recordLab.textColor = MGDTextColor2; + } else { + // Fallback on earlier versions + } + + UIButton *moreBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + self.moreBtn = moreBtn; + [self.backView addSubview:moreBtn]; + [self.moreBtn setTitle:@"查看更多" forState:UIControlStateNormal]; + [self.moreBtn setTintColor:BTNCOLOR]; + self.moreBtn.titleLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 12]; + } + return self; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + if (kIs_iPhoneX) { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth * 0.0271); + make.width.mas_equalTo(screenWidth); + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + }]; + + [self setMiddleFrame]; + }else { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth * 0.033); + make.width.mas_equalTo(screenWidth); + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + }]; + + [self setMiddleFrame]; + + } +} + +- (void)setMiddleFrame { + [_dotView mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.equalTo(@8); + make.height.equalTo(@8); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(8); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(15); + }]; + + [_recordLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(31); + make.width.equalTo(@72); + make.height.equalTo(@22); + }]; + + [_moreBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-15); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(4); + make.width.equalTo(@51); + make.height.equalTo(@17); + }]; +} +@end diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDRecordTableView.h b/MRMobileRun/MRLogin/MRMineView/View/MGDRecordTableView.h new file mode 100644 index 0000000..0a5d6a8 --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDRecordTableView.h @@ -0,0 +1,18 @@ +// +// MGDRecordTableView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/14. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDRecordTableView : UITableView + +@property(nonatomic,strong) UITableView *recordTableView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDRecordTableView.m b/MRMobileRun/MRLogin/MRMineView/View/MGDRecordTableView.m new file mode 100644 index 0000000..afbc2f9 --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDRecordTableView.m @@ -0,0 +1,32 @@ +// +// MGDRecordTableView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/14. +// + +#import "MGDRecordTableView.h" +#import + +@implementation MGDRecordTableView + +-(instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + UITableView *recordTableView = [[UITableView alloc] init]; + self.recordTableView = recordTableView; + self.recordTableView.backgroundColor = [UIColor clearColor]; + [self addSubview:recordTableView]; + } + return self; +} + +//- (void)layoutSubviews { +// [super layoutSubviews]; +// [_recordTableView mas_makeConstraints:^(MASConstraintMaker *make) { +// make.height.mas_equalTo(screenHeigth - 394); +// make.width.mas_equalTo(screenWidth); +// make.top.mas_equalTo(self.mas_top); +// }]; +//} + +@end diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableView.h b/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableView.h new file mode 100644 index 0000000..7b05713 --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableView.h @@ -0,0 +1,18 @@ +// +// MGDSportTableView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDSportTableView : UITableView + +@property(nonatomic,strong) UITableView *sportTableView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableView.m b/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableView.m new file mode 100644 index 0000000..5f6898a --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableView.m @@ -0,0 +1,38 @@ +// +// MGDSportTableView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import "MGDSportTableView.h" +#import + +@implementation MGDSportTableView + + + +-(instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + UITableView *sportTableView = [[UITableView alloc] init]; + self.sportTableView = sportTableView; + [self addSubview:sportTableView]; + self.sportTableView.backgroundColor = [UIColor redColor]; + } + return self; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + [_sportTableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth - 379); + make.width.mas_equalTo(screenWidth); + make.top.mas_equalTo(self.mas_top); + }]; +} + + + + +@end + diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableViewCell.h b/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableViewCell.h new file mode 100644 index 0000000..afa60dc --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableViewCell.h @@ -0,0 +1,36 @@ +// +// MGDSportTableViewCell.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDSportTableViewCell : UITableViewCell + +@property (nonatomic,strong) UILabel *dayLab; + +@property (nonatomic,strong) UILabel *timeLab; + +@property (nonatomic,strong) UILabel *kmLab; + +@property (nonatomic,strong) UILabel *kmUnit; + +@property (nonatomic,strong) UILabel *minLab; + +@property (nonatomic,strong) UILabel *minUnit; + +@property (nonatomic,strong) UILabel *calLab; + +@property (nonatomic,strong) UILabel *calUnit; + +@property (nonatomic,strong) UIView *cellView; + +@property (nonatomic,strong) UIImageView *arrowView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableViewCell.m b/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableViewCell.m new file mode 100644 index 0000000..1be5eaa --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDSportTableViewCell.m @@ -0,0 +1,192 @@ +// +// MGDSportTableViewCell.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import "MGDSportTableViewCell.h" +#import + +#define CELLCOLOR [UIColor colorWithRed:252/255.0 green:252/255.0 blue:252/255.0 alpha:1.0] +#define TEXTCOLOR [UIColor colorWithRed:51/255.0 green:55/255.0 blue:57/255.0 alpha:1.0] +#define UNITCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] + +@implementation MGDSportTableViewCell + + + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { + [self BuildUI]; + [self setFrame]; + self.selectionStyle = UITableViewCellSelectionStyleNone; + } + return self; +} + +- (void)BuildUI { + UILabel *dayLab = [[UILabel alloc] init]; + self.dayLab = dayLab; + [self.contentView addSubview:dayLab]; + _dayLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 17]; + _dayLab.textAlignment = NSTextAlignmentRight; + + UILabel *timeLab = [[UILabel alloc] init]; + self.timeLab = timeLab; + [self.contentView addSubview:timeLab]; + _timeLab.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 10]; + _timeLab.textColor = UNITCOLOR; + _timeLab.textAlignment = NSTextAlignmentRight; + + UIView *cellView = [[UIView alloc] init]; + self.cellView = cellView; + self.cellView.layer.cornerRadius = 12.0; + [self.contentView addSubview:cellView]; + + UILabel *kmLab = [[UILabel alloc] init]; + self.kmLab = kmLab; + [self.cellView addSubview:kmLab]; + _kmLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _kmLab.textAlignment = NSTextAlignmentCenter; + + UILabel *kmUnit = [[UILabel alloc] init]; + self.kmUnit = kmUnit; + [self.cellView addSubview:kmUnit]; + _kmUnit.text = @"公里"; + _kmUnit.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 11]; + _kmUnit.textColor = UNITCOLOR; + _kmUnit.textAlignment = NSTextAlignmentCenter; + + UILabel *minLab = [[UILabel alloc] init]; + self.minLab = minLab; + [self.cellView addSubview:minLab]; + //测试用数据 + _minLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _minLab.textAlignment = NSTextAlignmentCenter; + + UILabel *minUnit = [[UILabel alloc] init]; + self.minUnit = minUnit; + [self.cellView addSubview:minUnit]; + _minUnit.text = @"时间"; + _minUnit.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 11]; + _minUnit.textColor = UNITCOLOR; + _minUnit.textAlignment = NSTextAlignmentCenter; + + UILabel *calLab = [[UILabel alloc] init]; + self.calLab = calLab; + [self.cellView addSubview:calLab]; + _calLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _calLab.textAlignment = NSTextAlignmentCenter; + + UILabel *calUnit = [[UILabel alloc] init]; + self.calUnit = calUnit; + [self.cellView addSubview:calUnit]; + _calUnit.text = @"千卡"; + _calUnit.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 11]; + _calUnit.textColor = UNITCOLOR; + _calUnit.textAlignment = NSTextAlignmentCenter; + + UIImageView *arrowView = [[UIImageView alloc] init]; + self.arrowView = arrowView; + [self.cellView addSubview:arrowView]; + self.arrowView.image = [UIImage imageNamed:@"arraw"]; + + if (@available(iOS 11.0, *)) { + self.contentView.backgroundColor = MGDColor3; + self.dayLab.textColor = MGDTextColor1; + self.cellView.backgroundColor = MGDColor1; + self.kmLab.textColor = MGDTextColor1; + self.minLab.textColor = MGDTextColor1; + self.calLab.textColor = MGDTextColor1; + } else { + // Fallback on earlier versions + } +} + +- (void)setFrame { + [_dayLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.contentView.mas_top); + make.right.mas_equalTo(self.cellView.mas_left).mas_offset(-11); + make.width.equalTo(@55); + make.height.equalTo(@24); + }]; + + [_timeLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.dayLab.mas_bottom).mas_offset(-1); + make.right.mas_equalTo(self.dayLab); + make.width.equalTo(@30); + make.height.equalTo(@14); + }]; + + [_cellView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.contentView.mas_top); + make.left.mas_equalTo(self.contentView.mas_left).mas_offset(80); + make.right.mas_equalTo(self.contentView.mas_right); + make.height.equalTo(@60); + }]; + + [_kmLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.cellView.mas_top).mas_offset(13); + make.left.mas_equalTo(self.cellView.mas_left).mas_offset(7); + make.width.equalTo(@70); + make.height.equalTo(@18); + }]; + + [_kmUnit mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.cellView.mas_top).mas_offset(32); + make.left.mas_equalTo(self.cellView.mas_left).mas_offset(23); + make.width.equalTo(@36); + make.height.equalTo(@14); + }]; + + [_minLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.cellView.mas_top).mas_offset(13); + make.left.mas_equalTo(self.cellView.mas_left).mas_offset(99); + make.right.mas_equalTo(self.cellView.mas_right).mas_offset(-126); + make.height.equalTo(@18); + }]; + + [_minUnit mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.cellView.mas_top).mas_offset(32); + make.left.mas_equalTo(self.cellView.mas_left).mas_offset(115); + make.right.mas_equalTo(self.cellView.mas_right).mas_offset(-144); + make.height.equalTo(@14); + }]; + + [_calLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.cellView.mas_top).mas_offset(13); + make.right.mas_equalTo(self.cellView.mas_right).mas_offset(-34); + make.width.equalTo(@70); + make.height.equalTo(@18); + }]; + + [_calUnit mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.cellView.mas_top).mas_offset(32); + make.right.mas_equalTo(self.cellView.mas_right).mas_offset(-51); + make.width.equalTo(@36); + make.height.equalTo(@14); + }]; + + [_arrowView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.cellView.mas_top).mas_offset(23); + make.right.mas_equalTo(self.cellView.mas_right).mas_offset(-17); + make.width.equalTo(@14.14); + make.height.equalTo(@14.14); + }]; +} + + + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +@end diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDTopView.h b/MRMobileRun/MRLogin/MRMineView/View/MGDTopView.h new file mode 100644 index 0000000..e4540d4 --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDTopView.h @@ -0,0 +1,24 @@ +// +// MGDTopView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/9. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDTopView : UIView + +@property(nonatomic,strong) UIView *topView; + +@property(nonatomic,strong) UIImageView *userIcon; + +@property(nonatomic,strong) UILabel *userName; + +@property(nonatomic,strong) UILabel *personalSign; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRLogin/MRMineView/View/MGDTopView.m b/MRMobileRun/MRLogin/MRMineView/View/MGDTopView.m new file mode 100644 index 0000000..378ad68 --- /dev/null +++ b/MRMobileRun/MRLogin/MRMineView/View/MGDTopView.m @@ -0,0 +1,136 @@ +// +// MGDTopView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/9. +// + +#import "MGDTopView.h" +#import +#import "UIImageView+WebCache.h" +#define BACGROUNDCOLOR [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0]; +#define SHAWDOWCOLOR [UIColor colorWithRed:136/255.0 green:154/255.0 blue:181/255.0 alpha:0.05] + +@implementation MGDTopView + +-(instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + UIView *topView = [[UIView alloc] init]; + self.topView = topView; + if (@available(iOS 11.0, *)) { + self.topView.backgroundColor = MGDColor1; + } else { + // Fallback on earlier versions + } + //self.topView.backgroundColor = BACGROUNDCOLOR; + self.topView.layer.cornerRadius = 50; + self.topView.layer.shadowColor = SHAWDOWCOLOR.CGColor; + self.topView.layer.shadowOffset = CGSizeMake(0,3); + self.topView.layer.shadowOpacity = 1; + self.topView.layer.shadowRadius = 6; + [self addSubview:topView]; + + UIImageView *userIcon = [[UIImageView alloc] init]; + self.userIcon = userIcon; + self.userIcon.layer.masksToBounds = YES; + self.userIcon.layer.cornerRadius = 36.0; + self.userIcon.contentMode = UIViewContentModeScaleToFill; + [self.topView addSubview:userIcon]; + + UILabel *username = [[UILabel alloc] init]; + self.userName = username; + [self.topView addSubview:username]; + _userName.numberOfLines = 0; + _userName.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 18]; + // _userName.textColor = [UIColor colorWithRed:51/255.0 green:55/255.0 blue:57/255.0 alpha:1.0]; + if (@available(iOS 11.0, *)) { + self.userName.textColor = MGDTextColor1; + } else { + // Fallback on earlier versions + } + + UILabel *personalSign = [[UILabel alloc] init]; + self.personalSign = personalSign; + [self.topView addSubview:personalSign]; + _personalSign.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 13]; + _personalSign.textColor = [UIColor colorWithRed:160/255.0 green:160/255.0 blue:160/255.0 alpha:1.0]; + _personalSign.numberOfLines = 0; + + [self userInfo]; + } + return self; +} + +- (void)userInfo { + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *nickName = [user objectForKey:@"nickname"]; + NSString *imageUrl = [user objectForKey:@"avatar_url"]; + NSString *signature = [user objectForKey:@"signature"]; + [self.userIcon sd_setImageWithURL:[NSURL URLWithString:imageUrl]]; + self.userName.text = nickName; + self.personalSign.text = signature; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + if (kIs_iPhoneX) { + [_topView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self); + make.right.mas_equalTo(self); + make.top.mas_equalTo(self.mas_top); + make.height.equalTo(@136); + }]; + + [_userIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@72); + make.width.equalTo(@72); + make.left.mas_equalTo(self.topView.mas_left).mas_offset(16); + make.top.mas_equalTo(self.topView.mas_top).mas_offset(48); + }]; + + [_userName mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@25); + make.leading.lessThanOrEqualTo(self.topView.mas_leading).mas_offset(116); + make.top.lessThanOrEqualTo(self.topView.mas_top).mas_offset(59); + make.width.mas_lessThanOrEqualTo(screenWidth - 116); + }]; + + [_personalSign mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@18); + make.leading.lessThanOrEqualTo(self.topView.mas_leading).mas_offset(116); + make.width.mas_lessThanOrEqualTo(screenWidth - 116); + make.top.lessThanOrEqualTo(self.topView.mas_top).mas_offset(84); + }]; + }else { + [_topView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self); + make.right.mas_equalTo(self); + make.top.mas_equalTo(self.mas_top); + make.height.mas_equalTo(111); + }]; + + [_userIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@72); + make.width.equalTo(@72); + make.left.mas_equalTo(self.topView.mas_left).mas_offset(16); + make.top.mas_equalTo(self.topView.mas_top).mas_offset(23); + }]; + + [_userName mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@25); + make.leading.lessThanOrEqualTo(self.topView.mas_leading).mas_offset(116); + make.top.lessThanOrEqualTo(self.topView.mas_top).mas_offset(34); + make.width.mas_lessThanOrEqualTo(screenWidth - 116); + }]; + + [_personalSign mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@18); + make.leading.lessThanOrEqualTo(self.topView.mas_leading).mas_offset(116); + make.width.mas_lessThanOrEqualTo(screenWidth - 116); + make.top.lessThanOrEqualTo(self.topView.mas_top).mas_offset(59); + }]; + } +} + +@end diff --git a/MRMobileRun/MRLogin/ZYLLoginView.m b/MRMobileRun/MRLogin/ZYLLoginView.m index 1277510..fdab869 100644 --- a/MRMobileRun/MRLogin/ZYLLoginView.m +++ b/MRMobileRun/MRLogin/ZYLLoginView.m @@ -84,21 +84,27 @@ - (void)initTextFileds{ make.width.mas_equalTo(200); make.height.mas_equalTo(28); }]; + if (@available(iOS 11.0, *)) { + self.passwordField.textColor = [UIColor blackColor]; + self.usernameField.textColor = [UIColor blackColor]; + } else { + // Fallback on earlier versions + } } - (void)initNoticeLabel{ self.noticeLab = [[UILabel alloc] init]; - self.noticeLab.numberOfLines = 1; + self.noticeLab.numberOfLines = 0; self.noticeLab.font = [UIFont fontWithName:@"PingFangSC-Regular" size:12]; self.noticeLab.textColor = COLOR_WITH_HEX(0xB9BCBE); - self.noticeLab.text = @"身份证号中X为大写"; + self.noticeLab.text = @"身份证号中X为大写\n2020届以前密码为身份证后六位\n2020届密码为统一验证码后六位"; self.noticeLab.textAlignment = NSTextAlignmentLeft; [self addSubview: self.noticeLab]; [self.noticeLab mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.passwordIcon.mas_bottom).mas_offset(12); make.left.equalTo(self.passwordIcon.mas_right).mas_offset(24); - make.width.mas_equalTo(110); - make.height.mas_equalTo(14); + make.width.mas_equalTo(250); + make.height.mas_equalTo(64); }]; } diff --git a/MRMobileRun/MRLogin/ZYLLoginViewController.m b/MRMobileRun/MRLogin/ZYLLoginViewController.m index 75d8c7d..5f27473 100644 --- a/MRMobileRun/MRLogin/ZYLLoginViewController.m +++ b/MRMobileRun/MRLogin/ZYLLoginViewController.m @@ -10,11 +10,13 @@ #import "MRTabBarController.h" #import "MRLoginModel.h" #import "MBProgressHUD.h" +#import "MGDTabBarViewController.h" @interface ZYLLoginViewController () @property (nonatomic, strong) ZYLLoginView *loginView; @property (nonatomic,strong) MRLoginModel *loginModel; @property (nonatomic,strong) MBProgressHUD *loginProgress; +@property (nonatomic,strong) MBProgressHUD *waitProgress; @end @implementation ZYLLoginViewController @@ -32,28 +34,65 @@ - (void)Notification{ //登录的广播 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginSuccess:) name:@"isLoginSuccess" object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginFail:) name:@"isLoginFail" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginFailNoClient:) name:@"isLoginFailNoClient" object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginFailErrorData:) name:@"isLoginFailErrorData" object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginFailNoData:) name:@"isLoginFailNoData" object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginFailTimeOut:) name:@"isLoginFailTimeOut" object:nil]; } -- (void)loginFail:(NSNotification*)notification{ +- (void)loginFailNoClient:(NSNotification*)notification{ + [self.waitProgress removeFromSuperview]; self.loginProgress = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; - //登录失败后 [self.loginView.loginBtn setEnabled:YES]; self.loginProgress.mode = MBProgressHUDModeText; - self.loginProgress.label.text = @" 登录失败 "; - [self.loginProgress hideAnimated:YES afterDelay:1]; + self.loginProgress.label.text = @" 网络连接错误,请重新连接网络 "; + [self.loginProgress hideAnimated:YES afterDelay:2.0]; +} + +- (void)loginFailErrorData:(NSNotification*)notification{ + [self.waitProgress removeFromSuperview]; + self.loginProgress = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + [self.loginView.loginBtn setEnabled:YES]; + self.loginProgress.mode = MBProgressHUDModeText; + self.loginProgress.label.text = @" 账号密码输入错误 "; + [self.loginProgress hideAnimated:YES afterDelay:2.0]; +} + +- (void)loginFailNoData:(NSNotification*)notification{ + //[self.waitProgress removeFromSuperview]; + self.loginProgress = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + [self.loginView.loginBtn setEnabled:YES]; + self.loginProgress.mode = MBProgressHUDModeText; + self.loginProgress.label.text = @" 账号密码为空 "; + [self.loginProgress hideAnimated:YES afterDelay:2.0]; +} + +- (void)loginFailTimeOut:(NSNotification*)notification{ + self.loginProgress = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + [self.loginView.loginBtn setEnabled:YES]; + self.loginProgress.mode = MBProgressHUDModeText; + self.loginProgress.label.text = @" 连接超时 请检查网络 "; + [self.loginProgress hideAnimated:YES afterDelay:2.0]; } - (void)loginSuccess:(NSNotification*)notification{ [self.loginProgress hideAnimated:YES]; - MRTabBarController *mainVC = [[MRTabBarController alloc] init]; + MGDTabBarViewController *mainVC = [[MGDTabBarViewController alloc] init]; UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController: mainVC]; + //点击登录后收起键盘 [UIApplication sharedApplication].keyWindow.rootViewController = nav; //登录成功后进入主界面 NSLog(@"登陆成功"); } +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + [self.view endEditing:YES]; +} + #pragma mark - click event - (void)clickLoginButton{ @@ -61,15 +100,18 @@ - (void)clickLoginButton{ [self.loginModel postRequestWithStudentID:self.loginView.usernameField.text andPassword:self.loginView.passwordField.text]; //传入登录的数据 - - if (!([self.loginView.usernameField.text length] != 10 || [self.loginView.passwordField.text length] != 6)) - { - self.loginProgress = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; - self.loginProgress.mode = MBProgressHUDModeIndeterminate; - self.loginProgress.label.text = @" 正在登录 "; - self.loginProgress.bezelView.alpha = 0.8; - [self.loginProgress hideAnimated:YES afterDelay:0.5]; + if (!([self.loginView.usernameField.text length] != 0 && [self.loginView.passwordField.text length] != 0)) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"isLoginFailNoData" object:nil]; } + else { + self.waitProgress = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + self.waitProgress.mode = MBProgressHUDModeIndeterminate; + self.waitProgress.label.text = @" 正在登录 "; + self.waitProgress.bezelView.alpha = 0.8; + [self.waitProgress hideAnimated:YES afterDelay:30.0]; + } + [[[UIApplication sharedApplication] keyWindow] endEditing:YES]; + } #pragma mark - lazyload @@ -82,5 +124,4 @@ - (ZYLLoginView *)loginView{ } return _loginView; } - @end diff --git a/MRMobileRun/MRMainView/GYYHealthManager.h b/MRMobileRun/MRMainView/GYYHealthManager.h new file mode 100644 index 0000000..2c92a28 --- /dev/null +++ b/MRMobileRun/MRMainView/GYYHealthManager.h @@ -0,0 +1,39 @@ +// +// GYYHealthTableViewCell.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/7/9. +// + +#import +#import + +/** + xcodeproj - TARGETS - Signing & Capabilities - + Capability - HealthKit + + 开启HealthKit之后,在info.plist中增加 Privacy - Health Share Usage Description 与 Privacy - Health Update Usage Description,内容如实填写。 + */ + +NS_ASSUME_NONNULL_BEGIN + +@interface GYYHealthManager : NSObject + +@property (nonatomic, strong) HKHealthStore *healthStore; + ++ (id)shareInstance; + +//权限验证 +- (void)authorizeHealthKit:(void(^)(BOOL success, NSError *error))compltion; + +//获取步数 +- (void)getStepCountIsToday:(BOOL)isToday completion:(void(^)(double value, NSError *error))completion; + +//跑步界面获取步数 +- (void)getStepsRunningCompletion:(void(^)(int value, NSError *error))completion; + +//获取阶梯数 +- (void)getStairIsToday:(BOOL)isToday completion:(void(^)(double value, NSError *error))completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMainView/GYYHealthManager.m b/MRMobileRun/MRMainView/GYYHealthManager.m new file mode 100644 index 0000000..5211b08 --- /dev/null +++ b/MRMobileRun/MRMainView/GYYHealthManager.m @@ -0,0 +1,239 @@ +// +// GYYHealthTableViewCell.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/7/9. +// + +#import "GYYHealthManager.h" +#import + +#define HKVersion [[[UIDevice currentDevice] systemVersion] doubleValue] //取系统版本号 +#define CustomHealthErrorDomain @"com.sdqt.healthError" + +@implementation GYYHealthManager + ++ (id)shareInstance { //单例 程序启动之后,全局通用 + static id manager; //只开辟一次空间 存储在静态空间 + static dispatch_once_t onceToken; //GCD + dispatch_once(&onceToken, ^{ + manager = [[[self class] alloc] init]; + }); + return manager; +} + +//检查是否支持获取健康数据 +- (void)authorizeHealthKit:(void(^)(BOOL success, NSError *error))compltion{ + if (HKVersion >= 8.0) { + if (![HKHealthStore isHealthDataAvailable]) { + NSLog(@"该设备不支持HealthKit"); + }else{ + //只需要初始化一次 + if(self.healthStore == nil) + self.healthStore = [[HKHealthStore alloc] init]; + + //组装需要读写的数据类型 + NSSet *writeDataTypes = [self dataTypesToWrite]; + NSSet *readDataTypes = [self dataTypesRead]; + + //注册需要读写的数据类型,也可以在"设置 - 健康"中重新修改 + //ShareTypes 写的内容 + //readTypes 读的内容 + [self.healthStore requestAuthorizationToShareTypes:writeDataTypes readTypes:readDataTypes completion:^(BOOL success, NSError *error) { + // success = 0 1 + if (compltion != nil) { + NSLog(@"error->%@", error.localizedDescription); + compltion(success, error); + } + }]; + } + } else { + NSLog(@"iOS 系统低于8.0"); + } +} + +//获取步数 +- (void)getStepCountIsToday:(BOOL)isToday completion:(void(^)(double value, NSError *error))completion{ + //1.确定类型 HKQuantityTypeIdentifierStepCount + HKQuantityType *stepType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]; + //2.确定检索s + NSSortDescriptor *start = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierStartDate ascending:NO]; + NSSortDescriptor *end = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierEndDate ascending:NO]; + + HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType:stepType predicate:[GYYHealthManager predicateForSamplesToday:isToday] limit:HKObjectQueryNoLimit sortDescriptors:@[start, end] resultsHandler:^(HKSampleQuery *query, NSArray *results, NSError *error) { + + if(error){ + completion(0,error); + }else{ + NSInteger totleSteps = 0; + for(HKQuantitySample *quantitySample in results){ + HKQuantity *quantity = quantitySample.quantity; + HKUnit *heightUnit = [HKUnit countUnit]; + double usersHeight = [quantity doubleValueForUnit:heightUnit]; + totleSteps += usersHeight; + } + completion(totleSteps, error); + } + }]; + [self.healthStore executeQuery:query]; +} + +/** + * 跑步页面获取步数来计算吧步频 + */ +- (void)getStepsRunningCompletion:(void(^)(int value, NSError *error))completion{ + //获取这一分钟内的步数 + //1.查询采样信息 + HKSampleType *sampleType = [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]; + + //NSSortDescriptors用来告诉healthStore怎么样将结果排序。 + NSSortDescriptor *start = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierStartDate ascending:NO]; + NSSortDescriptor *end = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierEndDate ascending:NO]; + + NSDate *now = [NSDate date]; //现在的时间 + //一分钟之前的时间 + NSDate *laterOneMinut = [NSDate dateWithTimeIntervalSinceNow:-60]; + + NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:laterOneMinut endDate:now options:HKQueryOptionNone]; + + + + HKSampleQuery *sampQuery = [[HKSampleQuery alloc] initWithSampleType:sampleType predicate:predicate limit:0 sortDescriptors:@[start,end] resultsHandler:^(HKSampleQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable results, NSError * _Nullable error) { + NSLog(@"resultCount = %lu result = %@",(unsigned long)results.count,results); + + //设置一个int型变量来作为步数统计 + int allStepCount = 0; + if (error) { + completion(0,error); + }else{ + for (int i = 0; i < results.count; i++) { + //把结果转换为字符串类型 + HKQuantitySample *result = results[i]; + HKQuantity *quantity = result.quantity; + NSMutableString *stepCount = (NSMutableString *)quantity; + NSString *stepStr =[ NSString stringWithFormat:@"%@",stepCount]; + //获取51 count此类字符串前面的数字 + NSString *str = [stepStr componentsSeparatedByString:@" "][0]; + int stepNum = [str intValue]; + NSLog(@"%d",stepNum); + //把这一分钟内的所有步数加起来 + allStepCount = allStepCount + stepNum; + } + completion(allStepCount,error); + } + }]; + //执行查询 + [self.healthStore executeQuery:sampQuery]; +} + +//获取阶梯数 +- (void)getStairIsToday:(BOOL)isToday completion:(void(^)(double value, NSError *error))completion{ + //1.要检索的数据类型 + HKQuantityType *stairType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierFlightsClimbed]; //用系统方法,拿quantity,阶梯类型 + //2.数据的排序描述 + NSSortDescriptor *start = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierStartDate ascending:NO]; //渐进 + NSSortDescriptor *end = [NSSortDescriptor sortDescriptorWithKey:HKSampleSortIdentifierEndDate ascending:NO]; ////NSSortDescriptors用来告诉healthStore怎么样将结果排序。 我们这里用起止时间 + + /* + @param sampleType 要检索的数据类型。 + @param predicate 数据应该匹配的基准。3 配置系统要求的NSPredicate 类型的参数 + 4 @param limit 返回的最大数据条数 HKObjectQueryNoLimit = 0 系统静态 0就是没有限制 + @param sortDescriptors 数据的排序描述 + @param resultsHandler 结束后返回结果 + */ + HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType:stairType predicate:[GYYHealthManager predicateForSamplesToday:isToday] limit:HKObjectQueryNoLimit sortDescriptors:@[start, end] resultsHandler:^(HKSampleQuery * _Nonnull query, NSArray<__kindof HKSample *> * _Nullable results, NSError * _Nullable error) { + + if(error) { + completion(0,error); + } else { + //健康根据时间段记录 会有很多段记录 遍历results集合 取到quantitySample 样例 + double totleSteps = 0; + //5.拿到系统返回的数据集合 + for(HKQuantitySample *quantitySample in results) { + HKQuantity *quantity = quantitySample.quantity; + HKUnit *countUnit = [HKUnit countUnit]; + double usersHeight = [quantity doubleValueForUnit:countUnit]; + totleSteps += usersHeight; // totleSteps = totleSteps + usersHeight; + } + completion(totleSteps, error); + } + }]; + [self.healthStore executeQuery:query]; +} + ++ (NSPredicate *)predicateForSamplesToday:(BOOL)isToday{ + NSCalendar *calendar = [NSCalendar currentCalendar]; //拿日历 + NSDate *now = [NSDate date]; //获取当前date + NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:now]; //date 组件 + [components setHour:0]; // 2020-07-13 00:00:00 + [components setMinute:0]; + [components setSecond:0]; + + if (isToday) { + NSDate *startDate = [calendar dateFromComponents:components]; //2020-07-13 00:00:00、 + //计数单位 天 + NSDate *endDate = [calendar dateByAddingUnit:NSCalendarUnitDay value:1 toDate:startDate options:0]; //2020-07-14 00:00:00 + NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:startDate endDate:endDate options:HKQueryOptionNone]; //拼参数 + return predicate; + }else{ + NSDate *endDate = [calendar dateFromComponents:components]; //2020-07-13 00:00:00 + NSDate *startDate = [calendar dateByAddingUnit:NSCalendarUnitDay value:-1 toDate:endDate options:0]; //2020-07-12 00:00:00、 + NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:startDate endDate:endDate options:HKQueryOptionNone]; + return predicate; + } +} + +/** 官方文档 翻译 静态常量 字符串 + 身体测量 + 1. HKQuantityTypeIdentifierBodyMassIndex 身高体重指数 + 2. HKQuantityTypeIdentifierBodyFatPercentage 体脂率 + 3. HKQuantityTypeIdentifierHeight 身高 + 4. HKQuantityTypeIdentifierBodyMass 体重 + 5. HKQuantityTypeIdentifierLeanBodyMass 去脂体重 + + 健身数据 + 1. HKQuantityTypeIdentifierStepCount 步数 + 2. HKQuantityTypeIdentifierDistanceWalkingRunning 步行+跑步距离 + 3. HKQuantityTypeIdentifierDistanceCycling 骑车距离 + 4. HKQuantityTypeIdentifierBasalEnergyBurned 静息能量 + 5. HKQuantityTypeIdentifierActiveEnergyBurned 活动能量 + 6. HKQuantityTypeIdentifierFlightsClimbed 已爬楼层 + + 主要特征 + 1. HKQuantityTypeIdentifierHeartRate 心率 + 2. HKQuantityTypeIdentifierBodyTemperature 体温 + 3. HKQuantityTypeIdentifierBasalBodyTemperature 基础体温 + 4. HKQuantityTypeIdentifierBloodPressureSystolic 收缩压 + 5. HKQuantityTypeIdentifierBloodPressureDiastolic 舒张压 + 6. HKQuantityTypeIdentifierRespiratoryRate 呼吸速率 + + 数据结果、营养摄入 + */ + +//写权限集合 +- (NSSet *)dataTypesToWrite{ + + HKQuantityType *heightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight]; + HKQuantityType *weightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass]; + HKQuantityType *temperatureType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyTemperature]; + HKQuantityType *activeEnergyType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned]; + + return [NSSet setWithObjects:heightType, temperatureType, weightType,activeEnergyType,nil]; +} + +//读权限集合 +- (NSSet *)dataTypesRead{ + HKCharacteristicType *birthdayType = [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierDateOfBirth]; + HKCharacteristicType *sexType = [HKObjectType characteristicTypeForIdentifier:HKCharacteristicTypeIdentifierBiologicalSex]; + + HKQuantityType *heightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeight]; + HKQuantityType *weightType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierBodyMass]; + HKQuantityType *stepCountType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]; + HKQuantityType *stairType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierFlightsClimbed]; + HKQuantityType *distanceType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning]; + HKQuantityType *activeEnergyType = [HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned]; + + return [NSSet setWithObjects:birthdayType, sexType, heightType, weightType, stepCountType, stairType, distanceType, activeEnergyType, nil]; +} + +@end diff --git a/MRMobileRun/MRMainView/GYYHealthTableViewCell.h b/MRMobileRun/MRMainView/GYYHealthTableViewCell.h new file mode 100644 index 0000000..22aa4b9 --- /dev/null +++ b/MRMobileRun/MRMainView/GYYHealthTableViewCell.h @@ -0,0 +1,18 @@ +// +// GYYHealthTableViewCell.h +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/7/9. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface GYYHealthTableViewCell : UITableViewCell + +@property (nonatomic, copy)NSDictionary *runDataDic; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMainView/GYYHealthTableViewCell.m b/MRMobileRun/MRMainView/GYYHealthTableViewCell.m new file mode 100644 index 0000000..6e5d966 --- /dev/null +++ b/MRMobileRun/MRMainView/GYYHealthTableViewCell.m @@ -0,0 +1,295 @@ +// +// GYYHealthTableViewCell.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/7/9. +// + +#import "GYYHealthTableViewCell.h" +#import + +@interface GYYHealthTableViewCell() + +@property (nonatomic, strong)UIImageView *iconView; +@property (nonatomic, strong)UILabel *titleLab; +@property (nonatomic, strong)UILabel *dataLab; +@property (nonatomic, strong)UIView *redBarView; +@property (nonatomic, strong)UILabel *redBarTitleLab; +@property (nonatomic, strong)UIView *grayBarView; +@property (nonatomic, strong)UILabel *grayBarTitleLab; +@property (nonatomic, strong)UILabel *yesterdaydataLab; + + +@end + +@implementation GYYHealthTableViewCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.selectionStyle = UITableViewCellSelectionStyleNone; //点击时没有阴影效果 + + self.contentView.backgroundColor = [UIColor whiteColor]; + [self createSubviews]; + } + return self; +} + +//创建子视图 +- (void)createSubviews{ + //先添加视图,再约束。防止崩溃 + //或者按顺序添加 + //一定要addSubview之后 + [self.contentView addSubview:self.iconView]; //如果不用self 不走getter方法 + [self.contentView addSubview:self.titleLab]; + [self.contentView addSubview:self.dataLab]; + [self.contentView addSubview:self.redBarView]; + [self.redBarView addSubview:self.redBarTitleLab]; + [self.contentView addSubview:self.grayBarView]; + [self.grayBarView addSubview:self.grayBarTitleLab]; + [self.grayBarView addSubview:self.yestodaydataLab]; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + self.contentView.backgroundColor = GYYColor; + } else { + self.contentView.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + + [self.iconView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(-(screenWidth / 2 - 27.5)); + make.centerY.equalTo(self.titleLab); + }]; + + [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(5); + make.left.mas_equalTo(41); + }]; + + [self.dataLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(15); + make.top.mas_equalTo(22); + }]; + + [self.redBarView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(15); + make.height.mas_equalTo(26); + make.width.mas_equalTo(0); + make.bottom.mas_equalTo(-56); + }]; + [self.redBarTitleLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.left.mas_equalTo(10); + }]; + + [self.grayBarView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(15); + make.height.mas_equalTo(26); + make.width.mas_equalTo(0); + make.bottom.mas_equalTo(-19); + }]; + [self.grayBarTitleLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.left.mas_equalTo(10); + }]; + [self.yesterdaydataLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.mas_equalTo(-10); + make.centerY.mas_equalTo(0); + }]; +} + +- (void)setRunDataDic:(NSDictionary *)runDataDic{ //Setter + _runDataDic = runDataDic; + NSLog(@"++++%@", _runDataDic); + + _iconView.image = [UIImage imageNamed:_runDataDic[@"icon"]]; + _titleLab.text = _runDataDic[@"title"]; + + NSString *countStr = _runDataDic[@"todayData"]; + NSString *unitStr = _runDataDic[@"unit"]; + NSString *targetStr = [countStr stringByAppendingString:unitStr]; + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:targetStr]; + +// [attributedString addAttribute:NSForegroundColorAttributeName value:COLOR_WITH_HEX(0x333739) range:[targetStr rangeOfString:countStr]]; + [attributedString addAttribute:NSForegroundColorAttributeName value:COLOR_WITH_HEX(0xA0A0A0) range:[targetStr rangeOfString:unitStr]]; + + [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:24] range:[targetStr rangeOfString:countStr]]; + [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:14] range:[targetStr rangeOfString:unitStr]]; + + _dataLab.attributedText = attributedString; + + float todayCount = [_runDataDic[@"todayData"] floatValue]; + float yesterdayCount = [_runDataDic[@"yesterdayData"] floatValue]; + + if (todayCount != 0 && yesterdayCount != 0) { + if (todayCount > yesterdayCount) { + [_redBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth - 40); + }]; + + [_grayBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo((yesterdayCount / todayCount) * (screenWidth - 40) > (screenWidth - 40) * 0.4 ? (yesterdayCount / todayCount) * (screenWidth - 40) : (screenWidth - 40) * 0.4); + }]; + }else{ + [_grayBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth - 40); + }]; + + [_redBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo((todayCount / yesterdayCount) * (screenWidth - 40) > (screenWidth - 40) * 0.25 ? (todayCount / yesterdayCount) * (screenWidth - 40) : (screenWidth - 40) * 0.25); + }]; + } + }else{ + if (todayCount == 0) { + [_redBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo((screenWidth - 40) * 0.25); + }]; + }else{ + [_redBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth - 40); + }]; + } + + if (yesterdayCount == 0) { + [_grayBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo((screenWidth - 40) * 0.4); + }]; + }else{ + [_grayBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth - 40); + }]; + } + } + + _redBarTitleLab.text = _runDataDic[@"todayTitle"]; + _grayBarTitleLab.text = _runDataDic[@"yesterdayTitle"]; + + + NSString *yesCountStr = _runDataDic[@"yesterdayData"]; + NSString *yesTargetStr = [yesCountStr stringByAppendingString:unitStr]; + NSMutableAttributedString *yesAttributedString = [[NSMutableAttributedString alloc] initWithString:yesTargetStr]; + + [yesAttributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:14] range:[yesTargetStr rangeOfString:yesCountStr]]; + [yesAttributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:10] range:[yesTargetStr rangeOfString:unitStr]]; + + + + _yesterdaydataLab.attributedText = yesAttributedString; +} + +#pragma mark ======== 懒加载 ======== +- (UIImageView *)iconView{ + if (!_iconView) { + _iconView = [[UIImageView alloc] init]; + } + return _iconView; +} + +- (UILabel *)titleLab{ + if (!_titleLab) { + _titleLab = [[UILabel alloc] init]; + _titleLab.textColor = COLOR_WITH_HEX(0x64686F); + _titleLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size:12]; + } + return _titleLab; +} + +- (UILabel *)dataLab{ + if (!_dataLab) { + _dataLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x333739); + } + else { + return COLOR_WITH_HEX(0xFFFFFF); + } + }]; + self->_dataLab.textColor = rankColor; + } else { + _dataLab.textColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + + } + return _dataLab; +} + +- (UIView *)redBarView{ + if (!_redBarView) { + _redBarView = [[UIView alloc] init]; + _redBarView.backgroundColor = COLOR_WITH_HEX(0xFF5C77); + _redBarView.layer.masksToBounds = YES; + _redBarView.layer.cornerRadius = 6.0; + } + return _redBarView; +} + +- (UILabel *)redBarTitleLab{ //Getter + if (!_redBarTitleLab) { + _redBarTitleLab = [[UILabel alloc] init]; + _redBarTitleLab.textColor = [UIColor whiteColor]; + _redBarTitleLab.font = [UIFont fontWithName:@"PingFangSC-Regular" size:14]; + } + return _redBarTitleLab; +} + +- (UIView *)grayBarView{ + if (!_grayBarView) { + _grayBarView = [[UIView alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xE1E4E5); + } + else { + return COLOR_WITH_HEX(0x64686F); + } + }]; + _grayBarView.backgroundColor = GYYColor; + } else { + _grayBarView.backgroundColor = COLOR_WITH_HEX(0xE1E4E5); + } + _grayBarView.layer.masksToBounds = YES; //开启圆角 + _grayBarView.layer.cornerRadius = 6.0; //圆角大小 半径 + } + return _grayBarView; +} + +- (UILabel *)grayBarTitleLab{ //Getter + if (!_grayBarTitleLab) { + _grayBarTitleLab = [[UILabel alloc] init]; + _grayBarTitleLab.textColor = COLOR_WITH_HEX(0xA0A0A0); + _grayBarTitleLab.font = [UIFont fontWithName:@"PingFangSC-Regular" size:14]; + } + return _grayBarTitleLab; +} + +- (UILabel *)yestodaydataLab{ + if (!_yesterdaydataLab) { + _yesterdaydataLab = [[UILabel alloc] init]; + _yesterdaydataLab.textColor = COLOR_WITH_HEX(0xA0A0A0); + } + return _yesterdaydataLab; +} + + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +@end diff --git a/MRMobileRun/MRMainView/GYYRankHeaderMainView.h b/MRMobileRun/MRMainView/GYYRankHeaderMainView.h new file mode 100644 index 0000000..66a8054 --- /dev/null +++ b/MRMobileRun/MRMainView/GYYRankHeaderMainView.h @@ -0,0 +1,20 @@ +// +// GYYRankHeaderMainView.h +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/14. +// + +#import + +@class GYYRankModel; + +NS_ASSUME_NONNULL_BEGIN + +@interface GYYRankHeaderMainView : UIView + +@property (nonatomic, strong)GYYRankModel *rankModel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMainView/GYYRankHeaderMainView.m b/MRMobileRun/MRMainView/GYYRankHeaderMainView.m new file mode 100644 index 0000000..3b348cd --- /dev/null +++ b/MRMobileRun/MRMainView/GYYRankHeaderMainView.m @@ -0,0 +1,186 @@ +// +// GYYRankHeaderMainView.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/14. +// + +#import "GYYRankHeaderMainView.h" +#import "GYYRankModel.h" +#import +#import "UIImageView+WebCache.h" + +@interface GYYRankHeaderMainView() + +@property (nonatomic, strong)UIImageView *headImg; +@property (nonatomic, strong)UILabel *nameLab; +@property (nonatomic, strong)UILabel *distanceLab; +@property (nonatomic, strong)UILabel *rankLab; + + +@end + +@implementation GYYRankHeaderMainView + +- (instancetype)init{ + self = [super init]; + if (self) { + self.backgroundColor = [UIColor whiteColor]; + + self.layer.cornerRadius = 49; //圆角 + + self.layer.shadowColor = [COLOR_WITH_HEX(0xAAB9C0) colorWithAlphaComponent:0.1].CGColor; //阴影的颜色 + self.layer.shadowOffset = CGSizeMake(0, 3); //偏移量 + self.layer.shadowOpacity = 1; //不透明度 + self.layer.shadowRadius = 6; //阴影半径 阴影 + + // self.clipsToBounds = YES; //default is NO; + // self.layer.masksToBounds = YES; //default is NO; + + [self createSubviews]; + } + return self; +} + +- (void)createSubviews{ + [self addSubview:self.headImg]; + [self addSubview:self.rankLab]; + [self addSubview:self.nameLab]; + [self addSubview:self.distanceLab]; + + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFFFFFF); + } + else { + return COLOR_WITH_HEX(0x4A4D52); + } + }]; + self.backgroundColor = GYYColor; + } else { + self.backgroundColor = COLOR_WITH_HEX(0xFFFFFF); + } + UILabel *tipLab = [[UILabel alloc] init]; + [self addSubview:tipLab]; + tipLab.text = @"排名"; + tipLab.textColor = COLOR_WITH_HEX(0xB2B2B2); + tipLab.font = [UIFont systemFontOfSize:10]; + [tipLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.rankLab); + make.bottom.mas_equalTo(-21); + }]; + + + [self.rankLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.mas_equalTo(-33); + make.top.mas_equalTo(21); + }]; + [self.headImg mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.left.mas_equalTo(9); + make.size.mas_equalTo(CGSizeMake(72, 72)); + }]; + [self.nameLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.headImg.mas_top).offset(8); + make.left.equalTo(self.headImg.mas_right).offset(15); + }]; + [self.distanceLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.nameLab); + make.bottom.mas_equalTo(-13); + }]; +} + +- (void)setRankModel:(GYYRankModel *)rankModel{ + _rankModel = rankModel; + + // 对图片的网络请求进行封装,对请求的图片进行缓存,如果没有请求过,进行网络请求,如果请求过,从缓存取值。 url = @"http:xxxxxxx/xxxxx/xxx.png" 转换成哈希值,存在哈希结构里。 + NSURL *url = [NSURL URLWithString:_rankModel.AvatarUrl]; //把字符串 转化为 NSUrl + // [_headImg sd_setImageWithURL:url]; + //plaeceholder 占位图 + [_headImg sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"logo头像"]]; + _nameLab.text = _rankModel.Nickname; + + NSString *unit; + if (!_rankModel.Unit) { + unit = @"km"; + }else{ + unit = _rankModel.Unit; + } + NSString *targetStr = [NSString stringWithFormat:@"%@%@", _rankModel.DistanceValue, unit]; + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:targetStr]; + [attributedString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:26] range:[targetStr rangeOfString:_rankModel.DistanceValue]]; + [attributedString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:18] range:[targetStr rangeOfString:unit]]; + _distanceLab.attributedText = attributedString; + _rankLab.text = [NSString stringWithFormat:@"%@", _rankModel.Rank]; +} + +- (UILabel *)rankLab{ + if (!_rankLab) { + _rankLab = [[UILabel alloc] init]; + _rankLab.textColor = COLOR_WITH_HEX(0xF06272); + _rankLab.font = [UIFont boldSystemFontOfSize:25]; + } + return _rankLab; +} + +- (UIImageView *)headImg{ + if (!_headImg) { + _headImg = [[UIImageView alloc] init]; + _headImg.layer.masksToBounds = YES; + _headImg.layer.cornerRadius = 36; + } + return _headImg; +} + +- (UILabel *)nameLab{ + if (!_nameLab) { + _nameLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x333739); + } + else { + return COLOR_WITH_HEX(0xFFFFFF); + } + }]; + self->_nameLab.textColor = rankColor; + } else { + _nameLab.textColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + _nameLab.font = [UIFont boldSystemFontOfSize:16]; + } + return _nameLab; +} + +- (UILabel *)distanceLab{ + if (!_distanceLab) { + _distanceLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x333739); + } + else { + return COLOR_WITH_HEX(0xFFFFFF); + } + }]; + self->_distanceLab.textColor = rankColor; + } else { + _distanceLab.textColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + } + return _distanceLab; +} +/* +// Only override drawRect: if you perform custom drawing. +// An empty implementation adversely affects performance during animation. +- (void)drawRect:(CGRect)rect { + // Drawing code +} +*/ + +@end diff --git a/MRMobileRun/MRMainView/GYYRankModel.h b/MRMobileRun/MRMainView/GYYRankModel.h new file mode 100644 index 0000000..a933b3c --- /dev/null +++ b/MRMobileRun/MRMainView/GYYRankModel.h @@ -0,0 +1,24 @@ +// +// GYYRankModel.h +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/12. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface GYYRankModel : NSObject + +@property (nonatomic, copy)NSString *AvatarUrl; +@property (nonatomic, copy)NSString *Name; +@property (nonatomic, copy)NSString *Nickname; +@property (nonatomic, copy)NSString *Rank; +@property (nonatomic, copy)NSString *Signature; +@property (nonatomic, copy)NSString *Unit; +@property (nonatomic, copy)NSString *DistanceValue; //Vaule + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMainView/GYYRankModel.m b/MRMobileRun/MRMainView/GYYRankModel.m new file mode 100644 index 0000000..3943168 --- /dev/null +++ b/MRMobileRun/MRMainView/GYYRankModel.m @@ -0,0 +1,34 @@ +// +// GYYRankModel.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/12. +// + +#import "GYYRankModel.h" +#import + +@implementation GYYRankModel + +//// NSNumer -> NSString 一劳永逸 +//- (void)setValue:(id)value forUndefinedKey:(NSString *)key{ +// if ([key isEqualToString:@"Value"]) { +// self.DistanceValue = [NSString stringWithFormat:@"%.2f", [value floatValue]]; +// } +//} + +//property 属性 根据属性名拦截value做基本数据操作 +- (id)mj_newValueFromOldValue:(id)oldValue property:(MJProperty *)property{ + if ([property.name isEqualToString:@"DistanceValue"]) { + return [NSString stringWithFormat:@"%.2f", [oldValue floatValue]]; + } + return oldValue; +} + + //替换 ++ (NSDictionary *)mj_replacedKeyFromPropertyName{ + return @{@"DistanceValue" : @"Value"}; + //新值 //数据返回值 这个可能有冲突 所以选择新值替换 +} + +@end diff --git a/MRMobileRun/MRMainView/GYYRankTableViewCell.h b/MRMobileRun/MRMainView/GYYRankTableViewCell.h new file mode 100644 index 0000000..047010c --- /dev/null +++ b/MRMobileRun/MRMainView/GYYRankTableViewCell.h @@ -0,0 +1,19 @@ +// +// GYYRankTableViewCell.h +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/12. +// + +#import +#import "GYYRankModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface GYYRankTableViewCell : UITableViewCell + +@property (nonatomic, strong) GYYRankModel *rankModel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMainView/GYYRankTableViewCell.m b/MRMobileRun/MRMainView/GYYRankTableViewCell.m new file mode 100644 index 0000000..9dac2cf --- /dev/null +++ b/MRMobileRun/MRMainView/GYYRankTableViewCell.m @@ -0,0 +1,223 @@ +// +// GYYRankTableViewCell.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/12. +// + +#import "GYYRankTableViewCell.h" +#import +#import "UIImageView+WebCache.h" //SDWebImage头文件 + +@interface GYYRankTableViewCell() + +@property (nonatomic, strong)UIImageView *rankIcon; +@property (nonatomic, strong)UILabel *rankLab; +@property (nonatomic, strong)UIImageView *headImg; +@property (nonatomic, strong)UILabel *nameLab; +@property (nonatomic, strong)UILabel *signLab; +@property (nonatomic, strong)UILabel *distanceLab; + +@end + +@implementation GYYRankTableViewCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.selectionStyle = UITableViewCellSelectionStyleNone; + [self createSubviews]; + } + return self; +} + +- (void)createSubviews { + [self.contentView addSubview:self.rankIcon]; + [self.contentView addSubview:self.rankLab]; + [self.contentView addSubview:self.headImg]; + [self.contentView addSubview:self.nameLab]; + [self.contentView addSubview:self.signLab]; + [self.contentView addSubview:self.distanceLab]; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + self.contentView.backgroundColor = GYYColor; + } else { + self.contentView.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + + [self.rankIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.left.mas_equalTo(15); + make.size.mas_equalTo(CGSizeMake(24, 24)); + }]; + [self.rankLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.centerX.mas_equalTo(-(screenWidth / 2 - 27)); + }]; + [self.headImg mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.left.mas_equalTo(43); + make.size.mas_equalTo(CGSizeMake(50, 50)); + }]; + [self.nameLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.headImg.mas_top).offset(4); + make.left.equalTo(self.headImg.mas_right).offset(9); + }]; + [self.signLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.nameLab.mas_bottom).offset(1); + make.left.equalTo(self.headImg.mas_right).offset(9); + }]; + [self.distanceLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.nameLab); + make.right.mas_equalTo(-15); + }]; +} + +- (void)setRankModel:(GYYRankModel *)rankModel{ + _rankModel = rankModel; + + // 对图片的网络请求进行封装,对请求的图片进行缓存,如果没有请求过,进行网络请求,如果请求过,从缓存取值。 url = @"http:xxxxxxx/xxxxx/xxx.png" 转换成哈希值,存在哈希结构里。 + NSURL *url = [NSURL URLWithString:_rankModel.AvatarUrl]; //把字符串 转化为 NSUrl +// [_headImg sd_setImageWithURL:url]; + //plaeceholder 占位图 + [_headImg sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"logo头像"]]; + _nameLab.text = _rankModel.Nickname; + _signLab.text = _rankModel.Signature; + //@"%.6f" OC 取几位小数 .后面放几 + //@"%03ld" + + + NSString *targetStr = [NSString stringWithFormat:@"%@%@", _rankModel.DistanceValue, _rankModel.Unit]; + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:targetStr]; + [attributedString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:18] range:[targetStr rangeOfString:_rankModel.DistanceValue]]; + [attributedString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:12] range:[targetStr rangeOfString:_rankModel.Unit]]; + _distanceLab.attributedText = attributedString; + + if ([_rankModel.Rank integerValue] <= 3) { + _rankLab.hidden = YES; + _rankIcon.hidden = NO; + + _rankIcon.image = [UIImage imageNamed:[NSString stringWithFormat:@"rank_%@", _rankModel.Rank]]; + }else{ + _rankLab.hidden = NO; + _rankIcon.hidden = YES; + + _rankLab.text = [NSString stringWithFormat:@"%@", _rankModel.Rank]; // + } + +} + +- (UIImageView *)rankIcon{ + if (!_rankIcon) { + _rankIcon = [[UIImageView alloc] init]; + } + return _rankIcon; +} + +- (UILabel *)rankLab{ + if (!_rankLab) { + _rankLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x64686F); + } + else { + return COLOR_WITH_HEX(0xFFFFFF); + } + }]; + self->_rankLab.textColor = rankColor; + } else { + _rankLab.textColor = COLOR_WITH_HEX(0x64686F); + // Fallback on earlier versions + } + _rankLab.font = [UIFont systemFontOfSize:16]; + } + return _rankLab; +} + +- (UIImageView *)headImg{ + if (!_headImg) { + _headImg = [[UIImageView alloc] init]; + _headImg.layer.masksToBounds = YES; + _headImg.layer.cornerRadius = 25; + } + return _headImg; +} + +- (UILabel *)nameLab{ + if (!_nameLab) { + _nameLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x333739); + } + else { + return COLOR_WITH_HEX(0xFFFFFF); + } + }]; + self->_nameLab.textColor = rankColor; + } else { + _nameLab.textColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + _nameLab.font = [UIFont systemFontOfSize:15]; + } + return _nameLab; +} + +- (UILabel *)signLab{ + if (!_signLab) { + _signLab = [[UILabel alloc] init]; + _signLab.textColor = COLOR_WITH_HEX(0xA0A0A0); + _signLab.font = [UIFont systemFontOfSize:11]; + _signLab.numberOfLines = 1; + } + return _signLab; +} + +- (UILabel *)distanceLab{ + if (!_distanceLab) { + _distanceLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x333739); + } + else { + return COLOR_WITH_HEX(0xA0A0A0); + } + }]; + self->_distanceLab.textColor = rankColor; + } else { + _distanceLab.textColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + } + return _distanceLab; +} + +/* + + */ +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + + +@end diff --git a/MRMobileRun/MRMainView/GYYRunModel.h b/MRMobileRun/MRMainView/GYYRunModel.h new file mode 100644 index 0000000..7cc07f2 --- /dev/null +++ b/MRMobileRun/MRMainView/GYYRunModel.h @@ -0,0 +1,25 @@ +// +// GYYRunModel.h +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/7/16. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface GYYRunModel : NSObject + +//@property (nonatomic, copy) NSString *runModelId; + +//@property (nonatomic, copy) NSArry *Aarr; //OtherClass +@property (nonatomic, copy) NSString *SubTitle; //标题 +@property (nonatomic, copy) NSString *NowValue; //本次值 +@property (nonatomic, copy) NSString *LastValue; //上次值 +@property (nonatomic, copy) NSString *Unit; //单位 +//@property (nonatomic, copy) NSString *tip; //标志 找不到程序会crash + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMainView/GYYRunModel.m b/MRMobileRun/MRMainView/GYYRunModel.m new file mode 100644 index 0000000..6ea355a --- /dev/null +++ b/MRMobileRun/MRMainView/GYYRunModel.m @@ -0,0 +1,21 @@ +// +// GYYRunModel.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/7/16. +// + +#import "GYYRunModel.h" + +@implementation GYYRunModel + +- (void)setValue:(id)value forUndefinedKey:(NSString *)key{ + +} + + +//- (void)setValue:(id)value forUndefinedKey:(NSString *)key{ +// // key = tip +//} + +@end diff --git a/MRMobileRun/MRMainView/GYYRunTableViewCell.h b/MRMobileRun/MRMainView/GYYRunTableViewCell.h new file mode 100644 index 0000000..2ede700 --- /dev/null +++ b/MRMobileRun/MRMainView/GYYRunTableViewCell.h @@ -0,0 +1,20 @@ +// +// GYYRunTableViewCell.h +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/7/10. +// + +#import +#import "GYYRunModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface GYYRunTableViewCell : UITableViewCell + +@property (nonatomic, strong)GYYRunModel *runModel; +@property (nonatomic, copy)NSDictionary *runDataDic; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMainView/GYYRunTableViewCell.m b/MRMobileRun/MRMainView/GYYRunTableViewCell.m new file mode 100644 index 0000000..03da887 --- /dev/null +++ b/MRMobileRun/MRMainView/GYYRunTableViewCell.m @@ -0,0 +1,366 @@ +// +// GYYRunTableViewCell.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/7/10. +// + +#import "GYYRunTableViewCell.h" +#import + +@interface GYYRunTableViewCell() + +@property (nonatomic, strong)UIImageView *iconView; +@property (nonatomic, strong)UILabel *titleLab; +@property (nonatomic, strong)UILabel *dataLab; +@property (nonatomic, strong)UIView *redBarView; +@property (nonatomic, strong)UILabel *redBarTitleLab; +@property (nonatomic, strong)UIView *grayBarView; +@property (nonatomic, strong)UILabel *grayBarTitleLab; +@property (nonatomic, strong)UILabel *yesterdaydataLab; + +@end + +@implementation GYYRunTableViewCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.selectionStyle = UITableViewCellSelectionStyleNone; //点击时没有阴影效果 + + self.contentView.backgroundColor = [UIColor whiteColor]; + [self createSubviews]; + } + return self; +} + +//创建子视图 +- (void)createSubviews{ + //先添加视图,再约束。防止崩溃 + //或者按顺序添加 + //一定要addSubview之后 + [self.contentView addSubview:self.iconView]; //如果不用self 不走getter方法 + [self.contentView addSubview:self.titleLab]; + [self.contentView addSubview:self.dataLab]; + [self.contentView addSubview:self.redBarView]; + [self.redBarView addSubview:self.redBarTitleLab]; + [self.contentView addSubview:self.grayBarView]; + [self.grayBarView addSubview:self.grayBarTitleLab]; + [self.grayBarView addSubview:self.yestodaydataLab]; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + self.contentView.backgroundColor = GYYColor; + } else { + self.contentView.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + [self.iconView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(-(screenWidth / 2 - 27.5)); + make.centerY.equalTo(self.titleLab); + }]; + + [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(5); + make.left.mas_equalTo(41); + }]; + + [self.dataLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(15); + make.top.mas_equalTo(22); + }]; + + [self.redBarView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(15); + make.height.mas_equalTo(26); + make.width.mas_equalTo(0); + make.bottom.mas_equalTo(-56); + }]; + [self.redBarTitleLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.left.mas_equalTo(10); + }]; + + [self.grayBarView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(15); + make.height.mas_equalTo(26); + make.width.mas_equalTo(0); + make.bottom.mas_equalTo(-19); + }]; + [self.grayBarTitleLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.left.mas_equalTo(10); + }]; + [self.yesterdaydataLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.mas_equalTo(-10); + make.centerY.mas_equalTo(0); + }]; +} + +- (void)setRunModel:(GYYRunModel *)runModel{ + _runModel = runModel; + + NSString *imageName; + if ([_runModel.SubTitle isEqualToString:@"里程"]) { + imageName = @"homepage_kilometer"; + }else if ([_runModel.SubTitle isEqualToString:@"运动时间"]) { + imageName = @"homepage_time"; + }else if ([_runModel.SubTitle isEqualToString:@"步频"]) { + imageName = @"homepage_step"; + }else{ + imageName = @"homepage_consume"; + } + _iconView.image = [UIImage imageNamed:imageName]; + _titleLab.text = _runModel.SubTitle; + + NSString *countStr = _runModel.NowValue; + NSString *unitStr = _runModel.Unit; + NSString *targetStr = [countStr stringByAppendingString:unitStr]; + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:targetStr]; + +// [attributedString addAttribute:NSForegroundColorAttributeName value:COLOR_WITH_HEX(0x333739) range:[targetStr rangeOfString:countStr]]; + [attributedString addAttribute:NSForegroundColorAttributeName value:COLOR_WITH_HEX(0xA0A0A0) range:[targetStr rangeOfString:unitStr]]; + + [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:24] range:[targetStr rangeOfString:countStr]]; + [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:14] range:[targetStr rangeOfString:unitStr]]; + + _dataLab.attributedText = attributedString; + + float todayCount = [_runModel.NowValue floatValue]; + float yesterdayCount = [_runModel.LastValue floatValue]; + + CGFloat redBarMinLen, grayBarMinLen; + if ([_runModel.SubTitle isEqualToString:@"运动时间"]) { + redBarMinLen = (screenWidth - 40) * 0.3; + grayBarMinLen = (screenWidth - 40) * 0.5; + }else{ + redBarMinLen = (screenWidth - 40) * 0.25; + grayBarMinLen = (screenWidth - 40) * 0.4; + } + + if (todayCount != 0 && yesterdayCount != 0) { + if (todayCount > yesterdayCount) { + [_redBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth - 40); + }]; + + [_grayBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo((yesterdayCount / todayCount) * (screenWidth - 40) > grayBarMinLen ? (yesterdayCount / todayCount) * (screenWidth - 40) : grayBarMinLen); + }]; + }else{ + [_grayBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth - 40); + }]; + + [_redBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo((todayCount / yesterdayCount) * (screenWidth - 40) > redBarMinLen ? (todayCount / yesterdayCount) * (screenWidth - 40) : redBarMinLen); + }]; + } + }else{ + if (todayCount == 0) { + [_redBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(redBarMinLen); + }]; + }else{ + [_redBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth - 40); + }]; + } + + if (yesterdayCount == 0) { + [_grayBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(grayBarMinLen); + }]; + }else{ + [_grayBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth - 40); + }]; + } + } + + _redBarTitleLab.text = [NSString stringWithFormat:@"今日%@", _runModel.SubTitle]; + _grayBarTitleLab.text = [NSString stringWithFormat:@"昨日%@", _runModel.SubTitle]; + + NSString *yesCountStr = _runModel.LastValue; + NSString *yesTargetStr = [yesCountStr stringByAppendingString:unitStr]; + NSMutableAttributedString *yesAttributedString = [[NSMutableAttributedString alloc] initWithString:yesTargetStr]; + [yesAttributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:14] range:[yesTargetStr rangeOfString:yesCountStr]]; + [yesAttributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:10] range:[yesTargetStr rangeOfString:unitStr]]; + _yesterdaydataLab.attributedText = yesAttributedString; +} + +- (void)setRunDataDic:(NSDictionary *)runDataDic{ //Setter + _runDataDic = runDataDic; + NSLog(@"%@", _runDataDic); + + _iconView.image = [UIImage imageNamed:_runDataDic[@"icon"]]; + _titleLab.text = _runDataDic[@"title"]; + + NSString *countStr = _runDataDic[@"todayData"]; + NSString *unitStr = _runDataDic[@"unit"]; + NSString *targetStr = [countStr stringByAppendingString:unitStr]; + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:targetStr]; + +// if (@available(iOS 13.0, *)) { +// [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor labelColor] range:[targetStr rangeOfString:countStr]]; +// } else { +// // Fallback on earlier versions +// } + [attributedString addAttribute:NSForegroundColorAttributeName value:COLOR_WITH_HEX(0xA0A0A0) range:[targetStr rangeOfString:unitStr]]; + + [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:24] range:[targetStr rangeOfString:countStr]]; + [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:14] range:[targetStr rangeOfString:unitStr]]; + + _dataLab.attributedText = attributedString; + + float todayCount = [_runDataDic[@"todayData"] floatValue]; + float yestodayCount = [_runDataDic[@"yesterdayData"] floatValue]; + if (todayCount > yestodayCount) { + [_redBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth - 40); + }]; + + [_grayBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo((yestodayCount / todayCount) * (screenWidth - 40)); + }]; + }else{ + [_grayBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth - 40); + }]; + + [_redBarView mas_updateConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo((todayCount / yestodayCount) * (screenWidth - 40)); + }]; + } + + _redBarTitleLab.text = _runDataDic[@"todayTitle"]; + _grayBarTitleLab.text = _runDataDic[@"yesterdayTitle"]; + + + NSString *yesCountStr = _runDataDic[@"yesterdayData"]; + NSString *yesTargetStr = [yesCountStr stringByAppendingString:unitStr]; + NSMutableAttributedString *yesAttributedString = [[NSMutableAttributedString alloc] initWithString:yesTargetStr]; + + [yesAttributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:14] range:[yesTargetStr rangeOfString:yesCountStr]]; + [yesAttributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Medium" size:10] range:[yesTargetStr rangeOfString:unitStr]]; + + + + _yesterdaydataLab.attributedText = yesAttributedString; +} + +#pragma mark ======== 懒加载 ======== +- (UIImageView *)iconView{ + if (!_iconView) { + _iconView = [[UIImageView alloc] init]; + } + return _iconView; +} + +- (UILabel *)titleLab{ + if (!_titleLab) { + _titleLab = [[UILabel alloc] init]; + _titleLab.textColor = COLOR_WITH_HEX(0x64686F); + _titleLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size:12]; + } + return _titleLab; +} + +- (UILabel *)dataLab{ + if (!_dataLab) { + _dataLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x333739); + } + else { + return COLOR_WITH_HEX(0xFFFFFF); + } + }]; + self->_dataLab.textColor = rankColor; + } else { + _dataLab.textColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + + + } + return _dataLab; +} + +- (UIView *)redBarView{ + if (!_redBarView) { + _redBarView = [[UIView alloc] init]; + _redBarView.backgroundColor = COLOR_WITH_HEX(0xFF5C77); + _redBarView.layer.masksToBounds = YES; + _redBarView.layer.cornerRadius = 6.0; + } + return _redBarView; +} + +- (UILabel *)redBarTitleLab{ //Getter + if (!_redBarTitleLab) { + _redBarTitleLab = [[UILabel alloc] init]; + _redBarTitleLab.textColor = [UIColor whiteColor]; + _redBarTitleLab.font = [UIFont fontWithName:@"PingFangSC-Regular" size:14]; + } + return _redBarTitleLab; +} + +- (UIView *)grayBarView{ + if (!_grayBarView) { + _grayBarView = [[UIView alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xE1E4E5); + } + else { + return COLOR_WITH_HEX(0x64686F); + } + }]; + _grayBarView.backgroundColor = GYYColor; + } else { + _grayBarView.backgroundColor = COLOR_WITH_HEX(0xE1E4E5); + } + _grayBarView.layer.masksToBounds = YES; //开启圆角 + _grayBarView.layer.cornerRadius = 6.0; //圆角大小 半径 + } + return _grayBarView; +} + +- (UILabel *)grayBarTitleLab{ //Getter + if (!_grayBarTitleLab) { + _grayBarTitleLab = [[UILabel alloc] init]; + _grayBarTitleLab.textColor = COLOR_WITH_HEX(0xA0A0A0); + _grayBarTitleLab.font = [UIFont fontWithName:@"PingFangSC-Regular" size:14]; + } + return _grayBarTitleLab; +} + +- (UILabel *)yestodaydataLab{ + if (!_yesterdaydataLab) { + _yesterdaydataLab = [[UILabel alloc] init]; + _yesterdaydataLab.textColor = COLOR_WITH_HEX(0xA0A0A0); + } + return _yesterdaydataLab; +} + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +@end diff --git a/MRMobileRun/MRMainView/ZYLMainView.m b/MRMobileRun/MRMainView/ZYLMainView.m index 86a9cc3..f40b12c 100644 --- a/MRMobileRun/MRMainView/ZYLMainView.m +++ b/MRMobileRun/MRMainView/ZYLMainView.m @@ -9,7 +9,7 @@ #import "ZYLArrowBtn.h" #import "ZYLAvatarRequest.h" #import "ZYLStudentRankViewModel.h" -#import "ZYLRecordTimeString.h" +//#import "ZYLRecordTimeString.h" #import "ZYLRunningRecordModel.h" @implementation ZYLMainView @@ -186,7 +186,7 @@ - (void)initRunningTime{ self.timeLabel = [[UILabel alloc]init]; self.timeLabel.font = [UIFont fontWithName:@"DINAlternate-Bold" size:35*screenWidth/414.0]; - self.timeLabel.text = [ZYLRecordTimeString getTimeStringWithSecond:0]; +// self.timeLabel.text = [ZYLRecordTimeString getTimeStringWithSecond:0]; [self addSubview:self.timeLabel]; @@ -233,9 +233,9 @@ - (void)NetError:(NSNotification *)noti{ - (void)addRecordData:(NSNotification *)noti{ ZYLRunningRecordModel *model = noti.object; - if (model.student_id) { - self.timeLabel.text = [ZYLRecordTimeString getTimeStringWithSecond:[model.end_time intValue] - [model.begin_time intValue]]; - } +// if (model.student_id) { +// self.timeLabel.text = [ZYLRecordTimeString getTimeStringWithSecond:[model.end_time intValue] - [model.begin_time intValue]]; +// } } - (void)initbeginRuningBtu{ diff --git a/MRMobileRun/MRMainView/ZYLMainViewController.h b/MRMobileRun/MRMainView/ZYLMainViewController.h index 5f9673a..eb798ea 100644 --- a/MRMobileRun/MRMainView/ZYLMainViewController.h +++ b/MRMobileRun/MRMainView/ZYLMainViewController.h @@ -10,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN @interface ZYLMainViewController : MRBaseViewController ++ (id)shareAFNManager; @end diff --git a/MRMobileRun/MRMainView/ZYLMainViewController.m b/MRMobileRun/MRMainView/ZYLMainViewController.m index 8bf9c4b..8b84aa9 100644 --- a/MRMobileRun/MRMainView/ZYLMainViewController.m +++ b/MRMobileRun/MRMainView/ZYLMainViewController.m @@ -5,60 +5,566 @@ // Created by 丁磊 on 2019/3/23. // + #import "ZYLMainViewController.h" #import "ZYLMainView.h" #import "ZYLStartRunningButton.h" #import "ZYLHostView.h" #import "ZYLGetTimeScale.h" #import "ZYLHealthManager.h" +#import "GYYHealthTableViewCell.h" +#import "GYYRunTableViewCell.h" +#import "GYYHealthManager.h" +#import "MRTabBarController.h" #import #import -@interface ZYLMainViewController () +#import "HttpClient.h" +#import "ZYLRunningDataRequest.h" +#import +#import +#import +#import + +static NSString *const cellIdentifier = @"healthCell"; +static NSString *const runCellIdentifier = @"runCell"; + +static AFHTTPSessionManager *manager; + +@interface ZYLMainViewController () { - NSInteger todaySteps; - NSInteger yesterdaySteps; - NSInteger todayStairs; - NSInteger yesterdayStairs; -} -@property (strong, nonatomic) ZYLHostView *hostView; -@property (nonatomic, strong) NSUserDefaults *user; -@property (nonatomic, strong) ZYLHealthManager *healthManager; +// NSInteger todaySteps; +// NSInteger yesterdaySteps; +// NSInteger todayStairs; +// NSInteger yesterdayStairs; +} +//@property (strong, nonatomic) ZYLHostView *hostView; +//@property (nonatomic, strong) NSUserDefaults *user; +//@property (nonatomic, strong) ZYLHealthManager *healthManager; +@property (nonatomic, strong)UITableView *tableView; +@property (nonatomic, strong)UILabel *navLab; +@property (nonatomic, strong)UILabel *tempLab; +@property (nonatomic, strong)NSMutableArray *dataArray; //上拉加载更多 一定要用可变数组 +@property (nonatomic, strong)NSMutableArray *runDataArr; + @end @implementation ZYLMainViewController -- (void)viewWillAppear:(BOOL)animated{ + + +- (void)viewWillAppear:(BOOL)animated{ //视图将要出现 [super viewWillAppear:animated]; [self.navigationController setNavigationBarHidden:YES]; + self.tabBarController.hidesBottomBarWhenPushed = NO; + [self healthManagerConfig]; +} + +- (void)viewDidAppear:(BOOL)animated{ //视图已经出现 + [super viewDidAppear:animated]; + +} + +- (void)viewWillDisappear:(BOOL)animated{ + [super viewWillDisappear:animated]; +} + +- (void)viewDidDisappear:(BOOL)animated{ + [super viewDidDisappear:animated]; } - (void)viewDidLoad { [super viewDidLoad]; - self.user = [NSUserDefaults standardUserDefaults]; - self.healthManager = [ZYLHealthManager shareInstance]; - [self.view addSubview: self.hostView]; - [self getDataFromHealth]; - [self.hostView setTextOfStepLab:[NSString stringWithFormat:@"%ld",(long)todaySteps] andStairLab:[NSString stringWithFormat:@"%ld",(long)todayStairs]]; + if (@available(iOS 13.0, *)) { + UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { //浅色模式 + return [UIColor whiteColor]; + } else { //深色模式 + return [UIColor blackColor]; + } + }]; + self.view.backgroundColor = rightColor; //根据当前模式(光明\暗黑)-展示相应颜色 + } + +// self.user = [NSUserDefaults standardUserDefaults]; +// self.healthManager = [ZYLHealthManager shareInstance]; +// [self.view addSubview: self.hostView]; +// [self getDataFromHealth]; +// [self.hostView setTextOfStepLab:[NSString stringWithFormat:@"%ld",(long)todaySteps] andStairLab:[NSString stringWithFormat:@"%ld",(long)todayStairs]]; + [self createSubviews]; + [self requestData]; + //请求成功时发送广播 +// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(requestData) name:@"isLoginSuccess" object:nil]; } -- (void) getDataFromHealth{ - todaySteps = [self.healthManager getTodayStepCount]; - yesterdaySteps = [self.healthManager getYesterdayStepCount]; - todayStairs = [self.healthManager getTodayFlightsClimbedCount]; - yesterdayStairs = [self.healthManager getYesterdayFlightsClimbedCount]; ++ (id)shareAFNManager{ + static AFHTTPSessionManager *manager; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + manager = [AFHTTPSessionManager manager]; + }); + return manager; } -#pragma mark - 懒加载 -- (ZYLHostView *)hostView{ - if (!_hostView) { - _hostView = [[ZYLHostView alloc] init]; - _hostView.frame = CGRectMake(0, -kStatusBarHeigh*kRateX, screenWidth, screenHeigth); - _hostView.scrollEnabled = YES; - _hostView.contentSize = CGSizeMake(screenWidth, screenHeigth+100*kRateY); - [_hostView.greetLab setText:[NSString stringWithFormat:@"%@%@", [ZYLGetTimeScale getTimeScaleString], [_user valueForKey:@"nickname"]]]; +- (void)requestData{ + + /** + 是AFURLSessionManager的子类,为了便利使用HTTP请求。当一个baseURL提供时,用相对路径构造GET/POST等便利的方法来创建请求。 + */ + AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; + + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *token = [user objectForKey:@"token"]; + // 请求 TCP/IP http + AFHTTPRequestSerializer *requestSerializer = [AFHTTPRequestSerializer serializer]; + //添加请求头 + [requestSerializer setValue:token forHTTPHeaderField:@"token"]; + [manager setRequestSerializer:requestSerializer]; + + // 响应 + AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer]; + [responseSerializer setRemovesKeysWithNullValues:YES]; //去除空值 + responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObjectsFromSet:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", @"text/plain",@"application/atom+xml",@"application/xml",@"text/xml",nil]]; //设置接收内容的格式 + [manager setResponseSerializer:responseSerializer]; + + //HUD 加载菊花 + + [manager POST:@"https://cyxbsmobile.redrock.team/wxapi/mobile-run/home" parameters:@{} success:^(NSURLSessionDataTask *task, id responseObject) { + NSLog(@"请求到的数据 = %@", responseObject); + //hud remove + NSInteger status = [responseObject[@"status"] integerValue]; //NSNumber + if (status == 200) { //1.判断请求成功标志 成功,则继续取数据 +// NSDictionary *data = result[@"data"]; //2.1根据数据类型,层层取数据,直至核心数据 + NSArray *classify = responseObject[@"data"]; //2.2取到一个数组 + +// NSDictionary *runData; //2.3临时容器 +// for (int i = 0; i < classify.count; i++) { //2.4遍历classify数组 +// NSDictionary *tempDic = classify[i]; +// if ([tempDic[@"title"] isEqualToString:@"跑步"]) { +// runData = tempDic; +// break; +// } +// } +// NSArray *tempArr = runData[@"data"]; + + +// self.runDataArr = [GYYRunModel mj_objectArrayWithKeyValuesArray:tempArr]; +// //代码少 +// //用时少 0.001 MJExtension YYModel + +// NSLog(@"%@",responseObject); +// for (int i = 0; i < classify.count; i++) { +// NSDictionary *tempDic = classify[i]; +// GYYRunModel *model = [[GYYRunModel alloc] init]; +// [model setValuesForKeysWithDictionary:tempDic]; //KVC 要走好多方法 访问好多成员变量 +// [self.runDataArr addObject:model]; +// } + //对象数组 键值对数组 字典 + self.runDataArr = [GYYRunModel mj_objectArrayWithKeyValuesArray:classify]; //没有 page size 所以直接赋值 + + + + [self.tableView reloadData]; +// NSArray *classify = result[@"data"][@"classify"]; + }else{ + + } + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSLog(@"=====%@", error); // 404 500 + //MBProgressHUD 服务器异常 请稍后重试 + }]; +} +- (void)healthManagerConfig{ + GYYHealthManager *healthManager = [GYYHealthManager shareInstance]; + [healthManager authorizeHealthKit:^(BOOL success, NSError * _Nonnull error) { + if (success) { + __weak typeof(self) weakSelf = self; //block里避免循环引用,要用__weak 弱引用self 避免循环引用 + __block NSString *todayStais, *yesterdayStairs, *todayStep, *yesterdayStep; //不是属性的基本类型,要用__block修饰 + + dispatch_group_t group = dispatch_group_create();//创建一个任务组 + dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + + //把一个任务异步加到队列 + dispatch_group_enter(group); + dispatch_async(queue, ^{ + // 追加任务 1 + [healthManager getStairIsToday:YES completion:^(double value, NSError * _Nonnull error) { + todayStais = [NSString stringWithFormat:@"%@", [NSNumber numberWithDouble:value]]; + NSLog(@"今日阶梯:%@", todayStais); + dispatch_group_leave(group); + }]; + }); + + dispatch_group_enter(group); + dispatch_async(queue, ^{ + // 追加任务 2 + [healthManager getStairIsToday:NO completion:^(double value, NSError * _Nonnull error) { + yesterdayStairs = [NSString stringWithFormat:@"%@", [NSNumber numberWithDouble:value]]; + NSLog(@"昨日阶梯:%@", yesterdayStairs); + dispatch_group_leave(group); + }]; + }); + + dispatch_group_enter(group); + dispatch_async(queue, ^{ + // 追加任务 3 + [healthManager getStepCountIsToday:YES completion:^(double value, NSError * _Nonnull error) { + todayStep = [NSString stringWithFormat:@"%@", [NSNumber numberWithDouble:value]]; + NSLog(@"今日步数:%@", todayStep); + dispatch_group_leave(group); + }]; + }); + + + dispatch_group_enter(group); + dispatch_async(queue, ^{ + // 追加任务 4 + [healthManager getStepCountIsToday:NO completion:^(double value, NSError * _Nonnull error) { + yesterdayStep = [NSString stringWithFormat:@"%@", [NSNumber numberWithDouble:value]]; + NSLog(@"昨日步数:%@", yesterdayStep); + dispatch_group_leave(group); + }]; + }); + + + //监听任务组事件的执行完毕 + dispatch_group_notify(group, dispatch_get_main_queue(), ^{ + // 等前面的异步任务都执行完毕后,回到主线程执行下边任务 + + NSMutableDictionary *stepDic = weakSelf.dataArray[0]; + NSMutableDictionary *stairsDic = weakSelf.dataArray[1]; + + + [stepDic setObject:(todayStep == nil ? @" 12836" : todayStep) + forKey:@"todayData"]; + [stepDic setObject:(yesterdayStep == nil? @"8762":yesterdayStep) + forKey:@"yesterdayData"]; + + [stairsDic setObject:(todayStais == nil ? @"387" : todayStais) + forKey:@"todayData"]; + [stairsDic setObject:(yesterdayStairs == nil ? @"411" : yesterdayStairs) + forKey:@"yesterdayData"]; + + + [weakSelf.tableView reloadData]; + [weakSelf.tableView layoutIfNeeded]; + }); + }else{ + NSLog(@"权限验证失败"); + } + }]; +} + +- (void)createSubviews{ + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + self.view.backgroundColor = GYYColor; + } else { + self.view.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + + UIView *navView = [[UIView alloc] init]; + [self.view addSubview:navView]; + [navView addSubview:self.navLab]; + [navView addSubview:self.tempLab]; + [navView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.and.top.and.right.mas_equalTo(0); + make.height.mas_equalTo(90); + }]; + [_navLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(15); + make.top.mas_equalTo(63); + }]; + [_tempLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(_navLab.mas_centerY).offset(0); + make.right.mas_equalTo(55); + }]; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + navView.backgroundColor = GYYColor; + } else { + navView.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); } - return _hostView; + [self.view addSubview:self.tableView]; + [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.and.right.mas_equalTo(0); + make.bottom.mas_equalTo(-kTabBarHeight); + make.top.equalTo(navView.mas_bottom).offset(0); + }]; } +//- (void) getDataFromHealth{ +// todaySteps = [self.healthManager getTodayStepCount]; +// yesterdaySteps = [self.healthManager getYesterdayStepCount]; +// todayStairs = [self.healthManager getTodayFlightsClimbedCount]; +// yesterdayStairs = [self.healthManager getYesterdayFlightsClimbedCount]; +//} +//#pragma mark - 懒加载 +//- (ZYLHostView *)hostView{ +// if (!_hostView) { +// _hostView = [[ZYLHostView alloc] init]; +// _hostView.frame = CGRectMake(0, -kStatusBarHeigh*kRateX, screenWidth, screenHeigth); +// _hostView.scrollEnabled = YES; +// _hostView.contentSize = CGSizeMake(screenWidth, screenHeigth+100*kRateY); +// [_hostView.greetLab setText:[NSString stringWithFormat:@"%@%@", [ZYLGetTimeScale getTimeScaleString], [_user valueForKey:@"nickname"]]]; +// +// } +// return _hostView; +//} + +#pragma mark ======== UITableViewDelegate & UITableViewDataSource ======== +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { //分几个区 + return 2; +} + + + +/** + 下面三个方法 必须实现 + */ +//每个分区有多少个cell +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { //每个区有几个cell + if (section == 0){ + return self.dataArray.count; + }else{ + return self.runDataArr.count; //0 4 + } +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { //每个cell的高度 + if (indexPath.section == 0){ + return 137; + }else{ + return 137; + } + +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + if (indexPath.section == 0) { + GYYHealthTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; + cell.runDataDic = self.dataArray[indexPath.row]; + return cell; + }else{ + GYYRunTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:runCellIdentifier forIndexPath:indexPath]; + cell.runModel = self.runDataArr[indexPath.row]; + return cell; + } +} + +//- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ +// //点击触发 +//} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return 25; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{ + return 0.01; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + UIView *headerView = [[UIView alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + headerView.backgroundColor = GYYColor; + } else { + headerView.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + +// if (section == 0) { + UILabel *headerLab = [[UILabel alloc] init]; + [headerView addSubview:headerLab]; + if (section == 0 ) { // 只有label.text是不一样的 所以 if else 判断下赋值不同的text 就可以 + + headerLab.text = @"健康"; + }else{ + headerLab.text = @"跑步"; + } + headerLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size:18]; + if (@available(iOS 13.0, *)) { + headerLab.textColor = [UIColor labelColor]; + } else { + headerLab.textColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + [headerLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(15); + make.centerY.mas_equalTo(0); + }]; +// }else if (section == 1) { +// UILabel *headerLab = [[UILabel alloc] init]; +// [headerView addSubview:headerLab]; +// headerLab.text = @"跑步"; +// headerLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size:18]; +// headerLab.textColor = COLOR_WITH_HEX(0x333739); +// [headerLab mas_makeConstraints:^(MASConstraintMaker *make) { +// make.left.mas_equalTo(15); +// make.centerY.mas_equalTo(0); +// }]; +// } + return headerView; +} + +#pragma mark ======== Getter ========= +- (UILabel *)navLab{ + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *nickname= [user objectForKey:@"nickname"]; + NSString *Labname; + if (!_navLab) { + _navLab = [[UILabel alloc] init]; + + NSDateFormatter *formatter=[[NSDateFormatter alloc]init]; + [formatter setDateFormat:@"HH"]; + NSString *str = [formatter stringFromDate:[NSDate date]]; + int time = [str intValue]; + if(time<=12 && time >=0){ + Labname = [NSString stringWithFormat:@"上午好,%@",nickname]; + } + else{ + Labname = [NSString stringWithFormat:@"下午好,%@",nickname]; + } + _navLab.text = Labname; + _navLab.textColor = COLOR_WITH_HEX(0xA0A0A0); + _navLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size:14]; + } + return _navLab; +} +-(UILabel *)tempLab{ + if (!_tempLab) { + _tempLab = [[UILabel alloc] init]; + _tempLab.text = @"23°C"; + _tempLab.textColor = COLOR_WITH_HEX(0x64686F); + _tempLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size:18]; + } + return _tempLab; +} +- (UITableView *)tableView{ + if (!_tableView) { + _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped]; + if (@available(iOS 11.0, *)) { + _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + } else { + self.automaticallyAdjustsScrollViewInsets = NO; + } + + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + _tableView.backgroundColor = GYYColor; + } else { + _tableView.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + _tableView.showsVerticalScrollIndicator = NO; //右侧 竖条 + _tableView.delegate = self; + _tableView.dataSource = self; + _tableView.estimatedRowHeight = 137; + _tableView.sectionHeaderHeight = 25; + _tableView.sectionFooterHeight = 0.01; + [_tableView registerClass:[GYYHealthTableViewCell class] forCellReuseIdentifier:cellIdentifier]; + [_tableView registerClass:[GYYRunTableViewCell class] forCellReuseIdentifier:runCellIdentifier]; + _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + + } + return _tableView; +} + +- (NSMutableArray *)runDataArr{ + if (!_runDataArr) { + _runDataArr = [NSMutableArray array]; + } + return _runDataArr; +} + +- (NSMutableArray *)dataArray{ + if (!_dataArray) { + _dataArray = [NSMutableArray array]; + + NSMutableDictionary *stepDic = [NSMutableDictionary dictionaryWithDictionary:@{@"icon" : @"homepage_step", + @"title" : @"步数", + @"todayData" : @"0", + @"todayTitle" : @"今日步数", + @"unit" : @"步", + @"yesterdayData" : @"0", + @"yesterdayTitle" : @"昨日步数" + }]; + + NSDictionary *stairDic = [NSMutableDictionary + dictionaryWithDictionary:@{@"icon" : @"homepage_stairs", + @"title" : @"已爬阶梯", + @"todayData" : @"0", + @"todayTitle" : @"今日阶梯", + @"unit" : @"层", + @"yesterdayData" : @"0", + @"yesterdayTitle" : @"昨日阶梯" + }]; +// NSDictionary *mileDic = @{@"icon" : @"homepage_kilometer", +// @"title" : @"里程", +// @"todayData" : @"5.42", +// @"todayTitle" : @"今日里程", +// @"unit" : @"公里", +// @"yesterdayData" : @"3.55", +// @"yesterdayTitle" : @"昨日里程" +// }; +// NSDictionary *timeDic = @{@"icon" : @"homepage_time", +// @"title" : @"运动时间", +// @"todayData" : @"4:42", +// @"todayTitle" : @"今日运动时间", +// @"unit" : @"时间", +// @"yesterdayData" : @"3:34", +// @"yesterdayTitle" : @"昨日运动时间" +// }; +// NSDictionary *paceDic = @{@"icon" : @"homepage_pace", +// @"title" : @"步频", +// @"todayData" : @"5.42", +// @"todayTitle" : @"本次里程", +// @"unit" : @"公里", +// @"yesterdayData" : @"3.55", +// @"yesterdayTitle" : @"上次里程" +// }; +// NSDictionary *consumeDic = @{@"icon" : @"homepage_consume", +// @"title" : @"消耗", +// @"todayData" : @"4:42", +// @"todayTitle" : @"今日运动时间", +// @"unit" : @"时间", +// @"yesterdayData" : @"3:34", +// @"yesterdayTitle" : @"昨日运动时间" +// }; + [_dataArray addObject:stepDic]; + [_dataArray addObject:stairDic]; +// [_dataArray addObject:mileDic]; +// [_dataArray addObject:timeDic]; +// [_dataArray addObject:paceDic]; +// [_dataArray addObject:consumeDic]; + } + return _dataArray; +} @end diff --git a/MRMobileRun/MRMineView/Model/MGDSportData.h b/MRMobileRun/MRMineView/Model/MGDSportData.h new file mode 100644 index 0000000..db33733 --- /dev/null +++ b/MRMobileRun/MRMineView/Model/MGDSportData.h @@ -0,0 +1,47 @@ +// +// MGDSportData.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/31. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDSportData : NSObject + +@property (nonatomic, strong) NSString *distance; + +@property (nonatomic, strong) NSString *totalTime; + +@property (nonatomic, strong) NSString *cal; + +@property (nonatomic, strong) NSString *AverageSpeed; + +@property (nonatomic, strong) NSString *AverageStepFrequency; + +@property (nonatomic, strong) NSString *MaxSpeed; + +@property (nonatomic, strong) NSString *MaxStepFrequency; + +@property (nonatomic, strong) NSString *FinishDate; + +@property (nonatomic, strong) NSString *Weather; + +@property (nonatomic, strong) NSString *Temperature; + +@property (nonatomic, strong) NSArray *StepFrequencyArray; + +@property (nonatomic, strong) NSArray *SpeedArray; + +//一个数组 +@property (nonatomic, strong) NSArray *pathArray; + +-(instancetype)initWithDic:(NSDictionary *)dict; + ++(instancetype)SportDataWithDict:(NSDictionary *)dict; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/Model/MGDSportData.m b/MRMobileRun/MRMineView/Model/MGDSportData.m new file mode 100644 index 0000000..ed9aa1a --- /dev/null +++ b/MRMobileRun/MRMineView/Model/MGDSportData.m @@ -0,0 +1,87 @@ +// +// MGDSportData.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/31. +// + +#import "MGDSportData.h" + +@implementation MGDSportData + +-(instancetype)initWithDic:(NSDictionary *)dict { + if (self = [super init]) { + self.totalTime = dict[@"Duration"]; + self.distance = dict[@"Mileage"]; + self.cal = dict[@"Kcal"]; + self.FinishDate = dict[@"FinishDate"]; + self.AverageSpeed = dict[@"AverageSpeed"]; + self.AverageStepFrequency = dict[@"AverageStepFrequency"]; + self.MaxSpeed = dict[@"MaxSpeed"]; + self.MaxStepFrequency = dict[@"MaxStepFrequency"]; + self.Temperature = dict[@"Temperature"]; + self.Weather = dict[@"Weather"]; + + self.StepFrequencyArray = [self StringToArray:dict[@"StepFrequency"]]; + self.SpeedArray = [self StringToArray:dict[@"Speed"]]; + self.pathArray = [self StringToArray:dict[@"path"]]; + //字典转模型时取数组 + + } + return self; +} + ++(instancetype)SportDataWithDict:(NSDictionary *)dict { + return [[self alloc] initWithDic:dict]; +} + +- (NSArray *)StringToArray:(NSString *)JsonStr { + NSString *str = JsonStr; + if (str.length > 0) { + str = [str substringFromIndex:2]; + NSArray *tempArr = [str componentsSeparatedByString:@"],["]; + return tempArr; + }else { + return @[]; + } +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + if (self = [super init]) { + self.totalTime = [aDecoder decodeObjectForKey:@"totalTime"]; + self.distance = [aDecoder decodeObjectForKey:@"distance"]; + self.cal = [aDecoder decodeObjectForKey:@"cal"]; + self.FinishDate = [aDecoder decodeObjectForKey:@"FinishDate"]; + self.AverageSpeed = [aDecoder decodeObjectForKey:@"AverageSpeed"]; + self.AverageStepFrequency = [aDecoder decodeObjectForKey:@"AverageStepFrequency"]; + self.MaxSpeed = [aDecoder decodeObjectForKey:@"MaxSpeed"]; + self.MaxStepFrequency = [aDecoder decodeObjectForKey:@"MaxStepFrequency"]; + self.Temperature = [aDecoder decodeObjectForKey:@"Temperature"]; + self.Weather = [aDecoder decodeObjectForKey:@"Weather"]; + self.StepFrequencyArray = [aDecoder decodeObjectForKey:@"StepFrequencyArray"]; + self.SpeedArray = [aDecoder decodeObjectForKey:@"SpeedArray"]; + self.pathArray = [aDecoder decodeObjectForKey:@"pathArray"]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.totalTime forKey:@"totalTime"]; + [aCoder encodeObject:self.distance forKey:@"distance"]; + [aCoder encodeObject:self.cal forKey:@"cal"]; + [aCoder encodeObject:self.FinishDate forKey:@"FinishDate"]; + [aCoder encodeObject:self.AverageSpeed forKey:@"AverageSpeed"]; + [aCoder encodeObject:self.AverageStepFrequency forKey:@"AverageStepFrequency"]; + [aCoder encodeObject:self.MaxSpeed forKey:@"MaxSpeed"]; + [aCoder encodeObject:self.MaxStepFrequency forKey:@"MaxStepFrequency"]; + [aCoder encodeObject:self.Temperature forKey:@"Temperature"]; + [aCoder encodeObject:self.Weather forKey:@"Weather"]; + [aCoder encodeObject:self.StepFrequencyArray forKey:@"StepFrequencyArray"]; + [aCoder encodeObject:self.SpeedArray forKey:@"SpeedArray"]; + [aCoder encodeObject:self.pathArray forKey:@"pathArray"]; + +} + + +@end + diff --git a/MRMobileRun/MRMineView/Model/MGDUserData.h b/MRMobileRun/MRMineView/Model/MGDUserData.h new file mode 100644 index 0000000..8bae4e2 --- /dev/null +++ b/MRMobileRun/MRMineView/Model/MGDUserData.h @@ -0,0 +1,22 @@ +// +// mgduserdata.h +// MRMobileRun +// +// Created by 阿栋 on 2020/8/1. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDUserData : NSObject + +@property (nonatomic, copy) NSString *distance; +@property (nonatomic, copy) NSString *duration; +@property (nonatomic, copy) NSString *consume; + +-(instancetype)initWithDic:(NSDictionary *)dict; ++ (instancetype)DataWithDict:(NSDictionary *)dict; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/Model/MGDUserData.m b/MRMobileRun/MRMineView/Model/MGDUserData.m new file mode 100644 index 0000000..077452f --- /dev/null +++ b/MRMobileRun/MRMineView/Model/MGDUserData.m @@ -0,0 +1,25 @@ +// +// mgduserdata.m +// MRMobileRun +// +// Created by 阿栋 on 2020/8/1. +// + +#import "MGDUserData.h" + +@implementation MGDUserData + +- (instancetype)initWithDic:(NSDictionary *)dict { + if (self = [super init]) { + self.distance = dict[@"TotalDistance"]; + self.duration = dict[@"TotalDuration"]; + self.consume = dict[@"TotalConsume"]; + } + return self; +} + ++ (instancetype)DataWithDict:(NSDictionary *)dict { + return [[self alloc] initWithDic:dict]; +} + +@end diff --git a/MRMobileRun/MRMineView/Tool/MGDDataTool.h b/MRMobileRun/MRMineView/Tool/MGDDataTool.h new file mode 100644 index 0000000..6fa18c9 --- /dev/null +++ b/MRMobileRun/MRMineView/Tool/MGDDataTool.h @@ -0,0 +1,23 @@ +// +// MGDDataTool.h +// MRMobileRun +// +// Created by 阿栋 on 2020/10/11. +// + + +#import +#import "MGDSportData.h" +#import "MGDCellDataViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDDataTool : NSObject + ++ (MGDCellDataViewController *) DataToMGDCellDataVC:(MGDSportData *)model; ++ (NSArray *)DataViewArray:(NSArray *)dataArr; ++ (NSMutableArray *)cleanZeroData:(NSMutableArray *)array; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/Tool/MGDDataTool.m b/MRMobileRun/MRMineView/Tool/MGDDataTool.m new file mode 100644 index 0000000..8a431c3 --- /dev/null +++ b/MRMobileRun/MRMineView/Tool/MGDDataTool.m @@ -0,0 +1,76 @@ +// +// MGDDataTool.m +// MRMobileRun +// +// Created by 阿栋 on 2020/10/11. +// + +#import "MGDDataTool.h" +#import "MGDTimeTool.h" +#import + +@implementation MGDDataTool + ++ (MGDCellDataViewController *) DataToMGDCellDataVC:(MGDSportData *)model { + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + MGDCellDataViewController *detailDataVC = [[MGDCellDataViewController alloc] init]; + //距离 + detailDataVC.distanceStr = [NSString stringWithFormat:@"%.2f",[model.distance floatValue] / 1000]; + //日期 + detailDataVC.date = [MGDTimeTool getDateStringWithTimeStr:[NSString stringWithFormat:@"%@", model.FinishDate]]; + //时间 + detailDataVC.time = [MGDTimeTool getTimeStringWithTimeStr:[NSString stringWithFormat:@"%@",model.FinishDate]]; + //速度 + detailDataVC.speedStr = [MGDTimeTool getAverageSpeed:[NSString stringWithFormat:@"%0.2f",[model.AverageSpeed floatValue]]]; + //步频 + detailDataVC.stepFrequencyStr = [NSString stringWithFormat:@"%d",[model.AverageStepFrequency intValue]]; + //跑步时长 + detailDataVC.timeStr = [MGDTimeTool getRunTimeFromSS:model.totalTime]; + //卡路里 + detailDataVC.energyStr = [NSString stringWithFormat:@"%d",[model.cal intValue]]; + //最大速度 + detailDataVC.MaxSpeed = [NSString stringWithFormat:@"%0.2f",[model.MaxSpeed floatValue]]; + //最大步频 + detailDataVC.MaxStepFrequency = [NSString stringWithFormat:@"%d",[model.MaxStepFrequency intValue]]; + //温度 + detailDataVC.degree = [NSString stringWithFormat:@"%d°C",[model.Temperature intValue]]; + //步频数组,用于画图 + detailDataVC.stepFrequencyArray = [self DataViewArray:model.StepFrequencyArray]; + //速度数组,用于画图 + detailDataVC.speedArray = [self DataViewArray:model.SpeedArray]; + //路径数组,用于绘制轨迹 + detailDataVC.locationAry = [self DataViewArray:model.pathArray]; + detailDataVC.userIconStr = [user objectForKey:@"avatar_url"]; + detailDataVC.userNmaeStr = [user objectForKey:@"nickname"]; + return detailDataVC; +} + ++ (NSArray *)DataViewArray:(NSArray *)dataArr { + NSString *CLASS = [NSString stringWithFormat:@"%@",[dataArr class]]; + if ([CLASS isEqualToString:@"__NSSingleObjectArrayI"]) { + return @[]; + }else { + NSMutableArray *test = [dataArr mutableCopy]; + NSString *s = test.lastObject; + [test removeLastObject]; + s = [s substringToIndex:s.length - 2]; + [test addObject:s]; + return [test copy]; + } +} + +//解决杨诚上传的空数组的BUG,如果时间戳为0的话,去除该数据 ++ (NSMutableArray *)cleanZeroData:(NSMutableArray *)array { + NSArray *TempArray = [NSArray arrayWithArray:array]; + for (MGDSportData *model in TempArray) { + NSString *date = [NSString stringWithFormat:@"%@",model.FinishDate]; + if ([date isEqualToString:@"0"]) { + [array removeObject:model]; + } + + } + return array; +} + + +@end diff --git a/MRMobileRun/MRMineView/Tool/MGDRefreshTool.h b/MRMobileRun/MRMineView/Tool/MGDRefreshTool.h new file mode 100644 index 0000000..7441b40 --- /dev/null +++ b/MRMobileRun/MRMineView/Tool/MGDRefreshTool.h @@ -0,0 +1,19 @@ +// +// MGDRefreshTool.h +// MRMobileRun +// +// Created by 阿栋 on 2020/10/11. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDRefreshTool : NSObject + ++ (void)setUPHeader:(MJRefreshNormalHeader *)header AndFooter:(MJRefreshBackNormalFooter *)footer; ++ (void)setUPHeader:(MJRefreshNormalHeader *)header; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/Tool/MGDRefreshTool.m b/MRMobileRun/MRMineView/Tool/MGDRefreshTool.m new file mode 100644 index 0000000..eedce30 --- /dev/null +++ b/MRMobileRun/MRMineView/Tool/MGDRefreshTool.m @@ -0,0 +1,43 @@ +// +// MGDRefreshTool.m +// MRMobileRun +// +// Created by 阿栋 on 2020/10/11. +// + + +#import "MGDRefreshTool.h" + +@implementation MGDRefreshTool + ++ (void)setUPHeader:(MJRefreshNormalHeader *)header AndFooter:(MJRefreshBackNormalFooter *)footer { + //上滑加载的设置 + [footer setTitle:@"上滑加载更多" forState:MJRefreshStateIdle]; + [footer setTitle:@"上滑加载更多" forState:MJRefreshStatePulling]; + [footer setTitle:@"正在加载中" forState:MJRefreshStateRefreshing]; + [footer setTitle:@"暂无更多数据" forState:MJRefreshStateNoMoreData]; + + [header setTitle:@"正在刷新中………"forState:MJRefreshStateRefreshing]; + [header setTitle:@"松开刷新" forState:MJRefreshStatePulling]; + [header setTitle:@"下拉刷新" forState:MJRefreshStateIdle]; + //刷新字体的深色模式适配 + if (@available(iOS 11.0, *)) { + header.stateLabel.textColor = MGDTextColor1; + footer.stateLabel.textColor = MGDTextColor1; + } else { + // Fallback on earlier versions + } +} + ++ (void)setUPHeader:(MJRefreshNormalHeader *)header { + [header setTitle:@"正在刷新中………"forState:MJRefreshStateRefreshing]; + [header setTitle:@"松开刷新" forState:MJRefreshStatePulling]; + [header setTitle:@"下拉刷新" forState:MJRefreshStateIdle]; + if (@available(iOS 11.0, *)) { + header.stateLabel.textColor = MGDTextColor1; + } else { + // Fallback on earlier versions + } +} + +@end diff --git a/MRMobileRun/MRMineView/Tool/MGDTimeTool.h b/MRMobileRun/MRMineView/Tool/MGDTimeTool.h new file mode 100644 index 0000000..b82e341 --- /dev/null +++ b/MRMobileRun/MRMineView/Tool/MGDTimeTool.h @@ -0,0 +1,36 @@ +// +// MGDTimeTool.h +// MRMobileRun +// +// Created by 阿栋 on 2020/10/11. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDTimeTool : NSObject +//返回当前的时间 ++ (NSString *) dateToString:(NSDate *)date; +//返回年份 ++ (NSString *) dateToYear:(NSDate *)date; +//返回昨天 ++ (NSString *) yesterdayTostring:(NSDate *)date; +//配速的字符串 ++ (NSString *) getAverageSpeed:(NSString *)averagespeed; +//跑步时间的字符串 ++ (NSString *) getRunTimeFromSS:(NSString *)totalTime; +//秒数转换成时分秒 ++ (NSString *) getMMSSFromSS:(NSString *)totalTime; +//时间戳换成日期 ++ (NSString *) getDateStringWithTimeStr:(NSString *)str; +//时间戳换成具体的时间 ++ (NSString *) getTimeStringWithTimeStr:(NSString *)str; +//返回去年 ++ (NSString *) lastDateTostring:(NSDate *)date; +//获取当前的年份,并且设置列表的年份为 上一年,本年,下一年 ++ (NSArray *)columnYearLabelYear; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/Tool/MGDTimeTool.m b/MRMobileRun/MRMineView/Tool/MGDTimeTool.m new file mode 100644 index 0000000..3bcea22 --- /dev/null +++ b/MRMobileRun/MRMineView/Tool/MGDTimeTool.m @@ -0,0 +1,122 @@ +// +// MGDTimeTool.m +// MRMobileRun +// +// Created by 阿栋 on 2020/10/11. +// + +#import "MGDTimeTool.h" + +@implementation MGDTimeTool + +//返回当前的时间 ++ (NSString *) dateToString:(NSDate *)date { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + NSString *dateStr = [dateFormatter stringFromDate:date]; + return dateStr; +} + +//返回昨天 ++ (NSString *) yesterdayTostring:(NSDate *)date { + NSDate *mydate=[NSDate date]; + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSDateComponents *comps = nil; + comps = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:mydate]; + NSDateComponents *adcomps = [[NSDateComponents alloc] init]; + [adcomps setYear:0]; + [adcomps setMonth:0]; + [adcomps setDay:-1]; + NSDate *newdate = [calendar dateByAddingComponents:adcomps toDate:mydate options:0]; + return [self dateToString:newdate]; +} + +//配速的字符串 ++ (NSString *)getAverageSpeed:(NSString *)averagespeed { + NSArray *array = [averagespeed componentsSeparatedByString:@"."]; + NSString *speed = [NSString stringWithFormat:@"%@'%@''",array[0],array[1]]; + return speed; +} + +//跑步时间的字符串 ++ (NSString *)getRunTimeFromSS:(NSString *)totalTime{ + NSInteger seconds = [totalTime integerValue]; + NSString *str_minute = [NSString stringWithFormat:@"%02ld",(long)(seconds%3600)/60]; + NSString *str_second = [NSString stringWithFormat:@"%02ld",(long)seconds%60]; + NSString *format_time = [NSString stringWithFormat:@"%@:%@",str_minute,str_second]; + return format_time; +} + +//秒数转换成时分秒 ++ (NSString *)getMMSSFromSS:(NSString *)totalTime{ + NSInteger seconds = [totalTime integerValue]; + NSString *str_minute = [[NSString alloc] init]; + NSString *str_second = [NSString stringWithFormat:@"%02ld",(long)seconds%60]; + if (seconds >= 6000) { + str_minute = [NSString stringWithFormat:@"%03ld",(long)(seconds%3600)/60]; + }else { + str_minute = [NSString stringWithFormat:@"%02ld",(long)(seconds%3600)/60]; + } + NSString *format_time = [NSString stringWithFormat:@"%@:%@",str_minute,str_second]; + return format_time; +} + +//时间戳换成日期 ++ (NSString *)getDateStringWithTimeStr:(NSString *)str{ + NSTimeInterval time=[str doubleValue]; + NSDate *detailDate=[NSDate dateWithTimeIntervalSince1970:time]; + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + //设定时间格式,这里可以设置成自己需要的格式 + [dateFormatter setDateFormat:@"MM-dd"]; + NSString *currentDateStr = [dateFormatter stringFromDate: detailDate]; + return currentDateStr; +} + +//时间戳换成具体的时间 ++ (NSString *)getTimeStringWithTimeStr:(NSString *)str { + NSTimeInterval time=[str doubleValue]; + NSDate *detailDate=[NSDate dateWithTimeIntervalSince1970:time]; + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + //设定时间格式,这里可以设置成自己需要的格式 + [dateFormatter setDateFormat:@"HH:mm"]; + NSString *currentDateStr = [dateFormatter stringFromDate: detailDate]; + return currentDateStr; +} + +//返回年份 ++ (NSString *) dateToYear:(NSDate *)date { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; + [dateFormatter setDateFormat:@"yyyy"]; + NSString *dateStr = [dateFormatter stringFromDate:date]; + return dateStr; +} + +//返回去年的时间 ++ (NSString *) lastDateTostring:(NSDate *)date { + NSDate *mydate=[NSDate date]; + NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + NSDateComponents *comps = nil; + comps = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:mydate]; + NSDateComponents *adcomps = [[NSDateComponents alloc] init]; + [adcomps setYear:-1]; + [adcomps setMonth:0]; + [adcomps setDay:0]; + NSDate *newdate = [calendar dateByAddingComponents:adcomps toDate:mydate options:0]; + return [self dateToString:newdate]; +} + +//获取当前的年份,并且设置列表的年份为 上一年,本年,下一年 ++ (NSArray *)columnYearLabelYear { + NSMutableArray *yearArray = [NSMutableArray new]; + NSDate *date =[NSDate date]; + NSDateFormatter *formatter = [[NSDateFormatter alloc]init]; + [formatter setDateFormat:@"yyyy"]; + NSInteger currentYear=[[formatter stringFromDate:date] integerValue]; + for (int i = 2;i >= 0; i--) { + [yearArray addObject:[NSString stringWithFormat:@"%ld",(long)(currentYear - i)]]; + } + return [yearArray copy]; +} + + +@end diff --git a/MRMobileRun/MRMineView/View/MGDBaseInfoView.h b/MRMobileRun/MRMineView/View/MGDBaseInfoView.h new file mode 100644 index 0000000..e58a84a --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDBaseInfoView.h @@ -0,0 +1,36 @@ +// +// MGDBaseInfoView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/9. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDBaseInfoView : UIView + +@property(nonatomic,strong) UIView *backView; + +@property(nonatomic,strong) UIImageView *KmImage; + +@property(nonatomic,strong) UILabel *Kmlab; + +@property(nonatomic,strong) UILabel *kilometre; + +@property(nonatomic,strong) UIImageView *MinImage; + +@property(nonatomic,strong) UILabel *MinLab; + +@property(nonatomic,strong) UILabel *minus; + +@property(nonatomic,strong) UIImageView *calImage; + +@property(nonatomic,strong) UILabel *CalLab; + +@property(nonatomic,strong) UILabel *calories; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/View/MGDBaseInfoView.m b/MRMobileRun/MRMineView/View/MGDBaseInfoView.m new file mode 100644 index 0000000..f129c71 --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDBaseInfoView.m @@ -0,0 +1,251 @@ +// +// MGDBaseInfoView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/9. +// + +#import "MGDBaseInfoView.h" +#import + +#define NUMBERTEXTCOLOR [UIColor colorWithRed:65/255.0 green:68/255.0 blue:72/255.0 alpha:1.0] +#define UNITTEXTCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] + +@implementation MGDBaseInfoView + +-(instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + + UIView *backView = [[UIView alloc] init]; + self.backView = backView; + self.backView.backgroundColor = [UIColor clearColor]; + [self addSubview:backView]; + + UIImageView *KmImage = [[UIImageView alloc] init]; + self.KmImage = KmImage; + [self.backView addSubview:KmImage]; + _KmImage.image = [UIImage imageNamed:@"路程"]; + _KmImage.contentMode = UIViewContentModeScaleAspectFit; + + UIImageView *MinImage = [[UIImageView alloc] init]; + self.MinImage = MinImage; + [self.backView addSubview:MinImage]; + _MinImage.image = [UIImage imageNamed:@"时间"]; + _MinImage.contentMode = UIViewContentModeScaleAspectFit; + + UIImageView *CalImage = [[UIImageView alloc] init]; + self.calImage = CalImage; + [self.backView addSubview:CalImage]; + _calImage.image = [UIImage imageNamed:@"千卡"]; + _calImage.contentMode = UIViewContentModeScaleAspectFit; + + UILabel *KmLab = [[UILabel alloc] init]; + self.Kmlab = KmLab; + [self.backView addSubview:KmLab]; + _Kmlab.textAlignment = NSTextAlignmentCenter; + //_Kmlab.numberOfLines = 0; + _Kmlab.font = [UIFont fontWithName:@"Impact" size: 24]; + + UILabel *MinLab = [[UILabel alloc] init]; + self.MinLab = MinLab; + [self.backView addSubview:MinLab]; + _MinLab.textAlignment = NSTextAlignmentCenter; + //_MinLab.numberOfLines = 0; + _MinLab.font = [UIFont fontWithName:@"Impact" size: 24]; + + UILabel *CalLab = [[UILabel alloc] init]; + self.CalLab = CalLab; + [self.backView addSubview:CalLab]; + _CalLab.textAlignment = NSTextAlignmentCenter; + //_CalLab.numberOfLines = 0; + //字体不同,需要修改 + _CalLab.font = [UIFont fontWithName:@"Impact" size: 24]; + + UILabel *kilometre = [[UILabel alloc] init]; + self.kilometre = kilometre; + [self.backView addSubview:kilometre]; + _kilometre.text = @"公里"; + _kilometre.textAlignment = NSTextAlignmentCenter; + _kilometre.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 16]; + //_kilometre.numberOfLines = 0; + _kilometre.textColor = UNITTEXTCOLOR; + + UILabel *minus = [[UILabel alloc] init]; + self.minus = minus; + [self.backView addSubview:minus]; + _minus.text = @"分"; + _minus.textAlignment = NSTextAlignmentCenter; + _minus.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 16]; + //_minus.numberOfLines = 0; + _minus.textColor = UNITTEXTCOLOR; + + UILabel *calories = [[UILabel alloc] init]; + self.calories = calories; + [self.backView addSubview:calories]; + _calories.text = @"千卡"; + _calories.textAlignment = NSTextAlignmentCenter; + _calories.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 16]; + //_calories.numberOfLines = 0; + _calories.textColor = UNITTEXTCOLOR; + + + if (@available(iOS 11.0, *)) { + self.Kmlab.textColor = MGDTextColor1; + self.MinLab.textColor = MGDTextColor1; + self.CalLab.textColor = MGDTextColor1; + } else { + // Fallback on earlier versions + } + } + return self; +} + + +- (void)layoutSubviews { + [super layoutSubviews]; + if (kIs_iPhoneX) { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth * 0.1441); + make.width.mas_equalTo(screenWidth); + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + }]; + + [_KmImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth * 0.0493); + make.width.mas_equalTo(screenWidth * 0.1067); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.1467); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.0197); + }]; + + [_Kmlab mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth * 0.0345); + make.width.mas_equalTo(screenWidth * 0.24); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.0603); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.0773); + }]; + + [_kilometre mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth * 0.096); + make.height.mas_equalTo(screenHeigth * 0.0222); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.152); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.0936); + }]; + + [_MinImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.KmImage); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.4453); + make.top.mas_equalTo(self.KmImage); + make.width.mas_equalTo(self.KmImage); + }]; + + [_MinLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.Kmlab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.3813); + make.top.mas_equalTo(self.Kmlab); + make.width.mas_equalTo(self.Kmlab); + }]; + + [_minus mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.kilometre); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.4533); + make.top.mas_equalTo(self.kilometre); + make.width.mas_equalTo(self.kilometre); + }]; + + [_calImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.KmImage); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.744); + make.top.mas_equalTo(self.KmImage); + make.width.mas_equalTo(self.KmImage); + }]; + + [_CalLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.Kmlab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.6773); + make.top.mas_equalTo(self.Kmlab); + make.width.mas_equalTo(self.Kmlab); + }]; + + [_calories mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.kilometre); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.7493); + make.top.mas_equalTo(self.kilometre); + make.width.mas_equalTo(self.kilometre); + }]; + }else { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth * 0.1754); + make.width.mas_equalTo(screenWidth); + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + }]; + + [_KmImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth * 0.0493); + make.width.mas_equalTo(screenWidth * 0.1067); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.1467); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.0197); + }]; + + [_Kmlab mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth * 0.042); + make.width.mas_equalTo(screenWidth * 0.24); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.0735); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.0773); + }]; + + [_kilometre mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth * 0.108); + make.height.mas_equalTo(screenHeigth * 0.027); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.152); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.1139); + }]; + + [_MinImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.KmImage); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.4453); + make.top.mas_equalTo(self.KmImage); + make.width.mas_equalTo(self.KmImage); + }]; + + [_MinLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.Kmlab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.3813); + make.top.mas_equalTo(self.Kmlab); + make.width.mas_equalTo(self.Kmlab); + }]; + + [_minus mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.kilometre); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.4533); + make.top.mas_equalTo(self.kilometre); + make.width.mas_equalTo(self.kilometre); + }]; + + [_calImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.KmImage); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.744); + make.top.mas_equalTo(self.KmImage); + make.width.mas_equalTo(self.KmImage); + }]; + + [_CalLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.Kmlab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.6773); + make.top.mas_equalTo(self.Kmlab); + make.width.mas_equalTo(self.Kmlab); + }]; + + [_calories mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(self.kilometre); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.7493); + make.top.mas_equalTo(self.kilometre); + make.width.mas_equalTo(self.kilometre); + }]; + } + + +} + +@end diff --git a/MRMobileRun/MRMineView/View/MGDColumnChartView.h b/MRMobileRun/MRMineView/View/MGDColumnChartView.h new file mode 100644 index 0000000..4d0e62d --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDColumnChartView.h @@ -0,0 +1,35 @@ +// +// MGDColumnChartView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/18. +// + +#import + +NS_ASSUME_NONNULL_BEGIN +@class MGDColumnChartView; + +//协议 +@protocol MGDColumnChartViewDelegate + +//协议方法 +- (NSArray *_Nullable)columnChartTitleArrayYear:(NSString *_Nullable)year; + +- (NSArray *_Nullable)columnChartNumberArrayFor:(NSString *_Nullable)itemName index:(NSInteger)index year:(NSString *_Nonnull)year; + +- (void)changeYearClick:(MGDColumnChartView *_Nullable)chartView sender:(UIButton *_Nullable)sender; + +@end + +@interface MGDColumnChartView : UIView + +@property (nonatomic, weak) id delegate; + +@property (nonatomic, strong) NSString *yearName; + +- (void)reloadData; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/View/MGDColumnChartView.m b/MRMobileRun/MRMineView/View/MGDColumnChartView.m new file mode 100644 index 0000000..9e22cb7 --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDColumnChartView.m @@ -0,0 +1,484 @@ +// +// MGDColumnChartView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/18. +// + +#import "MGDColumnChartView.h" +#import + +#define LINECOLOR [UIColor colorWithRed:85/255.0 green:213/255.0 blue:226/255.0 alpha:1.0] +#define BACKGROUNDCOLOR [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0] +#define COLUMNCHARTCOLOR [UIColor colorWithRed:255/255.0 green:92/255.0 blue:119/255.0 alpha:1.0] +#define XLABELCOLOR [UIColor colorWithRed:51/255.0 green:55/255.0 blue:57/255.0 alpha:1.0] +#define YLABELCOLOR [UIColor colorWithRed:136/255.0 green:136/255.0 blue:136/255.0 alpha:1.0] +#define topMargin 40 +#define leftMargin 25 +#define bottomMargin 25 +#define XLen screenWidth - 23 - 26 +#define YLen 163 + + + + +@interface MGDColumnChartView () { + CGFloat _itemBottomY; + CGFloat _oneItemH; + NSArray *_currentHeaderItem; + NSInteger _firstIndex; + bool _isLayoutChart; +} + +//月份滑动 +@property (nonatomic, strong) UIScrollView *headerView; +//月份按钮 +@property (nonatomic, strong) NSMutableArray *headerBtns; +//下划线 +@property (nonatomic, strong) UIView *linePointView; +//下划线宽度 +@property (nonatomic, assign) CGFloat linePointW; +//月份滑动高度 +@property (nonatomic, assign) CGFloat headerH; +//年份选择 +@property (nonatomic, strong) UIButton *yearLabel; +//柱形图滑动 +@property (nonatomic, strong) UIScrollView *ChartScrollView; +//柱形图 +@property (nonatomic, strong) UIView *chartView; +//柱形图柱子数组 +@property (nonatomic, strong) NSMutableArray *chartItems; + +@property (nonatomic, strong) CALayer *itemX; +@property (nonatomic, strong) CALayer *itemY; +@property (nonatomic, strong) CALayer *axisY; +@property (nonatomic, strong) CALayer *axisX; +@property (nonatomic, strong) CATextLayer *labelX; +@property (nonatomic, strong) CATextLayer *labelY; +@property (nonatomic, strong) CATextLayer *messageX; + + +@end + +@implementation MGDColumnChartView + +- (UIView *)linePointView +{ + if (_linePointView == nil) { + _linePointView = [[UIView alloc] init]; + _linePointView.frame = CGRectMake(0, 25, _linePointW, 4); + _linePointView.backgroundColor = LINECOLOR; + _linePointView.layer.cornerRadius = 2.0; + [self.headerView addSubview:_linePointView]; + } + return _linePointView; +} + +- (NSMutableArray *)headerBtns +{ + if (_headerBtns == nil) { + _headerBtns = [NSMutableArray array]; + } + return _headerBtns; +} + +- (NSMutableArray *)chartItems +{ + if (_chartItems == nil) { + _chartItems = [NSMutableArray array]; + } + return _chartItems; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + [self initChild]; + } + return self; +} + +- (void)initChild { + _linePointW = 42; + _isLayoutChart = false; + + _yearLabel = [UIButton buttonWithType:UIButtonTypeCustom]; + if (@available(iOS 11.0, *)) { + [_yearLabel setTitleColor:MGDtextXColor forState:UIControlStateNormal]; + } else { + // Fallback on earlier versions + } + _yearLabel.titleLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 15]; + [_yearLabel setImage:[UIImage imageNamed:@"矩形"] forState:UIControlStateNormal]; + _yearLabel.imageView.contentMode = UIViewContentModeScaleAspectFit; + _yearLabel.backgroundColor = [UIColor clearColor]; + [_yearLabel setTitleEdgeInsets:UIEdgeInsetsMake(0, -15, 0, 14)]; + [_yearLabel setImageEdgeInsets:UIEdgeInsetsMake(8, 36, 6, 0)]; + _yearLabel.backgroundColor = [UIColor clearColor]; + [_yearLabel addTarget:self action:@selector(yearClick:) forControlEvents:UIControlEventTouchUpInside]; + + _headerView = [[UIScrollView alloc] init]; + _headerView.backgroundColor = [UIColor clearColor]; + _headerView.showsHorizontalScrollIndicator = NO; + _headerView.showsVerticalScrollIndicator = NO; + _headerView.pagingEnabled = NO; + + _chartView = [[UIView alloc] init]; + _chartView.backgroundColor = [UIColor clearColor]; + + + _ChartScrollView = [[UIScrollView alloc] init]; + _ChartScrollView.decelerationRate = 0.15f; + _ChartScrollView.backgroundColor = [UIColor clearColor]; + _ChartScrollView.bounces = NO; + _ChartScrollView.showsHorizontalScrollIndicator = NO; + + if (@available(iOS 11.0, *)) { + self.backgroundColor = MGDColor1; + self.chartView.backgroundColor = MGDColor1; + } else { + // Fallback on earlier versions + } + + [self addSubview:_headerView]; + [self addSubview:_yearLabel]; + [self addSubview:_chartView]; + [self.chartView addSubview:_ChartScrollView]; + [self setFrame]; +} + +- (void)setFrame { + _yearLabel.frame = CGRectMake(screenWidth - 69, 5, 48, 21); + _headerView.frame = CGRectMake(0, 0,screenWidth * 0.4187, 30); + _chartView.frame = CGRectMake(0, 30, screenWidth, 228); + _ChartScrollView.frame = CGRectMake(leftMargin + 1, 0, XLen, 228); + _ChartScrollView.contentSize = CGSizeMake(screenWidth * 0.6875 * 1.80, _ChartScrollView.frame.size.height); +} + + +- (void)yearClick:(UIButton *)sender +{ + if ([_delegate respondsToSelector:@selector(changeYearClick:sender:)]) { + [_delegate changeYearClick:self sender:sender]; + } +} + +- (void)setDelegate:(id)delegate { + _delegate = delegate; + + [self layoutHeaderItem]; + [self layoutChartView]; + [self clickItemIndex:_firstIndex]; +} + +- (void)setYearName:(NSString *)yearName +{ + _yearName = yearName; + [_yearLabel setTitle:yearName forState:UIControlStateNormal]; +} + +//------- 布局header +- (void)layoutHeaderItem +{ + if ([_delegate respondsToSelector:@selector(columnChartTitleArrayYear:)]) { + NSArray *items = [_delegate columnChartTitleArrayYear:_yearName]; + UIButton *lastBtn = nil; + NSInteger currentItem = 0; + if (items.count > 0) { + for (NSInteger i = 0; i < items.count; i++) { + UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; + [btn setTitle:items[i] forState:UIControlStateNormal]; + CGFloat btnx = lastBtn == nil ? 3 : CGRectGetMaxX(lastBtn.frame); + btn.frame = CGRectMake(btnx, 0, btn.frame.size.width + screenWidth * 0.143 , 30); + [self.headerView addSubview:btn]; + + lastBtn = btn; + [btn addTarget:self action:@selector(headerItemClick:) forControlEvents:UIControlEventTouchUpInside]; + if ([@"本月" isEqualToString:items[i]]) { + currentItem = i; + } + btn.tag = i; + [self.headerBtns addObject:btn]; + } + } + + self.headerView.contentSize = CGSizeMake(CGRectGetMaxX(lastBtn.frame), _headerH); + [self setSelectItem:self.headerBtns[currentItem] isAnima:NO]; + + _firstIndex = currentItem; + _currentHeaderItem = items; + } +} + +- (void)headerItemClick:(UIButton *)sender +{ + [self setSelectItem:sender isAnima:true]; +} + +- (void)clickItemIndex:(NSInteger)index +{ + UIButton *sender = self.headerBtns[index]; + [sender sendActionsForControlEvents:UIControlEventTouchUpInside]; +} + +- (void)setSelectItem:(UIButton *)sender isAnima:(BOOL)isAnima +{ + for (UIButton *senderTemp in self.headerBtns) { + [senderTemp setTitleColor:YLABELCOLOR forState:UIControlStateNormal]; + senderTemp.titleLabel.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 16]; + } + + CGFloat senderX = CGRectGetMinX(sender.frame); + CGFloat itemX = senderX + (sender.frame.size.width - _linePointW) * 0.5; + + CGRect lineFrame = self.linePointView.frame; + lineFrame.origin.x = itemX; + + if (isAnima) { + [UIView animateWithDuration:0.2 animations:^{ + self.linePointView.frame = lineFrame; + if (@available(iOS 11.0, *)) { + [sender setTitleColor:MGDTextColor1 forState:UIControlStateNormal]; + } else { + // Fallback on earlier versions + } + sender.titleLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 18]; + }]; + }else { + self.linePointView.frame = lineFrame; + [sender setTitleColor:XLABELCOLOR forState:UIControlStateNormal]; + } + + //停留的位置 + CGFloat senderCenterX = CGRectGetMidX(sender.frame); + + if (senderCenterX < self.headerView.frame.size.width * 0.5) { + [self.headerView setContentOffset:CGPointMake(0, 0) animated:isAnima]; + + }else if (senderCenterX > (self.headerView.contentSize.width - self.headerView.frame.size.width * 0.5)) { + [self.headerView setContentOffset:CGPointMake(self.headerView.contentSize.width - self.headerView.frame.size.width, 0) animated:isAnima]; + + }else { + CGFloat offsetX = senderCenterX - (self.headerView.frame.size.width * 0.5); + [self.headerView setContentOffset:CGPointMake(offsetX, 0) animated:isAnima]; + } + + [self changeChartShowName:sender.currentTitle index:sender.tag]; +} + +//------- 布局chart +- (void)layoutChartView +{ + CGFloat chartSizeH = self.chartView.frame.size.height; + CGFloat itemXMargin = screenWidth * 0.016; + CGFloat itemCountX = 31; + CGFloat itemCountY = 5; + CGFloat itemYH = (YLen - 6) / itemCountY; + CGFloat itemXW = screenWidth * 0.0213; + CGFloat YlabMargin = 15; + + //X轴 + _axisX = [self getSubLine:CGRectMake(leftMargin, topMargin + YLen, XLen , 1)]; + if (@available(iOS 11.0, *)) { + _axisX.backgroundColor = MGDlineColor.CGColor; + } else { + // Fallback on earlier versions + } + [self.chartView.layer addSublayer:_axisX]; + + //Y轴 + _axisY = [self getSubLine:CGRectMake(leftMargin, topMargin, 1, YLen)]; + if (@available(iOS 11.0, *)) { + _axisY.backgroundColor = MGDlineColor.CGColor; + } else { + // Fallback on earlier versions + } + [self.chartView.layer addSublayer:_axisY]; + + for (NSInteger i = 0; i < itemCountY; i++) { + //Y轴的灰色准线 + _itemY = [self getSubLine:CGRectMake(0, CGRectGetMinY(_axisX.frame) - itemYH * (i + 1), _ChartScrollView.contentSize.width, 1)]; + [self.ChartScrollView.layer addSublayer:_itemY]; + + //Y轴文字 + _labelY = [self getYLabel:[NSString stringWithFormat:@"%ld",(long)i+1] font:8 frame:CGRectMake(YlabMargin, _itemY.frame.origin.y - 11, 5, 11)]; + [self.chartView.layer addSublayer:_labelY]; + } + + NSArray *showXArr = @[@"1", @"5", @"10",@"20",@"15",@"25",@"30"]; + for (NSInteger i = 0; i < itemCountX; i++) { + //X轴的柱形 + _itemX = [self getLayer:COLUMNCHARTCOLOR frame:CGRectMake( 9 + (itemXMargin + itemXW) * i, 0, itemXW, CGRectGetMinY(_axisX.frame))]; + _itemX.cornerRadius = 2.0; + //使柱形图始终保持在层级中的最上层 + _itemX.zPosition = 2; + [self.ChartScrollView.layer addSublayer:_itemX]; + + + //X轴的文字 + NSString *currentIndex = [NSString stringWithFormat:@"%ld",(long)i+1]; + if ([showXArr containsObject: currentIndex]) { + _labelX = [self getXLabel:currentIndex font:8 frame:CGRectMake(_itemX.frame.origin.x + itemXW + itemXMargin, _axisX.frame.origin.y + 1, 10, 11)]; + [self.ChartScrollView.layer addSublayer:_labelX]; + } + + [self.chartItems addObject:_itemX]; + } + + _itemBottomY = chartSizeH - leftMargin; + _oneItemH = itemYH; + + + CATextLayer *pointZero = [self getYLabel:@"0" font:8 frame:CGRectMake(15,196,5,11)]; + + _messageX = [self getData:@"日期" font:8 frame:CGRectMake(screenWidth - 31, CGRectGetMaxY(_axisX.frame) + 1,16,11)]; + + CATextLayer *messageY = [self getYLabel:@"千米" font:11 frame:CGRectMake(15,14,22,16)]; + + [self.chartView.layer addSublayer:pointZero]; + [self.chartView.layer addSublayer:_messageX]; + [self.chartView.layer addSublayer:messageY]; +} + + +- (CATextLayer *)getYLabel:(NSString *)str font:(NSInteger)font frame:(CGRect)frame { + CATextLayer *label = [[CATextLayer alloc] init]; + label.string = str; + label.font = (__bridge CFTypeRef _Nullable)@"PingFangSC-Regular"; + label.fontSize = font; + label.frame = frame; + label.alignmentMode = @"center"; + label.contentsScale = 3; + label.foregroundColor = YLABELCOLOR.CGColor; + return label; +} + +- (CATextLayer *)getXLabel:(NSString *)str font:(NSInteger)font frame:(CGRect)frame { + CATextLayer *label = [[CATextLayer alloc] init]; + label.string = str; + label.font = (__bridge CFTypeRef _Nullable)@"PingFangSC-Medium"; + label.fontSize = font; + label.frame = frame; + label.alignmentMode = @"center"; + label.contentsScale = 3; + if (@available(iOS 11.0, *)) { + label.foregroundColor = YLABELCOLOR.CGColor; + } else { + // Fallback on earlier versions + } + return label; +} + +- (CATextLayer *)getData:(NSString *)str font:(NSInteger)font frame:(CGRect)frame { + CATextLayer *label = [[CATextLayer alloc] init]; + label.string = str; + label.font = (__bridge CFTypeRef _Nullable)@"PingFangSC-Medium"; + label.fontSize = font; + label.frame = frame; + label.alignmentMode = @"center"; + label.contentsScale = 3; + if (@available(iOS 11.0, *)) { + label.backgroundColor = MGDColor1.CGColor; + label.foregroundColor = MGDtextXColor.CGColor; + } else { + // Fallback on earlier versions + } + return label; +} + +- (CALayer *)getLayer:(UIColor *)color frame:(CGRect)frame { + CALayer *layer = [[CALayer alloc] init]; + layer.backgroundColor = color.CGColor; + layer.frame = frame; + return layer; +} + +- (CALayer *)getSubLine:(CGRect)frame { + CALayer *layer = [[CALayer alloc] init]; + if (@available(iOS 11.0, *)) { + layer.backgroundColor = MGDLineColor1.CGColor; + } else { + // Fallback on earlier versions + } + layer.frame = frame; + return layer; +} + + +- (CGFloat)getChartH:(CGFloat)chartH +{ + CGFloat itemH = _oneItemH * chartH; + if (chartH > 5.3) { + itemH = _oneItemH * 5.3; + } + return itemH; +} + +- (void)changeChartShowName:(NSString *)name index:(NSInteger) index +{ + if (!_isLayoutChart && [_delegate respondsToSelector:@selector(columnChartNumberArrayFor:index:year:)]) { + NSArray *arr = [_delegate columnChartNumberArrayFor:name index:index year:_yearName]; + if (self.chartItems.count > 0) { + _isLayoutChart = YES; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + self->_isLayoutChart = NO; + }); + [UIView animateWithDuration:0.1 animations:^{ + NSInteger cnt = arr.count; + NSInteger indexTemp = 0; + for (CALayer *item in self.chartItems) { + if (indexTemp <= cnt) { + CGFloat itemH = [self getChartH:[arr[indexTemp] floatValue]]; + item.frame = CGRectMake(item.frame.origin.x, self->_itemBottomY - itemH, item.frame.size.width, itemH); + }else { + //高度设置为0 + CGFloat itemH = [self getChartH:0]; + item.frame = CGRectMake(item.frame.origin.x, self->_itemBottomY - itemH, item.frame.size.width, itemH); + } + indexTemp++; + } + } completion:^(BOOL finished) { + }]; + } + } +} +//换页面时重新显示 +- (void)reloadData +{ + [[self.headerView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; + [self.headerView addSubview:self.linePointView]; + [self.headerBtns removeAllObjects]; + [self layoutHeaderItem]; + [self clickItemIndex:_firstIndex]; +} + +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { + [super traitCollectionDidChange:previousTraitCollection]; + if (@available(iOS 13.0, *)) { + if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) { + // 执行操作 + NSLog(@"改变了模式"); + + CGFloat itemCountY = 5; + CGFloat itemYH = (YLen - 6) / itemCountY; + CGFloat YlabMargin = 15; + + _axisY.backgroundColor = MGDlineColor.CGColor; + _axisX.backgroundColor = MGDlineColor.CGColor; + _messageX.backgroundColor = MGDColor1.CGColor; + _messageX.foregroundColor = MGDtextXColor.CGColor; + for (NSInteger i = 0; i < 5; i++) { + //Y轴的灰色准线 + _itemY = [self getSubLine:CGRectMake(0, CGRectGetMinY(_axisX.frame) - itemYH * (i + 1), _ChartScrollView.contentSize.width, 1)]; + [self.ChartScrollView.layer addSublayer:_itemY]; + + //Y轴文字 + _labelY = [self getYLabel:[NSString stringWithFormat:@"%ld",(long)i+1] font:8 frame:CGRectMake(YlabMargin, _itemY.frame.origin.y - 11, 5, 11)]; + [self.chartView.layer addSublayer:_labelY]; + } + } + } +} + +@end + diff --git a/MRMobileRun/MRMineView/View/MGDMiddleView.h b/MRMobileRun/MRMineView/View/MGDMiddleView.h new file mode 100644 index 0000000..a70cfa7 --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDMiddleView.h @@ -0,0 +1,24 @@ +// +// MGDMiddleView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDMiddleView : UIView + +@property(nonatomic,strong) UIView *backView; + +@property(nonatomic,strong) UIView *dotView; + +@property(nonatomic,strong) UILabel *recordLab; + +@property(nonatomic,strong) UIButton *moreBtn; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/View/MGDMiddleView.m b/MRMobileRun/MRMineView/View/MGDMiddleView.m new file mode 100644 index 0000000..3065db4 --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDMiddleView.m @@ -0,0 +1,125 @@ +// +// MGDMiddleView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import "MGDMiddleView.h" +#import + +#define DOTCOLOR [UIColor colorWithRed:123/255.0 green:183/255.0 blue:196/255.0 alpha:1.0] +#define RECORDCOLOR [UIColor colorWithRed:65/255.0 green:68/255.0 blue:72/255.0 alpha:1.0] +#define BTNCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] + +@implementation MGDMiddleView + +-(instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + + UIView *backView = [[UIView alloc] init]; + self.backView = backView; + [self addSubview:backView]; + + UIView *dotView = [[UIView alloc] init]; + self.dotView = dotView; + _dotView.backgroundColor = DOTCOLOR; + self.dotView.layer.masksToBounds = YES; + self.dotView.layer.cornerRadius = 4.0; + [self.backView addSubview:dotView]; + + UILabel *recordLab = [[UILabel alloc] init]; + self.recordLab = recordLab; + [self.backView addSubview:recordLab]; + + //测试用 + _recordLab.text = @"运动记录"; + + _recordLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _recordLab.textAlignment = NSTextAlignmentLeft; + if (@available(iOS 11.0, *)) { + self.recordLab.textColor = MGDTextColor2; + } else { + // Fallback on earlier versions + } + + UIButton *moreBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + self.moreBtn = moreBtn; + [self.backView addSubview:moreBtn]; + [self.moreBtn setTitle:@"查看更多" forState:UIControlStateNormal]; + [self.moreBtn setTintColor:BTNCOLOR]; + self.moreBtn.titleLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 12]; + } + return self; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + if (kIs_iPhoneX) { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth * 0.0271); + make.width.mas_equalTo(screenWidth); + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + }]; + + [self setMiddleFrame]; + }else { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth * 0.033); + make.width.mas_equalTo(screenWidth); + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + }]; + + [self setMiddleFrame]; + + } +} + +- (void)setMiddleFrame { + if (kIs_iPhoneX) { + [_dotView mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth * 0.0213); + make.height.mas_equalTo(screenHeigth * 0.0099); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.0099); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.04); + }]; + + [_recordLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.0827); + make.width.mas_equalTo(screenWidth * 0.192); + make.height.mas_equalTo(screenHeigth * 0.0271); + }]; + + [_moreBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.824); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.0049); + make.width.mas_equalTo(screenWidth * 0.136); + make.height.mas_equalTo(screenHeigth * 0.029); + }]; + }else { + [_dotView mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.mas_equalTo(screenWidth * 0.0213); + make.height.mas_equalTo(screenHeigth * 0.012); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.012); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.04); + }]; + + [_recordLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.0827); + make.width.mas_equalTo(screenWidth * 0.212); + make.height.mas_equalTo(screenHeigth * 0.033); + }]; + + [_moreBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.824); + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.006); + make.width.mas_equalTo(screenWidth * 0.166); + make.height.mas_equalTo(screenHeigth * 0.0255); + }]; + } +} +@end diff --git a/MRMobileRun/MRMineView/View/MGDSportTableView.h b/MRMobileRun/MRMineView/View/MGDSportTableView.h new file mode 100644 index 0000000..7b05713 --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDSportTableView.h @@ -0,0 +1,18 @@ +// +// MGDSportTableView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDSportTableView : UITableView + +@property(nonatomic,strong) UITableView *sportTableView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/View/MGDSportTableView.m b/MRMobileRun/MRMineView/View/MGDSportTableView.m new file mode 100644 index 0000000..2ec552a --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDSportTableView.m @@ -0,0 +1,42 @@ +// +// MGDSportTableView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import "MGDSportTableView.h" +#import + +@implementation MGDSportTableView + + + +-(instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + UITableView *sportTableView = [[UITableView alloc] init]; + self.sportTableView = sportTableView; + [self addSubview:sportTableView]; + if (@available(iOS 11.0, *)) { + self.backgroundColor = MGDColor3; + } else { + // Fallback on earlier versions + } + } + return self; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + [_sportTableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.mas_equalTo(screenHeigth - 379); + make.width.mas_equalTo(screenWidth); + make.top.mas_equalTo(self.mas_top); + }]; +} + + + + +@end + diff --git a/MRMobileRun/MRMineView/View/MGDSportTableViewCell.h b/MRMobileRun/MRMineView/View/MGDSportTableViewCell.h new file mode 100644 index 0000000..afa60dc --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDSportTableViewCell.h @@ -0,0 +1,36 @@ +// +// MGDSportTableViewCell.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDSportTableViewCell : UITableViewCell + +@property (nonatomic,strong) UILabel *dayLab; + +@property (nonatomic,strong) UILabel *timeLab; + +@property (nonatomic,strong) UILabel *kmLab; + +@property (nonatomic,strong) UILabel *kmUnit; + +@property (nonatomic,strong) UILabel *minLab; + +@property (nonatomic,strong) UILabel *minUnit; + +@property (nonatomic,strong) UILabel *calLab; + +@property (nonatomic,strong) UILabel *calUnit; + +@property (nonatomic,strong) UIView *cellView; + +@property (nonatomic,strong) UIImageView *arrowView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/View/MGDSportTableViewCell.m b/MRMobileRun/MRMineView/View/MGDSportTableViewCell.m new file mode 100644 index 0000000..874624d --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDSportTableViewCell.m @@ -0,0 +1,216 @@ +// +// MGDSportTableViewCell.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import "MGDSportTableViewCell.h" +#import + +#define CELLCOLOR [UIColor colorWithRed:252/255.0 green:252/255.0 blue:252/255.0 alpha:1.0] +#define TEXTCOLOR [UIColor colorWithRed:51/255.0 green:55/255.0 blue:57/255.0 alpha:1.0] +#define UNITCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] + +@implementation MGDSportTableViewCell + + + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { + [self BuildUI]; + [self setFrame]; + self.selectionStyle = UITableViewCellSelectionStyleNone; + } + return self; +} + +- (void)BuildUI { + UILabel *dayLab = [[UILabel alloc] init]; + self.dayLab = dayLab; + [self.contentView addSubview:dayLab]; + _dayLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 17]; + _dayLab.textAlignment = NSTextAlignmentRight; + + UILabel *timeLab = [[UILabel alloc] init]; + self.timeLab = timeLab; + [self.contentView addSubview:timeLab]; + _timeLab.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 10]; + _timeLab.textColor = UNITCOLOR; + _timeLab.textAlignment = NSTextAlignmentRight; + + UIView *cellView = [[UIView alloc] init]; + self.cellView = cellView; + self.cellView.layer.cornerRadius = 12.0; + self.cellView.layer.shadowColor = [UIColor colorWithRed:136/255.0 green:154/255.0 blue:181/255.0 alpha:0.05].CGColor; + self.cellView.layer.shadowOffset = CGSizeMake(0,3); + self.cellView.layer.shadowOpacity = 1; + self.cellView.layer.shadowRadius = 6; + [self.contentView addSubview:cellView]; + + UILabel *kmLab = [[UILabel alloc] init]; + self.kmLab = kmLab; + [self.cellView addSubview:kmLab]; + _kmLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _kmLab.textAlignment = NSTextAlignmentCenter; + + UILabel *kmUnit = [[UILabel alloc] init]; + self.kmUnit = kmUnit; + [self.cellView addSubview:kmUnit]; + _kmUnit.text = @"公里"; + _kmUnit.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 11]; + _kmUnit.textColor = UNITCOLOR; + _kmUnit.textAlignment = NSTextAlignmentCenter; + + UILabel *minLab = [[UILabel alloc] init]; + self.minLab = minLab; + [self.cellView addSubview:minLab]; + //测试用数据 + _minLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _minLab.textAlignment = NSTextAlignmentCenter; + + UILabel *minUnit = [[UILabel alloc] init]; + self.minUnit = minUnit; + [self.cellView addSubview:minUnit]; + _minUnit.text = @"时间"; + _minUnit.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 11]; + _minUnit.textColor = UNITCOLOR; + _minUnit.textAlignment = NSTextAlignmentCenter; + + UILabel *calLab = [[UILabel alloc] init]; + self.calLab = calLab; + [self.cellView addSubview:calLab]; + _calLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _calLab.textAlignment = NSTextAlignmentCenter; + + UILabel *calUnit = [[UILabel alloc] init]; + self.calUnit = calUnit; + [self.cellView addSubview:calUnit]; + _calUnit.text = @"千卡"; + _calUnit.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 11]; + _calUnit.textColor = UNITCOLOR; + _calUnit.textAlignment = NSTextAlignmentCenter; + + UIImageView *arrowView = [[UIImageView alloc] init]; + self.arrowView = arrowView; + [self.cellView addSubview:arrowView]; + self.arrowView.image = [UIImage imageNamed:@"arraw"]; + + if (@available(iOS 11.0, *)) { + self.contentView.backgroundColor = MGDColor3; + self.dayLab.textColor = MGDTextColor1; + self.cellView.backgroundColor = MGDColor1; + self.kmLab.textColor = MGDTextColor1; + self.minLab.textColor = MGDTextColor1; + self.calLab.textColor = MGDTextColor1; + } else { + // Fallback on earlier versions + } +} + +- (void)setFrame { + [_dayLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.contentView.mas_top); + make.right.mas_equalTo(self.cellView.mas_left).mas_offset(-screenWidth * 0.0293); + make.left.mas_equalTo(self.mas_left).mas_offset(screenWidth * 0.022); + make.height.mas_equalTo(screenHeigth * 0.036); + }]; + + [_timeLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.dayLab.mas_bottom).mas_offset(-1); + make.right.mas_equalTo(self.dayLab); + make.left.mas_equalTo(self.mas_left).mas_offset(screenWidth * 0.0773); + make.height.equalTo(@14); + }]; + if (kIs_iPhoneX) { + [_cellView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.contentView.mas_top); + make.left.mas_equalTo(self.contentView.mas_left).mas_offset(screenWidth * 0.2133); + make.right.mas_equalTo(self.contentView.mas_right); + make.height.mas_equalTo(screenHeigth * 0.078); + }]; + }else { + [_cellView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.contentView.mas_top); + make.left.mas_equalTo(self.contentView.mas_left).mas_offset(screenWidth * 0.2133); + make.right.mas_equalTo(self.contentView.mas_right); + make.height.mas_equalTo(screenHeigth * 0.09); + }]; + } + + CGFloat w = 0; + CGFloat h = 0; + + if (kIs_iPhoneX) { + w = screenWidth * 0.7867; + h = screenHeigth * 0.0738; + }else { + w = screenWidth * 0.7867; + h = screenHeigth * 0.09; + } + + + [_kmLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.cellView.mas_top).mas_offset(h * 0.2167); + make.left.mas_equalTo(self.cellView.mas_left).mas_offset(w * 0.0237); + make.width.mas_equalTo(w * 0.2373); + make.height.mas_equalTo(h * 0.3); + }]; + + [_kmUnit mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.cellView.mas_top).mas_offset(h * 0.5333); + make.left.mas_equalTo(self.cellView.mas_left).mas_offset(w * 0.078); + make.width.mas_equalTo(w * 0.122); + make.height.mas_equalTo(h * 0.2333); + }]; + + [_minLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.kmLab); + make.left.mas_equalTo(self.cellView.mas_left).mas_offset(w * 0.3356); + make.width.mas_equalTo(self.kmLab); + make.height.mas_equalTo(self.kmLab); + }]; + + [_minUnit mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.kmUnit); + make.left.mas_equalTo(self.cellView.mas_left).mas_offset(w * 0.3898); + make.width.mas_equalTo(self.kmUnit); + make.height.mas_equalTo(self.kmUnit); + }]; + + [_calLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.kmLab); + make.left.mas_equalTo(self.cellView.mas_left).mas_offset(w * 0.6475); + make.width.mas_equalTo(self.kmLab); + make.height.mas_equalTo(self.kmLab); + }]; + + [_calUnit mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.kmUnit); + make.left.mas_equalTo(self.cellView.mas_left).mas_offset(w * 0.7051); + make.width.mas_equalTo(self.kmUnit); + make.height.mas_equalTo(self.kmUnit); + }]; + + [_arrowView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.cellView.mas_top).mas_offset(screenHeigth * 0.0329); + make.left.mas_equalTo(self.cellView.mas_left).mas_offset(w * 0.8915); + make.width.mas_equalTo(w * 0.0479); + make.height.mas_equalTo(h * 0.2356); + }]; +} + + + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +@end diff --git a/MRMobileRun/MRMineView/View/MGDTopView.h b/MRMobileRun/MRMineView/View/MGDTopView.h new file mode 100644 index 0000000..e4540d4 --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDTopView.h @@ -0,0 +1,24 @@ +// +// MGDTopView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/9. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDTopView : UIView + +@property(nonatomic,strong) UIView *topView; + +@property(nonatomic,strong) UIImageView *userIcon; + +@property(nonatomic,strong) UILabel *userName; + +@property(nonatomic,strong) UILabel *personalSign; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/View/MGDTopView.m b/MRMobileRun/MRMineView/View/MGDTopView.m new file mode 100644 index 0000000..0ec7262 --- /dev/null +++ b/MRMobileRun/MRMineView/View/MGDTopView.m @@ -0,0 +1,134 @@ +// +// MGDTopView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/9. +// + +#import "MGDTopView.h" +#import "ZYLAvatarRequest.h" +#import +#import "UIImageView+WebCache.h" +#define SHAWDOWCOLOR [UIColor colorWithRed:136/255.0 green:154/255.0 blue:181/255.0 alpha:0.05] + +@implementation MGDTopView + +-(instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + UIView *topView = [[UIView alloc] init]; + self.topView = topView; + if (@available(iOS 11.0, *)) { + self.topView.backgroundColor = MGDColor1; + } else { + // Fallback on earlier versions + } + self.topView.layer.shadowColor = SHAWDOWCOLOR.CGColor; + self.topView.layer.shadowOffset = CGSizeMake(0,3); + self.topView.layer.shadowOpacity = 1; + self.topView.layer.shadowRadius = 6; + [self addSubview:topView]; + + UIImageView *userIcon = [[UIImageView alloc] init]; + self.userIcon = userIcon; + self.userIcon.layer.masksToBounds = YES; + self.userIcon.layer.cornerRadius = 36.0; + self.userIcon.contentMode = UIViewContentModeScaleToFill; + [self.topView addSubview:userIcon]; + + UILabel *username = [[UILabel alloc] init]; + self.userName = username; + [self.topView addSubview:username]; + _userName.numberOfLines = 0; + _userName.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 18]; + // _userName.textColor = [UIColor colorWithRed:51/255.0 green:55/255.0 blue:57/255.0 alpha:1.0]; + if (@available(iOS 11.0, *)) { + self.userName.textColor = MGDTextColor1; + } else { + // Fallback on earlier versions + } + + UILabel *personalSign = [[UILabel alloc] init]; + self.personalSign = personalSign; + [self.topView addSubview:personalSign]; + _personalSign.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 13]; + _personalSign.textColor = [UIColor colorWithRed:160/255.0 green:160/255.0 blue:160/255.0 alpha:1.0]; + _personalSign.numberOfLines = 0; + [self userInfo]; + } + return self; +} + +- (void)userInfo { + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *nickName = [user objectForKey:@"nickname"]; + NSString *imageUrl = [user objectForKey:@"avatar_url"]; + NSString *signature = [user objectForKey:@"signature"]; + [self.userIcon sd_setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage imageNamed:@"logo头像"] options:SDWebImageRefreshCached]; + self.userName.text = nickName; + self.personalSign.text = signature; +} + + +- (void)layoutSubviews { + [super layoutSubviews]; + if (kIs_iPhoneX) { + [_topView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self); + make.right.mas_equalTo(self); + make.top.mas_equalTo(self.mas_top); + make.height.equalTo(@136); + }]; + + [_userIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@72); + make.width.equalTo(@72); + make.left.mas_equalTo(self.topView.mas_left).mas_offset(16); + make.top.mas_equalTo(self.topView.mas_top).mas_offset(48); + }]; + + [_userName mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@25); + make.leading.lessThanOrEqualTo(self.topView.mas_leading).mas_offset(116); + make.top.lessThanOrEqualTo(self.topView.mas_top).mas_offset(59); + make.width.mas_lessThanOrEqualTo(screenWidth - 116); + }]; + + [_personalSign mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@18); + make.leading.lessThanOrEqualTo(self.topView.mas_leading).mas_offset(116); + make.width.mas_lessThanOrEqualTo(screenWidth - 116); + make.top.lessThanOrEqualTo(self.topView.mas_top).mas_offset(84); + }]; + }else { + [_topView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self); + make.right.mas_equalTo(self); + make.top.mas_equalTo(self.mas_top); + make.height.mas_equalTo(111); + }]; + + [_userIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@72); + make.width.equalTo(@72); + make.left.mas_equalTo(self.topView.mas_left).mas_offset(16); + make.top.mas_equalTo(self.topView.mas_top).mas_offset(23); + }]; + + [_userName mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@25); + make.leading.lessThanOrEqualTo(self.topView.mas_leading).mas_offset(116); + make.top.lessThanOrEqualTo(self.topView.mas_top).mas_offset(34); + make.width.mas_lessThanOrEqualTo(screenWidth - 116); + }]; + + [_personalSign mas_makeConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@18); + make.leading.lessThanOrEqualTo(self.topView.mas_leading).mas_offset(116); + make.width.mas_lessThanOrEqualTo(screenWidth - 116); + make.top.lessThanOrEqualTo(self.topView.mas_top).mas_offset(59); + }]; + } +} + +@end diff --git a/MRMobileRun/MRMineView/ViewController/MGDMineViewController.h b/MRMobileRun/MRMineView/ViewController/MGDMineViewController.h new file mode 100644 index 0000000..7418f56 --- /dev/null +++ b/MRMobileRun/MRMineView/ViewController/MGDMineViewController.h @@ -0,0 +1,36 @@ +// +// MGDMineViewController.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import +#import "MGDTopView.h" +#import "MGDBaseInfoView.h" +#import "MGDMiddleView.h" +#import "MGDSportTableView.h" +#import "MGDSportTableViewCell.h" +#import "MRTabBarView.h" + + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDMineViewController : UIViewController + +@property (nonatomic, strong) UIView *backView; + +@property (nonatomic, strong) MGDTopView *topview; + +@property (nonatomic, strong) MGDBaseInfoView *baseView; + +@property (nonatomic, strong) MGDMiddleView *middleView; + +@property (nonatomic, strong) MGDSportTableView *sportTableView; + +@property (nonatomic, strong) MRTabBarView *tabView; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/ViewController/MGDMineViewController.m b/MRMobileRun/MRMineView/ViewController/MGDMineViewController.m new file mode 100644 index 0000000..26c100b --- /dev/null +++ b/MRMobileRun/MRMineView/ViewController/MGDMineViewController.m @@ -0,0 +1,401 @@ +// +// MGDMineViewController.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/10. +// + +#import "MGDDataTool.h" +#import "MGDTimeTool.h" +#import "MGDRefreshTool.h" +#import "MGDMineViewController.h" +#import "MGDTopView.h" +#import "MGDBaseInfoView.h" +#import "MGDMiddleView.h" +#import "MGDSportTableView.h" +#import "MGDSportTableViewCell.h" +#import "MGDMineViewController.h" +#import "MGDMoreViewController.h" +#import "MGDUserData.h" +#import +#import "UIImageView+WebCache.h" +#import "MRTabBarController.h" +#import "HttpClient.h" +#import "MGDSportData.h" +#import "MGDCellDataViewController.h" +#import +#import "MBProgressHUD.h" + +#define BACKGROUNDCOLOR [UIColor colorWithRed:252/255.0 green:252/255.0 blue:252/255.0 alpha:1.0] + + +@interface MGDMineViewController () { + MJRefreshNormalHeader *_header; +} +@property (nonatomic, strong) MGDUserData *currentModel; //三大数据的模型 +@property (nonatomic, strong) MGDSportData *sportModel; //运动列表数据的模型 +@property (nonatomic, strong) NSMutableArray *userSportArray; //装运动列表的模型的数组 +@property (nonatomic, strong) MBProgressHUD *hud; //失败时的HUD +@property (nonatomic, strong) MBProgressHUD *successHud; //首次使用网络请求加载数据时的HUD +@property (nonatomic, assign) BOOL isConnected; //是否连接了网络 + +@end + +@implementation MGDMineViewController + +NSString *ID = @"Recored_cell"; +static AFHTTPSessionManager *manager; //单例的AFN + +- (void)viewWillAppear:(BOOL)animated { + _isConnected = false; + [self.navigationController setNavigationBarHidden:YES animated:YES]; +} + + +- (void)viewDidLoad { + [super viewDidLoad]; + //设置tabBar的高度 + CGFloat tabBarHeight; + if (kIs_iPhoneX) { + tabBarHeight = 83; + }else { + tabBarHeight = 49; + } + + //UITableView的设置 + if (kIs_iPhoneX) { + self.sportTableView = [[MGDSportTableView alloc] initWithFrame:CGRectMake(0,290, screenWidth, screenHeigth) style:UITableViewStylePlain]; + }else { + self.sportTableView = [[MGDSportTableView alloc] initWithFrame:CGRectMake(0,265, screenWidth, screenHeigth - tabBarHeight) style:UITableViewStylePlain]; + } + //去除分割线 + self.sportTableView.separatorStyle = NO; + self.sportTableView.delegate = self; + self.sportTableView.dataSource = self; + self.sportTableView.scrollEnabled =YES; + [self.view addSubview:self.sportTableView]; + + [self.sportTableView registerClass:[MGDSportTableViewCell class] forCellReuseIdentifier:ID]; + + [self buildUI]; + + //加载数据的操作 + _userSportArray = [[NSMutableArray alloc] init]; + + /** + 三大数据: + 如果是第一次登陆该账号,则请求网络数据,并且写入缓存 + 之后首先读取缓存并展示,同时请求数据,并写入缓存,用于下一次的展示 + 列表数据: + 此处如果是首次登陆该账号,则使用网络数据 + 如果不是,则首先读取缓存的数据 + 如果是第一次打开此程序,然后判断当前网络的状况,如果有网络,则自动刷新,没有网络则不刷新 + 之后再跳转到此页面只读取缓存数据 + */ + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + if (!([user objectForKey:@"km"] && [user objectForKey:@"min"] && [user objectForKey:@"cal"]) && ![user boolForKey:@"MineIsCache"]) { + NSLog(@"==三大数据使用网络请求=="); + [self getBaseInfo]; + [user setBool:YES forKey:@"MineIsCache"]; + [user synchronize]; + }else { + NSLog(@"==三大数据使用缓存数据=="); + self.baseView.Kmlab.text = [NSString stringWithFormat:@"%.2f",[[user objectForKey:@"km"] floatValue]]; + self.baseView.MinLab.text = [NSString stringWithFormat:@"%d",[[user objectForKey:@"min"] intValue]/60]; + self.baseView.CalLab.text = [NSString stringWithFormat:@"%d",[[user objectForKey:@"cal"] intValue]]; + [self refreshBaseDataCache]; + } + + NSData *arrayData = [user objectForKey:@"SportList"]; + NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:arrayData]; + NSMutableArray *sportList = [NSMutableArray arrayWithArray:array]; + _userSportArray = sportList; + if ([user objectForKey:@"SportList"]) { + NSLog(@"==记录列表的缓存的数据=="); + [self setUpRefresh]; + if ([user boolForKey:@"MineIsFirst"]) { + [self checkNetWorkTrans]; + [user setBool:NO forKey:@"MineIsFirst"]; + [user synchronize]; + } + }else { + NSLog(@"==记录列表的网络数据=="); + if ([user boolForKey:@"MineIsFirst"]) { + _successHud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + _successHud.mode = MBProgressHUDModeText; + _successHud.animationType = MBProgressHUDAnimationZoomOut; + _successHud.label.text = @" 正在加载中... "; + [_successHud setOffset:CGPointMake(0, 25)]; + } + [self getUserSportData]; + [user setBool:NO forKey:@"MineIsFirst"]; + [user synchronize]; + } + + //深色模式的适配 + if (@available(iOS 11.0, *)) { + self.view.backgroundColor = MGDColor3; + self.backView.backgroundColor = MGDColor3; + self.sportTableView.backgroundColor = MGDColor3; + } else { + // Fallback on earlier versions + } + [self setUpRefresh]; +} + +-(void)scrollViewDidScroll:(UIScrollView *)scrollView{ + self.sportTableView.contentSize = CGSizeMake(0,screenHeigth - 20); +} + +- (void)buildUI { + _backView = [[UIView alloc] init]; + _topview = [[MGDTopView alloc] init]; + _baseView = [[MGDBaseInfoView alloc] init]; + _middleView = [[MGDMiddleView alloc] init]; + + [_middleView.moreBtn addTarget:self action:@selector(MoreVC) forControlEvents:UIControlEventTouchUpInside]; + + if (kIs_iPhoneX) { + _backView.frame = CGRectMake(0, 0, screenWidth, 290); + _topview.frame = CGRectMake(0,0,screenWidth,136); + _baseView.frame = CGRectMake(0,136,screenWidth,117); + _middleView.frame = CGRectMake(0,253,screenWidth,22); + }else { + _backView.frame = CGRectMake(0, 0, screenWidth, 265); + _topview.frame = CGRectMake(0,0,screenWidth,111); + _baseView.frame = CGRectMake(0,111,screenWidth,117); + _middleView.frame = CGRectMake(0,228,screenWidth,22); + } + //只设置左下角为圆角 + UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.topview.bounds byRoundingCorners:UIRectCornerBottomLeft cornerRadii:CGSizeMake(50, 50)]; + CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; + maskLayer.frame = self.topview.bounds; + maskLayer.path = maskPath.CGPath; + self.topview.layer.mask = maskLayer; + [self.view addSubview:_backView]; + [self.backView addSubview:_topview]; + [self.backView addSubview:_baseView]; + [self.backView addSubview:_middleView]; +} + +- (void)setUpRefresh { + _header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; + self.sportTableView.mj_header = _header; + self.sportTableView.estimatedRowHeight = 0; + [MGDRefreshTool setUPHeader:_header]; +} + +- (void)loadNewData { + [_header beginRefreshing]; + [_userSportArray removeAllObjects]; + [self getUserSportData]; +} + + +#pragma mark- 代理方法 +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ + return screenHeigth * 0.117; +} + +#pragma mark- 数据源方法 +- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + if (_userSportArray.count > 5) { + return 5; + }else { + return _userSportArray.count; + } +} + +//转到杨诚的界面 +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + MGDSportData *model = _userSportArray[indexPath.row]; + MGDCellDataViewController *detailDataVC = [MGDDataTool DataToMGDCellDataVC:model]; + [self.navigationController pushViewController:detailDataVC animated:YES]; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + + //创建单元格(用复用池) + MGDSportTableViewCell* cell = nil; + cell = [tableView dequeueReusableCellWithIdentifier:ID]; + + //展示cell的数据 + if (_userSportArray != nil && ![_userSportArray isKindOfClass:[NSNull class]] && _userSportArray.count != 0) { + MGDSportData *model = _userSportArray[indexPath.row]; + NSString *date = [MGDTimeTool getDateStringWithTimeStr:[NSString stringWithFormat:@"%@", model.FinishDate]]; + NSDate *currentDate = [NSDate date]; + NSString *currentDateStr = [[MGDTimeTool dateToString:currentDate] substringWithRange:NSMakeRange(5,5)]; + NSString *lastDay = [[MGDTimeTool yesterdayTostring:currentDate] substringWithRange:NSMakeRange(5, 5)]; + if ([date isEqualToString:currentDateStr]) { + cell.dayLab.text = @"今天"; + }else if ([date isEqualToString:lastDay]) { + cell.dayLab.text = @"昨天"; + }else { + cell.dayLab.text = date; + } + NSString *time = [MGDTimeTool getTimeStringWithTimeStr:[NSString stringWithFormat:@"%@",model.FinishDate]]; + cell.timeLab.text = time; + cell.kmLab.text = [NSString stringWithFormat:@"%.2f",[model.distance floatValue] / 1000]; + cell.minLab.text = [NSString stringWithFormat:@"%@",[MGDTimeTool getMMSSFromSS:[NSString stringWithFormat:@"%@", model.totalTime]]]; + cell.calLab.text = [NSString stringWithFormat:@"%d",[model.cal intValue]]; + }else { + + } + return cell; +} + +- (void)MoreVC{ + MGDMoreViewController *moreVC = [[MGDMoreViewController alloc] init]; + moreVC.pageNumber = 1; + [self.navigationController pushViewController:moreVC animated:YES]; +} + +//原来的三大数据的网络请求 +- (void)getBaseInfo{ + manager = [AFHTTPSessionManager manager]; + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *token = [user objectForKey:@"token"]; + // 响应 + AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer]; + [responseSerializer setRemovesKeysWithNullValues:YES]; //去除空值 + responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObjectsFromSet:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", @"text/plain",@"application/atom+xml",@"application/xml",nil]]; //设置接收内容的格式 + [manager setResponseSerializer:responseSerializer]; + [manager.requestSerializer setValue:[NSString stringWithFormat:@"%@",token] forHTTPHeaderField:@"token"]; + + [manager POST:@"https://cyxbsmobile.redrock.team/wxapi/mobile-run/getTotalData" parameters:nil + success:^(NSURLSessionDataTask *task, id responseObject) { + NSDictionary *dict = [[NSDictionary alloc] init]; + dict = responseObject[@"data"]; + self->_currentModel = [MGDUserData DataWithDict:dict]; + [self reloadBaseData:self->_currentModel]; + [user setObject:self->_currentModel.distance forKey:@"km"]; + [user setObject:self->_currentModel.duration forKey:@"min"]; + [user setObject:self->_currentModel.consume forKey:@"cal"]; + [user synchronize]; + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSLog(@"=====%@", error); // 404 500 + //MBProgressHUD 服务器异常 请稍后重试 + }]; +} + +- (void)refreshBaseDataCache { + manager = [AFHTTPSessionManager manager]; + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *token = [user objectForKey:@"token"]; + // 响应 + AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer]; + [responseSerializer setRemovesKeysWithNullValues:YES]; //去除空值 + responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObjectsFromSet:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", @"text/plain",@"application/atom+xml",@"application/xml",nil]]; //设置接收内容的格式 + [manager setResponseSerializer:responseSerializer]; + [manager.requestSerializer setValue:[NSString stringWithFormat:@"%@",token] forHTTPHeaderField:@"token"]; + + [manager POST:TotalDataUrl parameters:nil + success:^(NSURLSessionDataTask *task, id responseObject) { + NSDictionary *dict = [[NSDictionary alloc] init]; + dict = responseObject[@"data"]; + self->_currentModel = [MGDUserData DataWithDict:dict]; + [user setObject:self->_currentModel.distance forKey:@"km"]; + [user setObject:self->_currentModel.duration forKey:@"min"]; + [user setObject:self->_currentModel.consume forKey:@"cal"]; + [user synchronize]; + NSLog(@"写入新的缓存"); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSLog(@"=====%@", error); // 404 500 + //MBProgressHUD 服务器异常 请稍后重试 + }]; +} + +//展示跑步总距离的数据 +- (void)reloadBaseData:(MGDUserData *)model { + self.baseView.Kmlab.text = [NSString stringWithFormat:@"%.2f",[model.distance floatValue]]; + self.baseView.MinLab.text = [NSString stringWithFormat:@"%d",[model.duration intValue]/60]; + self.baseView.CalLab.text = [NSString stringWithFormat:@"%d",[model.consume intValue]]; +} + +//获取近五次的运动记录(只显示五次) +- (void)getUserSportData { + manager = [AFHTTPSessionManager manager]; + manager.requestSerializer.cachePolicy = NSURLRequestUseProtocolCachePolicy; + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *token = [user objectForKey:@"token"]; + AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer]; + responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObjectsFromSet:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", @"text/plain",@"application/atom+xml",@"application/xml",nil]]; + [manager setResponseSerializer:responseSerializer]; + [manager.requestSerializer setValue:[NSString stringWithFormat:@"%@",token] forHTTPHeaderField:@"token"]; + NSDate *currentDate = [NSDate date]; + NSString *currentDateStr = [MGDTimeTool dateToString:currentDate]; + NSString *lastDateStr = @"2020-01-01 00:00:00"; + NSDictionary *param = @{@"from_time":lastDateStr,@"to_time":currentDateStr}; + [manager POST:AllSportRecordUrl parameters:param + success:^(NSURLSessionDataTask *task, id responseObject) { + + NSDictionary *dict = [[NSDictionary alloc] init]; + dict = responseObject[@"data"]; + NSArray *record = [[NSArray alloc] init]; + record = dict[@"record_list"]; + [self->_userSportArray removeAllObjects]; + for (NSDictionary *dic in record) { + self->_sportModel = [MGDSportData SportDataWithDict:dic]; + [self->_userSportArray addObject:self->_sportModel]; + } + self->_userSportArray = [[self->_userSportArray reverseObjectEnumerator] allObjects]; + NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:self->_userSportArray]; + [user setObject:arrayData forKey:@"SportList"]; + [user synchronize]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self.sportTableView reloadData]; + }); + [self.sportTableView.mj_header endRefreshing]; + [self->_successHud removeFromSuperview]; + } failure:^(NSURLSessionDataTask *task, NSError *error) { + [self.sportTableView.mj_header endRefreshing]; + [self->_successHud removeFromSuperview]; + NSLog(@"报错信息%@", error); + if (error.code == -1001) { + self->_hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + self->_hud.mode = MBProgressHUDModeText; + self->_hud.label.text = @" 网络异常 请稍后重试 "; + [self->_hud hideAnimated:YES afterDelay:1.5]; + }else { + self->_hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + self->_hud.mode = MBProgressHUDModeText; + self->_hud.label.text = @" 加载失败 "; + [self->_hud hideAnimated:YES afterDelay:1.5]; + } + }]; +} + +- (void)checkNetWorkTrans { + AFNetworkReachabilityManager *managerAF = [AFNetworkReachabilityManager sharedManager]; + [managerAF startMonitoring]; + [managerAF setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { + switch (status) { + case AFNetworkReachabilityStatusUnknown: + self->_isConnected = true; + if (self->_isConnected) { + [self loadNewData]; + } + break; + case AFNetworkReachabilityStatusReachableViaWiFi: + self->_isConnected = true; + if (self->_isConnected) { + [self loadNewData]; + } + NSLog(@"使用WIFI"); + break; + case AFNetworkReachabilityStatusReachableViaWWAN: + self->_isConnected = true; + if (self->_isConnected) { + [self loadNewData]; + } + break; + case AFNetworkReachabilityStatusNotReachable: + self->_isConnected = false; + NSLog(@"没有连接网络"); + break; + } + }]; +} + +@end diff --git a/MRMobileRun/MRMineView/ViewController/MGDMoreViewController.h b/MRMobileRun/MRMineView/ViewController/MGDMoreViewController.h new file mode 100644 index 0000000..fa47b41 --- /dev/null +++ b/MRMobileRun/MRMineView/ViewController/MGDMoreViewController.h @@ -0,0 +1,35 @@ +// +// MGDMoreViewController.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/13. +// + +#import +#import "MGDSportTableView.h" +#include "MGDColumnChartView.h" + + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDMoreViewController : UIViewController + +@property (nonatomic, strong) UIView *backView; + +@property (nonatomic, strong) NSArray *month; + +@property (nonatomic, strong) UIView *titleView; + +@property (nonatomic, strong) UILabel *navBarTitle; + +@property (nonatomic, strong) UIView *divider; + +@property (nonatomic, strong) MGDSportTableView *recordTableView; + +@property (nonatomic, strong) MGDColumnChartView *columnChartView; + +@property (nonatomic, assign) int pageNumber; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRMineView/ViewController/MGDMoreViewController.m b/MRMobileRun/MRMineView/ViewController/MGDMoreViewController.m new file mode 100644 index 0000000..1684c68 --- /dev/null +++ b/MRMobileRun/MRMineView/ViewController/MGDMoreViewController.m @@ -0,0 +1,666 @@ +// +// MGDMoreViewController.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/13. + + +#import "MGDDataTool.h" +#import "MGDTimeTool.h" +#import "MGDRefreshTool.h" +#import "MGDMoreViewController.h" +#import "MGDSportTableViewCell.h" +#import "MGDColumnChartView.h" +#import "YBPopupMenu.h" +#import "MRTabBarController.h" +#import +#import +#import +#import "MGDSportData.h" +#import "MGDCellDataViewController.h" +#import "MBProgressHUD.h" + + + +//此处遵守自定义的MGDColumnChartView的协议,用于切换年份的操作 +@interface MGDMoreViewController () { + BOOL _isShowSec; + NSArray *_selectArr; + MJRefreshBackNormalFooter *_footer; + MJRefreshNormalHeader *_header; +} + +//用于展示页面第一次加载出来时的柱形图数据模型的数组 +@property (nonatomic, strong) NSMutableArray *recordArray; +//用于展示改变年份后的柱形图数据模型的数组 +@property (nonatomic, strong) NSMutableArray *tmpArray; +//用于展示列表数据的数组数据模型的数组 +@property (nonatomic, strong) NSMutableArray *cellListArray; +//列表数据模型 +@property (nonatomic, strong) MGDSportData *userDataModel; +//柱形图数组 +@property (nonatomic, strong) NSMutableArray *chartArr; +//加载数据失败时的hud +@property (nonatomic, strong) MBProgressHUD *hud; +//首次使用网络请求加载数据时的hud +@property (nonatomic, strong) MBProgressHUD *successHud; +//是否连接网络 +@property (nonatomic, assign) BOOL isConnected; +@end + +@implementation MGDMoreViewController + +- (NSMutableArray *)chartArr { + if (_chartArr == nil) { + _chartArr = [NSMutableArray array]; + } + return _chartArr; +} + +NSString *ID1 = @"Sport_cell"; +static int page = 1; +static AFHTTPSessionManager *manager; //单例的AFN + +-(void)viewWillAppear:(BOOL)animated { + [self.navigationController setNavigationBarHidden:NO animated:YES]; + self.tabBarController.tabBar.hidden = YES; + _isConnected = false; +} + +-(void)viewWillDisappear:(BOOL)animated { + self.tabBarController.tabBar.hidden = NO; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.navigationController.navigationBar.translucent = NO; + self.extendedLayoutIncludesOpaqueBars = YES; + self.navigationController.navigationBar.shadowImage = [UIImage new]; + self.title = @"运动记录"; + + //自定义的返回按钮 + UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + [backBtn setImage:[UIImage imageNamed:@"返回箭头4"] forState:UIControlStateNormal]; + [backBtn setImageEdgeInsets:UIEdgeInsetsMake(10, 5, 10, 5)]; + [backBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; + UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:backBtn]; + self.navigationItem.leftBarButtonItem = backItem; + + //UI布局 + if (kIs_iPhoneX) { + _recordTableView = [[MGDSportTableView alloc] initWithFrame:CGRectMake(0, 361, screenWidth, screenHeigth - 361) style:UITableViewStylePlain]; + }else { + _recordTableView = [[MGDSportTableView alloc] initWithFrame:CGRectMake(0, 341, screenWidth, screenHeigth - 341) style:UITableViewStylePlain]; + } + + //UITableView的一些设置 + _recordTableView.separatorStyle = NO; //取消分割线 + _recordTableView.delegate = self; + _recordTableView.dataSource = self; + [self.view addSubview:_recordTableView]; + [_recordTableView registerClass:[MGDSportTableViewCell class] forCellReuseIdentifier:ID1]; + + //深色模式颜色的适配 + if (@available(iOS 11.0, *)) { + self.view.backgroundColor = MGDColor3; + self.recordTableView.backgroundColor = MGDColor1; + self.backView.backgroundColor = MGDColor1; + self.navigationController.navigationBar.barTintColor = MGDColor1; + self.navigationController.navigationBar.tintColor = MGDTextColor1; + } else { + // Fallback on earlier versions + } + + //加载数据的操作 + _recordArray = [[NSMutableArray alloc] init]; + _cellListArray = [[NSMutableArray alloc] init]; + _tmpArray = [[NSMutableArray alloc] init]; + + //获取缓存中的数据 + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + + NSData *ColumnData = [user objectForKey:@"SportMoreList"]; //柱形图的数据 + NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:ColumnData]; + NSMutableArray *ColumnArray = [NSMutableArray arrayWithArray:array]; + + NSData *cellarrayData = [user objectForKey:@"CellData"]; //跑步列表的数据 + NSArray *cellarray = [NSKeyedUnarchiver unarchiveObjectWithData:cellarrayData]; + NSMutableArray *listArray = [NSMutableArray arrayWithArray:cellarray]; + _recordArray = ColumnArray; + _cellListArray = listArray; + + /** + 此处如果是首次登陆该账号,则使用网络数据 + 如果不是,则首先读取缓存的数据 + 如果是第一次打开此程序,然后判断当前网络的状况,如果有网络,则自动刷新,没有网络则不刷新 + 之后再跳转到此页面只读取缓存数据 + */ + if (([user objectForKey:@"SportMoreList"] && [user objectForKey:@"CellData"]) || [user boolForKey:@"MoreIsCache"]) { + NSLog(@"=====使用缓存数据====="); + [self setUpRefresh]; + [self getCache:^(NSMutableArray *recordList) { + [self loadmoreDataWithPageWithCache]; + [self setUI]; + }]; + if ([user boolForKey:@"MoreIsFirst"]) { + [self checkNetWorkTrans]; + [user setBool:NO forKey:@"MoreIsFirst"]; + [user synchronize]; + } + }else { + NSLog(@"=====使用网络数据====="); + [self setUpRefresh]; + [self hud:_successHud setUpHud:@" 正在加载中... "]; + CGFloat margin = 0; + if (kIs_iPhoneX) { + margin = 361+20 - self.view.center.y; + }else { + margin = 361+20 - self.view.center.y; + } + [_successHud setOffset:CGPointMake(0, margin)]; + [self getRecordList:^(NSMutableArray *recordList) { + [self loadmoreDataWithPage:self->_pageNumber]; + [self setUI]; + }]; + [user setBool:YES forKey:@"MoreIsCache"]; + [user setBool:NO forKey:@"MoreIsFirst"]; + [user synchronize]; + } + + //设置右滑返回的手势 + id target = self.navigationController.interactivePopGestureRecognizer.delegate; + //handleNavigationTransition:为系统私有API,即系统自带侧滑手势的回调方法,在自己的手势上直接用它的回调方法 + UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)]; + panGesture.delegate = self; //设置手势代理,拦截手势触发 + [self.view addGestureRecognizer:panGesture]; + self.navigationController.interactivePopGestureRecognizer.enabled = NO; //禁止系统自带的滑动手势 + + //关闭预估高度的效果 + self.recordTableView.estimatedRowHeight = 0; + self.recordTableView.estimatedSectionHeaderHeight = 0; + self.recordTableView.estimatedSectionFooterHeight = 0; +} + + +- (void)handleNavigationTransition:(UIPanGestureRecognizer *)pan { + NSLog(@"右滑返回"); //自定义滑动手势 +} + + +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { + // 当当前控制器是根控制器时,不可以侧滑返回,所以不能使其触发手势 + if(self.navigationController.childViewControllers.count == 1) { + return NO; + } + return YES; +} + +//返回上一个控制器 +- (void) back { + [self.navigationController popViewControllerAnimated:YES]; +} + +//进行UI的布局 +- (void)setUI { + CGFloat navigationBarAndStatusBarHeight = self.navigationController.navigationBar.frame.size.height + [[UIApplication sharedApplication] statusBarFrame].size.height; + if (kIs_iPhoneX) { + _backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, 370)]; + _columnChartView = [[MGDColumnChartView alloc] initWithFrame:CGRectMake(0, navigationBarAndStatusBarHeight, screenWidth, 228)]; + _divider = [[UIView alloc] initWithFrame:CGRectMake(0, 344, screenWidth, 1)]; + }else { + _backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, 348)]; + _columnChartView = [[MGDColumnChartView alloc] initWithFrame:CGRectMake(0, navigationBarAndStatusBarHeight, screenWidth, 228)]; + _divider = [[UIView alloc] initWithFrame:CGRectMake(0, 322, screenWidth, 1)]; + } + + //设置年份 + NSDate *date =[NSDate date]; + _columnChartView.yearName = [MGDTimeTool dateToYear:date]; + _columnChartView.delegate = self; + [self.view addSubview:_backView]; + [self.backView addSubview:_columnChartView]; + + //深色模式的适配 + if (@available(iOS 11.0, *)) { + self.divider.backgroundColor = MGDdividerColor; + self.recordTableView.backgroundColor = MGDColor3; + } else { + // Fallback on earlier versions + } + + [self.view addSubview:_divider]; + _isShowSec = false; + _selectArr = [MGDTimeTool columnYearLabelYear]; +} + +//设置关于列表刷新的相关文字 +- (void)setUpRefresh { + //上滑加载的设置 + _footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; + self.recordTableView.mj_footer = _footer; + + //下拉刷新的设置 + _header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadnewData)]; + self.recordTableView.mj_header = _header; + self.recordTableView.estimatedRowHeight = 0; + + [MGDRefreshTool setUPHeader:_header AndFooter:_footer]; +} + +/** + 首次登陆此账号时的网络请求,获取柱形图的数据,同时写入缓存,并且在block中请求列表的数据 + */ +- (void)getRecordList:(void(^)(NSMutableArray *recordList))result { + AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *token = [user objectForKey:@"token"]; + AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer]; + responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObjectsFromSet:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", @"text/plain",@"application/atom+xml",@"application/xml",nil]]; + [manager setResponseSerializer:responseSerializer]; + [manager.requestSerializer setValue:[NSString stringWithFormat:@"%@",token] forHTTPHeaderField:@"token"]; + NSDate *currentDate = [NSDate date]; + NSString *currentDateStr = [MGDTimeTool dateToString:currentDate]; + NSString *lastDateStr = [MGDTimeTool lastDateTostring:currentDate]; + NSDictionary *param = @{@"from_time":lastDateStr,@"to_time":currentDateStr}; + [manager POST:AllSportRecordUrl parameters:param + success:^(NSURLSessionDataTask *task, id responseObject) { + NSDictionary *dict = [[NSDictionary alloc] init]; + dict = responseObject[@"data"]; + NSArray *record = [[NSArray alloc] init]; + record = dict[@"record_list"]; + for (NSDictionary *dic in record) { + self->_userDataModel = [MGDSportData SportDataWithDict:dic]; + [self->_recordArray addObject:self.userDataModel]; + } + NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:self->_recordArray]; + [user setObject:arrayData forKey:@"SportMoreList"]; + [user synchronize]; + [self makeListData:self->_recordArray]; + //通过block把值传出来 + dispatch_async(dispatch_get_main_queue(), ^{ + result(self->_recordArray); + }); + + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSLog(@"=====%@", error); + [self->_successHud removeFromSuperview]; + [self hud:self->_hud setUpHud:@" 加载失败 "]; + }]; +} + +/** + 上滑加载时,调用此方法,加载新的数据 + */ +- (void) loadMoreData { + [self.recordTableView.mj_footer beginRefreshing]; + if (_footer.state == MJRefreshStateNoMoreData) { + [_footer endRefreshingWithNoMoreData]; + } + //上滑时count++进行查询 + page++; + _pageNumber = page; + [self loadmoreDataWithPage:_pageNumber]; +} + +/** + 下拉刷新时,清除之前的数据,重新加载新的数据 + */ +- (void) loadnewData { + [self.recordTableView.mj_header beginRefreshing]; + page = 1; + self->_pageNumber = page; + [self loadmoreDataWithPageRefresh:self->_pageNumber]; +} + +/** +加载新的数据,同时写入缓存,没有数据时则设置footer的状态,没有网络时提示加载失败 + */ +- (void)loadmoreDataWithPage:(int)page { + manager = [AFHTTPSessionManager manager]; + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *token = [user objectForKey:@"token"]; + AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer]; + responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObjectsFromSet:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", @"text/plain",@"application/atom+xml",@"application/xml",nil]]; + [manager setResponseSerializer:responseSerializer]; + [manager.requestSerializer setValue:[NSString stringWithFormat:@"%@",token] forHTTPHeaderField:@"token"]; + NSDictionary *param = @{@"page":[NSString stringWithFormat:@"%d",_pageNumber],@"count":@"5"}; + [manager POST:SportListUrl parameters:param + success:^(NSURLSessionDataTask *task, id responseObject) { + NSDictionary *dict = [[NSDictionary alloc] init]; + dict = responseObject[@"data"]; + NSArray *record = [[NSArray alloc] init]; + record = dict[@"record_list"]; + //还有数据时继续查询,没有数据了改变状态为没有数据 + if (record.count > 0) { + for (NSDictionary *dic in record) { + self->_userDataModel = [MGDSportData SportDataWithDict:dic]; + [self->_cellListArray addObject:self.userDataModel]; + } + [MGDDataTool cleanZeroData:self->_cellListArray]; + NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:self->_cellListArray]; + [user setObject:arrayData forKey:@"CellData"]; + [user synchronize]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self.recordTableView reloadData]; //列表数据刷新 + [self.recordTableView layoutIfNeeded]; //停止刷新 + }); + [self.recordTableView.mj_footer endRefreshing]; + }else { + self->_footer.state = MJRefreshStateNoMoreData; //改变状态 + } + [self->_successHud removeFromSuperview]; //移除加载中的successHud + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSLog(@"=====%@", error); + [self.recordTableView.mj_footer endRefreshing]; + [self hud:self->_hud setUpHud:@" 加载失败 "]; + }]; +} + +/** + 刷新新的数据后,清除之前的数据,加载新的数据,并且写入缓存,没有网络时提示刷新失败 + */ +- (void)loadmoreDataWithPageRefresh:(int)page { + manager = [AFHTTPSessionManager manager]; + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *token = [user objectForKey:@"token"]; + AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer]; + responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObjectsFromSet:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", @"text/plain",@"application/atom+xml",@"application/xml",nil]]; + [manager setResponseSerializer:responseSerializer]; + [manager.requestSerializer setValue:[NSString stringWithFormat:@"%@",token] forHTTPHeaderField:@"token"]; + NSDictionary *param = @{@"page":[NSString stringWithFormat:@"%d",_pageNumber],@"count":@"5"}; + [manager POST:SportListUrl parameters:param + success:^(NSURLSessionDataTask *task, id responseObject) { + NSDictionary *dict = [[NSDictionary alloc] init]; + dict = responseObject[@"data"]; + NSArray *record = [[NSArray alloc] init]; + record = dict[@"record_list"]; + [self->_cellListArray removeAllObjects]; + //还有数据时继续查询,没有数据了改变状态为没有数据 + if (record.count > 0) { + for (NSDictionary *dic in record) { + self->_userDataModel = [MGDSportData SportDataWithDict:dic]; + [self->_cellListArray addObject:self.userDataModel]; + } + [MGDDataTool cleanZeroData:self->_cellListArray]; + NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:self->_cellListArray]; + [user setObject:arrayData forKey:@"CellData"]; + [user synchronize]; + dispatch_async(dispatch_get_main_queue(), ^{ + //列表数据刷新 + [self.recordTableView reloadData]; + [self.recordTableView layoutIfNeeded]; + [self.recordTableView.mj_header endRefreshing]; //停止刷新 + }); + }else { + self->_footer.state = MJRefreshStateNoMoreData; //改变状态 + } + [self.recordTableView.mj_header endRefreshing]; + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSLog(@"=====%@", error); + [self.recordTableView.mj_header endRefreshing]; + [self hud:self->_hud setUpHud:@"刷新失败"]; + }]; +} + +/** + 通过缓存读取数据 + */ +- (void)loadmoreDataWithPageWithCache{ + [self setUpRefresh]; + dispatch_async(dispatch_get_main_queue(), ^{ + //列表数据刷新 + [self.recordTableView reloadData]; + [self.recordTableView layoutIfNeeded]; + //停止刷新 + }); + [self.recordTableView.mj_footer endRefreshing]; +} + +- (void)changeYearClick:(MGDColumnChartView *)chartView sender:(UIButton *)sender { + [self showYearSelect:sender]; +} + +//判断月份并且截取月份,设置当月为"本月" +- (NSArray *)columnChartTitleArrayYear:(NSString *)year { + NSDate *date =[NSDate date]; + NSDateFormatter *formatter = [[NSDateFormatter alloc]init]; + + [formatter setDateFormat:@"yyyy"]; + NSInteger currentYear=[[formatter stringFromDate:date] integerValue]; + [formatter setDateFormat:@"MM"]; + NSInteger currentMonth=[[formatter stringFromDate:date]integerValue]; + NSMutableArray *monthArray = [NSMutableArray arrayWithArray:@[@"1月", @"2月", @"3月", @"4月", @"5月", @"6月", @"7月", @"8月", @"9月", @"10月", @"11月", @"12月"]]; + NSString *month = @"月"; + NSMutableArray *nowArray = [NSMutableArray new]; + if ([year isEqualToString:[NSString stringWithFormat: @"%ld", (long)currentYear]]) { + for (int i = 0;i < monthArray.count; i++) { + NSString *nowMonth = [NSString stringWithFormat:@"%d", i+1]; + if ([nowMonth isEqualToString:[NSString stringWithFormat:@"%ld", (long)currentMonth]]) { + [nowArray addObject:@"本月"]; + break; + } + [nowArray addObject:[[NSString stringWithFormat:@"%d", i+1] stringByAppendingString:month]]; + } + return [nowArray copy]; + }else { + return [monthArray copy]; + } +} + +//获取柱形图的数据,无数据设为0 +- (NSArray *)columnChartNumberArrayFor:(NSString *)itemName index:(NSInteger)index year:(NSString *)year { + NSMutableArray *arr = [NSMutableArray array]; + NSDictionary *dic = self.chartArr[index]; + for (NSInteger i = 0; i < 31; i++) { + NSString* point = [NSString stringWithFormat:@"%ld", (long)i]; + if (point.length == 1) { + point = [NSString stringWithFormat:@"0%@", point]; + } + NSString *num = dic[point]; + if (num) { + [arr addObject:num]; + }else { + [arr addObject:@"0"]; + } + } + return arr; +} + +- (void)showYearSelect:(UIButton *)sender { + [YBPopupMenu showRelyOnView:sender titles:_selectArr icons:@[@"", @"", @""] menuWidth:180 delegate:self]; +} + +/** + 点击年份来查询柱形图,从年初到年尾的全部数据,没有网络时提醒无网络连接 + */ +- (void)ybPopupMenu:(YBPopupMenu *)ybPopupMenu didSelectedAtIndex:(NSInteger)index { + NSString *year = _selectArr[index]; + NSLog(@"这是当前的年份----%@",year); + NSDate *mydate=[NSDate date]; + NSString *currentYear = [MGDTimeTool dateToYear:mydate]; + if ([year isEqualToString:currentYear]) { + NSLog(@"%@-------%@",year,currentYear); + } + manager = [AFHTTPSessionManager manager]; + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *token = [user objectForKey:@"token"]; + AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer]; + responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObjectsFromSet:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", @"text/plain",@"application/atom+xml",@"application/xml",nil]]; + [manager setResponseSerializer:responseSerializer]; + [manager.requestSerializer setValue:[NSString stringWithFormat:@"%@",token] forHTTPHeaderField:@"token"]; + NSString *currentDateStr = [year stringByAppendingString:@"-12-31 11:59:59"]; + NSString *lastDateStr = [year stringByAppendingFormat:@"-01-01 00:00:00"]; + NSDictionary *param = @{@"from_time":lastDateStr,@"to_time":currentDateStr}; + NSLog(@"%@",param); + [manager POST:SportListUrl parameters:param + success:^(NSURLSessionDataTask *task, id responseObject) { + [self.tmpArray removeAllObjects]; + NSDictionary *dict = [[NSDictionary alloc] init]; + dict = responseObject[@"data"]; + NSArray *record = [[NSArray alloc] init]; + record = dict[@"record_list"]; + for (NSDictionary *dic in record) { + self->_userDataModel = [MGDSportData SportDataWithDict:dic]; + [self->_tmpArray addObject:self.userDataModel]; + } + self->_tmpArray = [[self->_tmpArray reverseObjectEnumerator] allObjects]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self makeListData:self->_tmpArray]; + NSLog(@"刷新年份数据"); + }); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSLog(@"%@",error); + [self hud:self->_hud setUpHud:@"无网络连接"]; + }]; + self.columnChartView.yearName = year; + [self.columnChartView reloadData]; +} + + +#pragma mark- 代理方法 +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + return screenHeigth * 0.117; +} + +#pragma mark- 数据源方法 +- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return _cellListArray.count; +} + + +//转到杨诚的界面 +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + MGDSportData *model = _cellListArray[indexPath.row]; + MGDCellDataViewController *detailDataVC = [MGDDataTool DataToMGDCellDataVC:model]; + [self.navigationController pushViewController:detailDataVC animated:YES]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + //创建单元格(用复用池) + MGDSportTableViewCell* cell = nil; + cell.backgroundColor = [UIColor clearColor]; + cell = [tableView dequeueReusableCellWithIdentifier:ID1]; + if (_recordArray != nil && ![_recordArray isKindOfClass:[NSNull class]] && _recordArray.count != 0) { + MGDSportData *model = _cellListArray[indexPath.row]; + NSString *date = [MGDTimeTool getDateStringWithTimeStr:[NSString stringWithFormat:@"%@", model.FinishDate]]; + //获取当前时间来判断,如果是昨天或者今天的数据则显示为文字,否则显示为日期 + NSDate *currentDate = [NSDate date]; + NSString *currentDateStr = [[MGDTimeTool dateToString:currentDate] substringWithRange:NSMakeRange(5,5)]; + NSString *lastDay = [[MGDTimeTool yesterdayTostring:currentDate] substringWithRange:NSMakeRange(5, 5)]; + if ([date isEqualToString:currentDateStr]) { + cell.dayLab.text = @"今天"; + }else if ([date isEqualToString:lastDay]) { + cell.dayLab.text = @"昨天"; + }else { + cell.dayLab.text = date; + } + //展示cell上的数据 + NSString *time = [MGDTimeTool getTimeStringWithTimeStr:[NSString stringWithFormat:@"%@",model.FinishDate]]; + cell.timeLab.text = time; + cell.kmLab.text = [NSString stringWithFormat:@"%.2f",[model.distance floatValue]/1000]; + cell.minLab.text = [NSString stringWithFormat:@"%@",[MGDTimeTool getMMSSFromSS:[NSString stringWithFormat:@"%@", model.totalTime]]]; + cell.calLab.text = [NSString stringWithFormat:@"%d",[model.cal intValue]]; + return cell; + }else { + return cell; + } +} + +/** + 通过缓存获取柱形图的数据 + */ +- (void)getCache:(void(^)(NSMutableArray *recordList))result { + [self.chartArr removeAllObjects]; + [self makeListData:self->_recordArray]; + //通过block把值传出来 + dispatch_async(dispatch_get_main_queue(), ^{ + result(self->_recordArray); + }); +} + +/** + 用于展示柱形图的柱子,从月份获取到天,累加每一天的数据,没有数据设置为0 + */ +- (void)makeListData:(NSArray *)array { + NSInteger count = 12; + NSMutableArray *dataArr = [NSMutableArray array]; + for (NSInteger i = 0; i < count; i++) { + [dataArr addObject:[NSMutableDictionary dictionary]]; + } + for (MGDSportData *model in array) { + NSString *date = [MGDTimeTool getDateStringWithTimeStr:[NSString stringWithFormat:@"%@", model.FinishDate]]; + //以-符号来分割字符串 + NSArray *arr = [date componentsSeparatedByString:@"-"]; + if (arr.count > 1) { + NSInteger count = [arr.firstObject integerValue] - 1; + NSMutableDictionary *monthDic = dataArr[count]; + + NSString* dayNum = arr[1]; + NSString* runNum = monthDic[dayNum]; + + //累加每一天的走路 + if (runNum) { + CGFloat runTemp = [NSString stringWithFormat:@"%.2f",[model.distance floatValue]].floatValue/1000; + CGFloat all = runTemp + runNum.floatValue; + monthDic[dayNum] = [NSString stringWithFormat:@"%.2f", all]; + + }else { + monthDic[dayNum] = [NSString stringWithFormat:@"%.2f",[model.distance floatValue]/1000]; + } + } + } + [self.chartArr removeAllObjects]; + [self.chartArr addObjectsFromArray:dataArr]; + [self.columnChartView reloadData]; +} + +//判断当前网络连接的情况,如果此时有网络,且是第一次打开该程序,则自动刷新,否则不刷新 +- (void)checkNetWorkTrans { + AFNetworkReachabilityManager *managerAF = [AFNetworkReachabilityManager sharedManager]; + [managerAF setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { + switch (status) { + case AFNetworkReachabilityStatusUnknown: + self->_isConnected = true; + if (self->_isConnected) { + [self loadnewData]; + } + break; + case AFNetworkReachabilityStatusReachableViaWiFi: + self->_isConnected = true; + if (self->_isConnected) { + [self loadnewData]; + } + NSLog(@"使用WIFI"); + break; + case AFNetworkReachabilityStatusReachableViaWWAN: + self->_isConnected = true; + if (self->_isConnected) { + [self loadnewData]; + } + break; + case AFNetworkReachabilityStatusNotReachable: + self->_isConnected = false; + NSLog(@"没有连接网络"); + break; + } + }]; + [managerAF startMonitoring]; +} + +- (void) hud:(MBProgressHUD *)hud setUpHud:(NSString *)remindLabel { + hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + hud.animationType = MBProgressHUDAnimationZoomOut; + hud.mode = MBProgressHUDModeText; + hud.label.text = remindLabel; + CGFloat margin = 0; + if (kIs_iPhoneX) { + margin = 361+20 - self.view.center.y; + }else { + margin = 361+20 - self.view.center.y; + } + [hud setOffset:CGPointMake(0, margin)]; + [hud hideAnimated:YES afterDelay:1.2]; +} + +@end diff --git a/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenu.h b/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenu.h new file mode 100755 index 0000000..def0963 --- /dev/null +++ b/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenu.h @@ -0,0 +1,266 @@ +// +// YBPopupMenu.h +// YBPopupMenu +// +// Created by lyb on 2017/5/10. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import +#import "YBPopupMenuPath.h" + +// 过期提醒 +#define YBDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead) + +typedef NS_ENUM(NSInteger , YBPopupMenuType) { + YBPopupMenuTypeDefault = 0, + YBPopupMenuTypeDark +}; + +/** + 箭头方向优先级 + + 当控件超出屏幕时会自动调整成反方向 + */ +typedef NS_ENUM(NSInteger , YBPopupMenuPriorityDirection) { + YBPopupMenuPriorityDirectionTop = 0, //Default + YBPopupMenuPriorityDirectionBottom, + YBPopupMenuPriorityDirectionLeft, + YBPopupMenuPriorityDirectionRight, + YBPopupMenuPriorityDirectionNone //不自动调整 +}; + +@class YBPopupMenu; +@protocol YBPopupMenuDelegate + +@optional + +///////旧版本///////// +/** + 点击事件回调 + */ +- (void)ybPopupMenuDidSelectedAtIndex:(NSInteger)index ybPopupMenu:(YBPopupMenu *)ybPopupMenu YBDeprecated("请替用 ybPopupMenu: didSelectedAtIndex: 方法"); +- (void)ybPopupMenuBeganDismiss; +- (void)ybPopupMenuDidDismiss; +- (void)ybPopupMenuBeganShow; +- (void)ybPopupMenuDidShow; + +///////新版本///////// +- (void)ybPopupMenu:(YBPopupMenu *)ybPopupMenu didSelectedAtIndex:(NSInteger)index; + +/** + 自定义cell + + 可以自定义cell,设置后会忽略 fontSize textColor backColor type 属性 + cell 的高度是根据 itemHeight 的,直接设置无效 + 建议cell 背景色设置为透明色,不然切的圆角显示不出来 + */ +- (UITableViewCell *)ybPopupMenu:(YBPopupMenu *)ybPopupMenu cellForRowAtIndex:(NSInteger)index; + +@end + +@interface YBPopupMenu : UIView + +/** + 标题数组 只读属性 + */ +@property (nonatomic, strong, readonly) NSArray * titles; + +/** + 图片数组 只读属性 + */ +@property (nonatomic, strong, readonly) NSArray * images; + +/** + tableView Default separatorStyle is UITableViewCellSeparatorStyleNone + */ +@property (nonatomic, strong) UITableView * tableView; + +/** + 文字颜色数组 只读属性 + */ +@property (nonatomic, copy) NSArray * textColors; + +/** + 圆角半径 Default is 5.0 + */ +@property (nonatomic, assign) CGFloat cornerRadius; + +/** + 自定义圆角 Default is UIRectCornerAllCorners + + 当自动调整方向时corner会自动转换至镜像方向 + */ +@property (nonatomic, assign) UIRectCorner rectCorner; + +/** + 是否显示阴影 Default is YES + */ +@property (nonatomic, assign , getter=isShadowShowing) BOOL isShowShadow; + +/** + 是否显示灰色覆盖层 Default is YES + */ +@property (nonatomic, assign) BOOL showMaskView; + +/** + 选择菜单项后消失 Default is YES + */ +@property (nonatomic, assign) BOOL dismissOnSelected; + +/** + 点击菜单外消失 Default is YES + */ +@property (nonatomic, assign) BOOL dismissOnTouchOutside; + +/** + 设置字体大小 自定义cell时忽略 Default is 15 + */ +@property (nonatomic, assign) CGFloat fontSize; + +/** + 设置字体颜色 自定义cell时忽略 Default is [UIColor blackColor] + */ +@property (nonatomic, strong) UIColor * textColor; + +/** + 设置偏移距离 (>= 0) Default is 0.0 + */ +@property (nonatomic, assign) CGFloat offset; + +/** + 边框宽度 Default is 0.0 + + 设置边框需 > 0 + */ +@property (nonatomic, assign) CGFloat borderWidth; + +/** + 边框颜色 Default is LightGrayColor + + borderWidth <= 0 无效 + */ +@property (nonatomic, strong) UIColor * borderColor; + +/** + 箭头宽度 Default is 15 + */ +@property (nonatomic, assign) CGFloat arrowWidth; + +/** + 箭头高度 Default is 10 + */ +@property (nonatomic, assign) CGFloat arrowHeight; + +/** + 箭头位置 Default is center + + 只有箭头优先级是YBPopupMenuPriorityDirectionLeft/YBPopupMenuPriorityDirectionRight/YBPopupMenuPriorityDirectionNone时需要设置 + */ +@property (nonatomic, assign) CGFloat arrowPosition; + +/** + 箭头方向 Default is YBPopupMenuArrowDirectionTop + */ +@property (nonatomic, assign) YBPopupMenuArrowDirection arrowDirection; + +/** + 箭头优先方向 Default is YBPopupMenuPriorityDirectionTop + + 当控件超出屏幕时会自动调整箭头位置 + */ +@property (nonatomic, assign) YBPopupMenuPriorityDirection priorityDirection; + +/** + 可见的最大行数 Default is 5; + */ +@property (nonatomic, assign) NSInteger maxVisibleCount; + +/** + menu背景色 自定义cell时忽略 Default is WhiteColor + */ +@property (nonatomic, strong) UIColor * backColor; + +/** + item的高度 Default is 44; + */ +@property (nonatomic, assign) CGFloat itemHeight; + +/** + popupMenu距离最近的Screen的距离 Default is 10 + */ +@property (nonatomic, assign) CGFloat minSpace; + +/** + 设置显示模式 自定义cell时忽略 Default is YBPopupMenuTypeDefault + */ +@property (nonatomic, assign) YBPopupMenuType type; + +/** + 代理 + */ +@property (nonatomic, weak) id delegate; + +/** + 在指定位置弹出 + + @param titles 标题数组 数组里是NSString/NSAttributedString + @param icons 图标数组 数组里是NSString/UIImage + @param itemWidth 菜单宽度 + @param delegate 代理 + */ ++ (YBPopupMenu *)showAtPoint:(CGPoint)point + titles:(NSArray *)titles + icons:(NSArray *)icons + menuWidth:(CGFloat)itemWidth + delegate:(id)delegate; + +/** + 在指定位置弹出(推荐方法) + + @param point 弹出的位置 + @param titles 标题数组 数组里是NSString/NSAttributedString + @param icons 图标数组 数组里是NSString/UIImage + @param itemWidth 菜单宽度 + @param otherSetting 其他设置 + */ ++ (YBPopupMenu *)showAtPoint:(CGPoint)point + titles:(NSArray *)titles + icons:(NSArray *)icons + menuWidth:(CGFloat)itemWidth + otherSettings:(void (^) (YBPopupMenu * popupMenu))otherSetting; + +/** + 依赖指定view弹出 + + @param titles 标题数组 数组里是NSString/NSAttributedString + @param icons 图标数组 数组里是NSString/UIImage + @param itemWidth 菜单宽度 + @param delegate 代理 + */ ++ (YBPopupMenu *)showRelyOnView:(UIView *)view + titles:(NSArray *)titles + icons:(NSArray *)icons + menuWidth:(CGFloat)itemWidth + delegate:(id)delegate; + +/** + 依赖指定view弹出(推荐方法) + + @param titles 标题数组 数组里是NSString/NSAttributedString + @param icons 图标数组 数组里是NSString/UIImage + @param itemWidth 菜单宽度 + @param otherSetting 其他设置 + */ ++ (YBPopupMenu *)showRelyOnView:(UIView *)view + titles:(NSArray *)titles + icons:(NSArray *)icons + menuWidth:(CGFloat)itemWidth + otherSettings:(void (^) (YBPopupMenu * popupMenu))otherSetting; + +/** + 消失 + */ +- (void)dismiss; + +@end diff --git a/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenu.m b/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenu.m new file mode 100755 index 0000000..6119627 --- /dev/null +++ b/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenu.m @@ -0,0 +1,770 @@ +// +// YBPopupMenu.m +// YBPopupMenu +// +// Created by lyb on 2017/5/10. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import "YBPopupMenu.h" +#import "YBPopupMenuPath.h" + +#define YBScreenWidth [UIScreen mainScreen].bounds.size.width +#define YBScreenHeight [UIScreen mainScreen].bounds.size.height +#define YBMainWindow [UIApplication sharedApplication].keyWindow +#define YB_SAFE_BLOCK(BlockName, ...) ({ !BlockName ? nil : BlockName(__VA_ARGS__); }) + +#pragma mark - ///////////// +#pragma mark - private cell + +@interface YBPopupMenuCell : UITableViewCell +@property (nonatomic, assign) BOOL isShowSeparator; +@property (nonatomic, strong) UIColor * separatorColor; +@end + +@implementation YBPopupMenuCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + _isShowSeparator = YES; + _separatorColor = [UIColor lightGrayColor]; + [self setNeedsDisplay]; + } + return self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGRect frame = self.textLabel.frame; + frame.size.width = self.bounds.size.width; + self.textLabel.frame = frame; +} + +- (void)setIsShowSeparator:(BOOL)isShowSeparator +{ + _isShowSeparator = isShowSeparator; + [self setNeedsDisplay]; +} + +- (void)setSeparatorColor:(UIColor *)separatorColor +{ + _separatorColor = separatorColor; + [self setNeedsDisplay]; +} + +- (void)drawRect:(CGRect)rect +{ + if (!_isShowSeparator) return; + UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, rect.size.height - 0.5, rect.size.width, 0.5)]; + [_separatorColor setFill]; + [bezierPath fillWithBlendMode:kCGBlendModeNormal alpha:1]; + [bezierPath closePath]; +} + +@end + + + +@interface YBPopupMenu () +< +UITableViewDelegate, +UITableViewDataSource +> + +@property (nonatomic, strong) UIView * menuBackView; +@property (nonatomic) CGRect relyRect; +@property (nonatomic, assign) CGFloat itemWidth; +@property (nonatomic) CGPoint point; +@property (nonatomic, assign) BOOL isCornerChanged; +@property (nonatomic, strong) UIColor * separatorColor; +@property (nonatomic, assign) BOOL isChangeDirection; +@end + +@implementation YBPopupMenu + +- (instancetype)init +{ + self = [super init]; + if (self) { + [self setDefaultSettings]; + } + return self; +} + +#pragma mark - publics ++ (YBPopupMenu *)showAtPoint:(CGPoint)point titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth delegate:(id)delegate +{ + YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init]; + popupMenu.point = point; + popupMenu.titles = titles; + popupMenu.images = icons; + popupMenu.itemWidth = itemWidth; + popupMenu.delegate = delegate; + [popupMenu show]; + return popupMenu; +} + ++ (YBPopupMenu *)showRelyOnView:(UIView *)view titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth delegate:(id)delegate +{ + CGRect absoluteRect = [view convertRect:view.bounds toView:YBMainWindow]; + CGPoint relyPoint = CGPointMake(absoluteRect.origin.x + absoluteRect.size.width / 2, absoluteRect.origin.y + absoluteRect.size.height); + YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init]; + popupMenu.point = relyPoint; + popupMenu.relyRect = absoluteRect; + popupMenu.titles = titles; + popupMenu.images = icons; + popupMenu.itemWidth = itemWidth; + popupMenu.delegate = delegate; + [popupMenu show]; + return popupMenu; +} + ++ (YBPopupMenu *)showAtPoint:(CGPoint)point titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth otherSettings:(void (^) (YBPopupMenu * popupMenu))otherSetting +{ + YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init]; + popupMenu.point = point; + popupMenu.titles = titles; + popupMenu.images = icons; + popupMenu.itemWidth = itemWidth; + YB_SAFE_BLOCK(otherSetting,popupMenu); + [popupMenu show]; + return popupMenu; +} + ++ (YBPopupMenu *)showRelyOnView:(UIView *)view titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth otherSettings:(void (^) (YBPopupMenu * popupMenu))otherSetting +{ + CGRect absoluteRect = [view convertRect:view.bounds toView:YBMainWindow]; + CGPoint relyPoint = CGPointMake(absoluteRect.origin.x + absoluteRect.size.width / 2, absoluteRect.origin.y + absoluteRect.size.height); + YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init]; + popupMenu.point = relyPoint; + popupMenu.relyRect = absoluteRect; + popupMenu.titles = titles; + popupMenu.images = icons; + popupMenu.itemWidth = itemWidth; + YB_SAFE_BLOCK(otherSetting,popupMenu); + [popupMenu show]; + return popupMenu; +} + +- (void)dismiss +{ + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuBeganDismiss)]) { + [self.delegate ybPopupMenuBeganDismiss]; + } + [UIView animateWithDuration: 0.25 animations:^{ + self.layer.affineTransform = CGAffineTransformMakeScale(0.1, 0.1); + self.alpha = 0; + self->_menuBackView.alpha = 0; + } completion:^(BOOL finished) { + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuDidDismiss)]) { + [self.delegate ybPopupMenuDidDismiss]; + } + self.delegate = nil; + [self removeFromSuperview]; + [self->_menuBackView removeFromSuperview]; + }]; +} + +#pragma mark tableViewDelegate & dataSource +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return _titles.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell * tableViewCell = nil; + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenu:cellForRowAtIndex:)]) { + tableViewCell = [self.delegate ybPopupMenu:self cellForRowAtIndex:indexPath.row]; + } + + if (tableViewCell) { + return tableViewCell; + } + + static NSString * identifier = @"ybPopupMenu"; + YBPopupMenuCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; + if (!cell) { + cell = [[YBPopupMenuCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier]; + cell.textLabel.numberOfLines = 0; + } + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.backgroundColor = [UIColor clearColor]; + if (_textColors.count > indexPath.row) { + cell.textLabel.textColor = _textColors[indexPath.row]; + + }else { + cell.textLabel.textColor = _textColor; + } + cell.textLabel.font = [UIFont systemFontOfSize:_fontSize]; + if ([_titles[indexPath.row] isKindOfClass:[NSAttributedString class]]) { + cell.textLabel.attributedText = _titles[indexPath.row]; + }else if ([_titles[indexPath.row] isKindOfClass:[NSString class]]) { + cell.textLabel.text = _titles[indexPath.row]; + }else { + cell.textLabel.text = nil; + } + cell.separatorColor = _separatorColor; + if (_images.count >= indexPath.row + 1) { + if ([_images[indexPath.row] isKindOfClass:[NSString class]]) { + cell.imageView.image = [UIImage imageNamed:_images[indexPath.row]]; + }else if ([_images[indexPath.row] isKindOfClass:[UIImage class]]){ + cell.imageView.image = _images[indexPath.row]; + }else { + cell.imageView.image = nil; + } + }else { + cell.imageView.image = nil; + } + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return _itemHeight; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (_dismissOnSelected) [self dismiss]; + + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuDidSelectedAtIndex:ybPopupMenu:)]) { + +// [self.delegate ybPopupMenuDidSelectedAtIndex:indexPath.row ybPopupMenu:self]; + } + + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenu:didSelectedAtIndex:)]) { + [self.delegate ybPopupMenu:self didSelectedAtIndex:indexPath.row]; + } +} + +#pragma mark - scrollViewDelegate +- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView +{ + if ([[self getLastVisibleCell] isKindOfClass:[YBPopupMenuCell class]]) { + YBPopupMenuCell *cell = [self getLastVisibleCell]; + cell.isShowSeparator = YES; + } +} + +- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView +{ + if ([[self getLastVisibleCell] isKindOfClass:[YBPopupMenuCell class]]) { + YBPopupMenuCell *cell = [self getLastVisibleCell]; + cell.isShowSeparator = NO; + } +} + +- (YBPopupMenuCell *)getLastVisibleCell +{ + NSArray *indexPaths = [self.tableView indexPathsForVisibleRows]; + indexPaths = [indexPaths sortedArrayUsingComparator:^NSComparisonResult(NSIndexPath * _Nonnull obj1, NSIndexPath * _Nonnull obj2) { + return obj1.row < obj2.row; + }]; + NSIndexPath *indexPath = indexPaths.firstObject; + return [self.tableView cellForRowAtIndexPath:indexPath]; +} + +#pragma mark - privates +- (void)show +{ + [YBMainWindow addSubview:_menuBackView]; + [YBMainWindow addSubview:self]; + if ([[self getLastVisibleCell] isKindOfClass:[YBPopupMenuCell class]]) { + YBPopupMenuCell *cell = [self getLastVisibleCell]; + cell.isShowSeparator = NO; + } + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuBeganShow)]) { + [self.delegate ybPopupMenuBeganShow]; + } + self.layer.affineTransform = CGAffineTransformMakeScale(0.1, 0.1); + [UIView animateWithDuration: 0.25 animations:^{ + self.layer.affineTransform = CGAffineTransformMakeScale(1.0, 1.0); + self.alpha = 1; + self->_menuBackView.alpha = 1; + } completion:^(BOOL finished) { + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuDidShow)]) { + [self.delegate ybPopupMenuDidShow]; + } + }]; +} + +- (void)setDefaultSettings +{ + _cornerRadius = 5.0; + _rectCorner = UIRectCornerAllCorners; + self.isShowShadow = YES; + _dismissOnSelected = YES; + _dismissOnTouchOutside = YES; + _fontSize = 15; + _offset = 0.0; + _relyRect = CGRectZero; + _point = CGPointZero; + _borderWidth = 0.0; + _borderColor = [UIColor lightGrayColor]; + _arrowWidth = 15.0; + _arrowHeight = 10.0; + if (@available(iOS 11.0, *)) { + self.backColor = MGDColor1; + self.textColor = MGDTextColor1; + } else { + // Fallback on earlier versions + } + _type = YBPopupMenuTypeDefault; + _arrowDirection = YBPopupMenuArrowDirectionTop; + _priorityDirection = YBPopupMenuPriorityDirectionTop; + _minSpace = 10.0; + _maxVisibleCount = 5; + _itemHeight = 44; + _isCornerChanged = NO; + _showMaskView = YES; + _menuBackView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, YBScreenWidth, YBScreenHeight)]; + _menuBackView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.1]; + _menuBackView.alpha = 0; + UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(touchOutSide)]; + [_menuBackView addGestureRecognizer: tap]; + self.alpha = 0; + self.backgroundColor = [UIColor clearColor]; + [self addSubview:self.tableView]; +} + +- (UITableView *)tableView +{ + if (!_tableView) { + _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; + _tableView.backgroundColor = [UIColor clearColor]; + _tableView.tableFooterView = [UIView new]; + _tableView.delegate = self; + _tableView.dataSource = self; + _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + } + return _tableView; +} + +- (void)touchOutSide +{ + if (_dismissOnTouchOutside) { + [self dismiss]; + } +} + +- (void)setIsShowShadow:(BOOL)isShowShadow +{ + _isShowShadow = isShowShadow; + self.layer.shadowOpacity = isShowShadow ? 0.5 : 0; + self.layer.shadowOffset = CGSizeMake(0, 0); + self.layer.shadowRadius = isShowShadow ? 2.0 : 0; +} + +- (void)setShowMaskView:(BOOL)showMaskView +{ + _showMaskView = showMaskView; + _menuBackView.backgroundColor = showMaskView ? [[UIColor blackColor] colorWithAlphaComponent:0.1] : [UIColor clearColor]; +} + +- (void)setType:(YBPopupMenuType)type +{ + _type = type; + switch (type) { + case YBPopupMenuTypeDark: + { + _textColor = [UIColor lightGrayColor]; + _backColor = [UIColor colorWithRed:0.25 green:0.27 blue:0.29 alpha:1]; + _separatorColor = [UIColor lightGrayColor]; + } + break; + + default: + { + _textColor = [UIColor blackColor]; + _backColor = [UIColor whiteColor]; + _separatorColor = [UIColor lightGrayColor]; + } + break; + } + [self updateUI]; +} + +- (void)setFontSize:(CGFloat)fontSize +{ + _fontSize = fontSize; + [self.tableView reloadData]; +} + +- (void)setTextColor:(UIColor *)textColor +{ + _textColor = textColor; + [self.tableView reloadData]; +} + +- (void)setPoint:(CGPoint)point +{ + _point = point; + [self updateUI]; +} + +- (void)setItemWidth:(CGFloat)itemWidth +{ + _itemWidth = itemWidth; + [self updateUI]; +} + +- (void)setItemHeight:(CGFloat)itemHeight +{ + _itemHeight = itemHeight; + [self updateUI]; +} + +- (void)setBorderWidth:(CGFloat)borderWidth +{ + _borderWidth = borderWidth; + [self updateUI]; +} + +- (void)setBorderColor:(UIColor *)borderColor +{ + _borderColor = borderColor; + [self updateUI]; +} + +- (void)setArrowPosition:(CGFloat)arrowPosition +{ + _arrowPosition = arrowPosition; + [self updateUI]; +} + +- (void)setArrowWidth:(CGFloat)arrowWidth +{ + _arrowWidth = arrowWidth; + [self updateUI]; +} + +- (void)setArrowHeight:(CGFloat)arrowHeight +{ + _arrowHeight = arrowHeight; + [self updateUI]; +} + +- (void)setArrowDirection:(YBPopupMenuArrowDirection)arrowDirection +{ + _arrowDirection = arrowDirection; + [self updateUI]; +} + +- (void)setMaxVisibleCount:(NSInteger)maxVisibleCount +{ + _maxVisibleCount = maxVisibleCount; + [self updateUI]; +} + +- (void)setBackColor:(UIColor *)backColor +{ + _backColor = backColor; + [self updateUI]; +} + +- (void)setTitles:(NSArray *)titles +{ + _titles = titles; + [self updateUI]; +} + +- (void)setImages:(NSArray *)images +{ + _images = images; + [self updateUI]; +} + +- (void)setPriorityDirection:(YBPopupMenuPriorityDirection)priorityDirection +{ + _priorityDirection = priorityDirection; + [self updateUI]; +} + +- (void)setRectCorner:(UIRectCorner)rectCorner +{ + _rectCorner = rectCorner; + [self updateUI]; +} + +- (void)setCornerRadius:(CGFloat)cornerRadius +{ + _cornerRadius = cornerRadius; + [self updateUI]; +} + +- (void)setOffset:(CGFloat)offset +{ + _offset = offset; + [self updateUI]; +} + +- (void)updateUI +{ + CGFloat height; + if (_titles.count > _maxVisibleCount) { + height = _itemHeight * _maxVisibleCount + _borderWidth * 2; + self.tableView.bounces = YES; + }else { + height = _itemHeight * _titles.count + _borderWidth * 2; + self.tableView.bounces = NO; + } + _isChangeDirection = NO; + if (_priorityDirection == YBPopupMenuPriorityDirectionTop) { + if (_point.y + height + _arrowHeight > YBScreenHeight - _minSpace) { + _arrowDirection = YBPopupMenuArrowDirectionBottom; + _isChangeDirection = YES; + }else { + _arrowDirection = YBPopupMenuArrowDirectionTop; + _isChangeDirection = NO; + } + }else if (_priorityDirection == YBPopupMenuPriorityDirectionBottom) { + if (_point.y - height - _arrowHeight < _minSpace) { + _arrowDirection = YBPopupMenuArrowDirectionTop; + _isChangeDirection = YES; + }else { + _arrowDirection = YBPopupMenuArrowDirectionBottom; + _isChangeDirection = NO; + } + }else if (_priorityDirection == YBPopupMenuPriorityDirectionLeft) { + if (_point.x + _itemWidth + _arrowHeight > YBScreenWidth - _minSpace) { + _arrowDirection = YBPopupMenuArrowDirectionRight; + _isChangeDirection = YES; + }else { + _arrowDirection = YBPopupMenuArrowDirectionLeft; + _isChangeDirection = NO; + } + }else if (_priorityDirection == YBPopupMenuPriorityDirectionRight) { + if (_point.x - _itemWidth - _arrowHeight < _minSpace) { + _arrowDirection = YBPopupMenuArrowDirectionLeft; + _isChangeDirection = YES; + }else { + _arrowDirection = YBPopupMenuArrowDirectionRight; + _isChangeDirection = NO; + } + } + [self setArrowPosition]; + [self setRelyRect]; + if (_arrowDirection == YBPopupMenuArrowDirectionTop) { + CGFloat y = _isChangeDirection ? _point.y : _point.y; + if (_arrowPosition > _itemWidth / 2) { + self.frame = CGRectMake(YBScreenWidth - _minSpace - _itemWidth, y, _itemWidth, height + _arrowHeight); + }else if (_arrowPosition < _itemWidth / 2) { + self.frame = CGRectMake(_minSpace, y, _itemWidth, height + _arrowHeight); + }else { + self.frame = CGRectMake(_point.x - _itemWidth / 2, y, _itemWidth, height + _arrowHeight); + } + }else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) { + CGFloat y = _isChangeDirection ? _point.y - _arrowHeight - height : _point.y - _arrowHeight - height; + if (_arrowPosition > _itemWidth / 2) { + self.frame = CGRectMake(YBScreenWidth - _minSpace - _itemWidth, y, _itemWidth, height + _arrowHeight); + }else if (_arrowPosition < _itemWidth / 2) { + self.frame = CGRectMake(_minSpace, y, _itemWidth, height + _arrowHeight); + }else { + self.frame = CGRectMake(_point.x - _itemWidth / 2, y, _itemWidth, height + _arrowHeight); + } + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) { + CGFloat x = _isChangeDirection ? _point.x : _point.x; + if (_arrowPosition < _itemHeight / 2) { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + }else if (_arrowPosition > _itemHeight / 2) { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + }else { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + } + }else if (_arrowDirection == YBPopupMenuArrowDirectionRight) { + CGFloat x = _isChangeDirection ? _point.x - _itemWidth - _arrowHeight : _point.x - _itemWidth - _arrowHeight; + if (_arrowPosition < _itemHeight / 2) { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + }else if (_arrowPosition > _itemHeight / 2) { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + }else { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + } + }else if (_arrowDirection == YBPopupMenuArrowDirectionNone) { + + } + + if (_isChangeDirection) { + [self changeRectCorner]; + } + [self setAnchorPoint]; + [self setOffset]; + [self.tableView reloadData]; + [self setNeedsDisplay]; +} + +- (void)setRelyRect +{ + if (CGRectEqualToRect(_relyRect, CGRectZero)) { + return; + } + if (_arrowDirection == YBPopupMenuArrowDirectionTop) { + _point.y = _relyRect.size.height + _relyRect.origin.y; + }else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) { + _point.y = _relyRect.origin.y; + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) { + _point = CGPointMake(_relyRect.origin.x + _relyRect.size.width, _relyRect.origin.y + _relyRect.size.height / 2); + }else { + _point = CGPointMake(_relyRect.origin.x, _relyRect.origin.y + _relyRect.size.height / 2); + } +} + + +- (void)setFrame:(CGRect)frame +{ + [super setFrame:frame]; + if (_arrowDirection == YBPopupMenuArrowDirectionTop) { + self.tableView.frame = CGRectMake(_borderWidth, _borderWidth + _arrowHeight, frame.size.width - _borderWidth * 2, frame.size.height - _arrowHeight); + }else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) { + self.tableView.frame = CGRectMake(_borderWidth, _borderWidth, frame.size.width - _borderWidth * 2, frame.size.height - _arrowHeight); + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) { + self.tableView.frame = CGRectMake(_borderWidth + _arrowHeight, _borderWidth , frame.size.width - _borderWidth * 2 - _arrowHeight, frame.size.height); + }else if (_arrowDirection == YBPopupMenuArrowDirectionRight) { + self.tableView.frame = CGRectMake(_borderWidth , _borderWidth , frame.size.width - _borderWidth * 2 - _arrowHeight, frame.size.height); + } +} + +- (void)changeRectCorner +{ + if (_isCornerChanged || _rectCorner == UIRectCornerAllCorners) { + return; + } + BOOL haveTopLeftCorner = NO, haveTopRightCorner = NO, haveBottomLeftCorner = NO, haveBottomRightCorner = NO; + if (_rectCorner & UIRectCornerTopLeft) { + haveTopLeftCorner = YES; + } + if (_rectCorner & UIRectCornerTopRight) { + haveTopRightCorner = YES; + } + if (_rectCorner & UIRectCornerBottomLeft) { + haveBottomLeftCorner = YES; + } + if (_rectCorner & UIRectCornerBottomRight) { + haveBottomRightCorner = YES; + } + + if (_arrowDirection == YBPopupMenuArrowDirectionTop || _arrowDirection == YBPopupMenuArrowDirectionBottom) { + + if (haveTopLeftCorner) { + _rectCorner = _rectCorner | UIRectCornerBottomLeft; + }else { + _rectCorner = _rectCorner & (~UIRectCornerBottomLeft); + } + if (haveTopRightCorner) { + _rectCorner = _rectCorner | UIRectCornerBottomRight; + }else { + _rectCorner = _rectCorner & (~UIRectCornerBottomRight); + } + if (haveBottomLeftCorner) { + _rectCorner = _rectCorner | UIRectCornerTopLeft; + }else { + _rectCorner = _rectCorner & (~UIRectCornerTopLeft); + } + if (haveBottomRightCorner) { + _rectCorner = _rectCorner | UIRectCornerTopRight; + }else { + _rectCorner = _rectCorner & (~UIRectCornerTopRight); + } + + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft || _arrowDirection == YBPopupMenuArrowDirectionRight) { + if (haveTopLeftCorner) { + _rectCorner = _rectCorner | UIRectCornerTopRight; + }else { + _rectCorner = _rectCorner & (~UIRectCornerTopRight); + } + if (haveTopRightCorner) { + _rectCorner = _rectCorner | UIRectCornerTopLeft; + }else { + _rectCorner = _rectCorner & (~UIRectCornerTopLeft); + } + if (haveBottomLeftCorner) { + _rectCorner = _rectCorner | UIRectCornerBottomRight; + }else { + _rectCorner = _rectCorner & (~UIRectCornerBottomRight); + } + if (haveBottomRightCorner) { + _rectCorner = _rectCorner | UIRectCornerBottomLeft; + }else { + _rectCorner = _rectCorner & (~UIRectCornerBottomLeft); + } + } + + _isCornerChanged = YES; +} + +- (void)setOffset +{ + if (_itemWidth == 0) return; + + CGRect originRect = self.frame; + + if (_arrowDirection == YBPopupMenuArrowDirectionTop) { + originRect.origin.y += _offset; + }else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) { + originRect.origin.y -= _offset; + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) { + originRect.origin.x += _offset; + }else if (_arrowDirection == YBPopupMenuArrowDirectionRight) { + originRect.origin.x -= _offset; + } + self.frame = originRect; +} + +- (void)setAnchorPoint +{ + if (_itemWidth == 0) return; + + CGPoint point = CGPointMake(0.5, 0.5); + if (_arrowDirection == YBPopupMenuArrowDirectionTop) { + point = CGPointMake(_arrowPosition / _itemWidth, 0); + }else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) { + point = CGPointMake(_arrowPosition / _itemWidth, 1); + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) { + point = CGPointMake(0, (_itemHeight - _arrowPosition) / _itemHeight); + }else if (_arrowDirection == YBPopupMenuArrowDirectionRight) { + point = CGPointMake(1, (_itemHeight - _arrowPosition) / _itemHeight); + } + CGRect originRect = self.frame; + self.layer.anchorPoint = point; + self.frame = originRect; +} + +- (void)setArrowPosition +{ + if (_priorityDirection == YBPopupMenuPriorityDirectionNone) { + return; + } + if (_arrowDirection == YBPopupMenuArrowDirectionTop || _arrowDirection == YBPopupMenuArrowDirectionBottom) { + if (_point.x + _itemWidth / 2 > YBScreenWidth - _minSpace) { + _arrowPosition = _itemWidth - (YBScreenWidth - _minSpace - _point.x); + }else if (_point.x < _itemWidth / 2 + _minSpace) { + _arrowPosition = _point.x - _minSpace; + }else { + _arrowPosition = _itemWidth / 2; + } + + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft || _arrowDirection == YBPopupMenuArrowDirectionRight) { +// if (_point.y + _itemHeight / 2 > YBScreenHeight - _minSpace) { +// _arrowPosition = _itemHeight - (YBScreenHeight - _minSpace - _point.y); +// }else if (_point.y < _itemHeight / 2 + _minSpace) { +// _arrowPosition = _point.y - _minSpace; +// }else { +// _arrowPosition = _itemHeight / 2; +// } + } +} + +- (void)drawRect:(CGRect)rect +{ + UIBezierPath *bezierPath = [YBPopupMenuPath yb_bezierPathWithRect:rect rectCorner:_rectCorner cornerRadius:_cornerRadius borderWidth:_borderWidth borderColor:_borderColor backgroundColor:_backColor arrowWidth:_arrowWidth arrowHeight:_arrowHeight arrowPosition:_arrowPosition arrowDirection:_arrowDirection]; + [bezierPath fill]; + [bezierPath stroke]; +} + +@end diff --git a/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenuPath.h b/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenuPath.h new file mode 100755 index 0000000..314a803 --- /dev/null +++ b/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenuPath.h @@ -0,0 +1,39 @@ +// +// YBPopupMenuPath.h +// YBPopupMenu +// +// Created by lyb on 2017/5/9. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import + +typedef NS_ENUM(NSInteger, YBPopupMenuArrowDirection) { + YBPopupMenuArrowDirectionTop = 0, //箭头朝上 + YBPopupMenuArrowDirectionBottom, //箭头朝下 + YBPopupMenuArrowDirectionLeft, //箭头朝左 + YBPopupMenuArrowDirectionRight, //箭头朝右 + YBPopupMenuArrowDirectionNone //没有箭头 +}; + +@interface YBPopupMenuPath : NSObject + ++ (CAShapeLayer *)yb_maskLayerWithRect:(CGRect)rect + rectCorner:(UIRectCorner)rectCorner + cornerRadius:(CGFloat)cornerRadius + arrowWidth:(CGFloat)arrowWidth + arrowHeight:(CGFloat)arrowHeight + arrowPosition:(CGFloat)arrowPosition + arrowDirection:(YBPopupMenuArrowDirection)arrowDirection; + ++ (UIBezierPath *)yb_bezierPathWithRect:(CGRect)rect + rectCorner:(UIRectCorner)rectCorner + cornerRadius:(CGFloat)cornerRadius + borderWidth:(CGFloat)borderWidth + borderColor:(UIColor *)borderColor + backgroundColor:(UIColor *)backgroundColor + arrowWidth:(CGFloat)arrowWidth + arrowHeight:(CGFloat)arrowHeight + arrowPosition:(CGFloat)arrowPosition + arrowDirection:(YBPopupMenuArrowDirection)arrowDirection; +@end diff --git a/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenuPath.m b/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenuPath.m new file mode 100755 index 0000000..e577f2a --- /dev/null +++ b/MRMobileRun/MRMineView/YBPopupMenu/YBPopupMenuPath.m @@ -0,0 +1,172 @@ +// +// YBPopupMenuPath.m +// YBPopupMenu +// +// Created by lyb on 2017/5/9. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import "YBPopupMenuPath.h" +#import "YBRectConst.h" + +@implementation YBPopupMenuPath + ++ (CAShapeLayer *)yb_maskLayerWithRect:(CGRect)rect + rectCorner:(UIRectCorner)rectCorner + cornerRadius:(CGFloat)cornerRadius + arrowWidth:(CGFloat)arrowWidth + arrowHeight:(CGFloat)arrowHeight + arrowPosition:(CGFloat)arrowPosition + arrowDirection:(YBPopupMenuArrowDirection)arrowDirection +{ + CAShapeLayer *shapeLayer = [CAShapeLayer layer]; + shapeLayer.path = [self yb_bezierPathWithRect:rect rectCorner:rectCorner cornerRadius:cornerRadius borderWidth:0 borderColor:nil backgroundColor:nil arrowWidth:arrowWidth arrowHeight:arrowHeight arrowPosition:arrowPosition arrowDirection:arrowDirection].CGPath; + return shapeLayer; +} + + ++ (UIBezierPath *)yb_bezierPathWithRect:(CGRect)rect + rectCorner:(UIRectCorner)rectCorner + cornerRadius:(CGFloat)cornerRadius + borderWidth:(CGFloat)borderWidth + borderColor:(UIColor *)borderColor + backgroundColor:(UIColor *)backgroundColor + arrowWidth:(CGFloat)arrowWidth + arrowHeight:(CGFloat)arrowHeight + arrowPosition:(CGFloat)arrowPosition + arrowDirection:(YBPopupMenuArrowDirection)arrowDirection +{ + UIBezierPath *bezierPath = [UIBezierPath bezierPath]; + if (borderColor) { + [borderColor setStroke]; + } + if (backgroundColor) { + [backgroundColor setFill]; + } + bezierPath.lineWidth = borderWidth; + rect = CGRectMake(borderWidth / 2, borderWidth / 2, YBRectWidth(rect) - borderWidth, YBRectHeight(rect) - borderWidth); + CGFloat topRightRadius = 0,topLeftRadius = 0,bottomRightRadius = 0,bottomLeftRadius = 0; + CGPoint topRightArcCenter,topLeftArcCenter,bottomRightArcCenter,bottomLeftArcCenter; + + if (rectCorner & UIRectCornerTopLeft) { + topLeftRadius = cornerRadius; + } + if (rectCorner & UIRectCornerTopRight) { + topRightRadius = cornerRadius; + } + if (rectCorner & UIRectCornerBottomLeft) { + bottomLeftRadius = cornerRadius; + } + if (rectCorner & UIRectCornerBottomRight) { + bottomRightRadius = cornerRadius; + } + + if (arrowDirection == YBPopupMenuArrowDirectionTop) { + topLeftArcCenter = CGPointMake(topLeftRadius + YBRectX(rect), arrowHeight + topLeftRadius + YBRectX(rect)); + topRightArcCenter = CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect), arrowHeight + topRightRadius + YBRectX(rect)); + bottomLeftArcCenter = CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) - bottomLeftRadius + YBRectX(rect)); + bottomRightArcCenter = CGPointMake(YBRectWidth(rect) - bottomRightRadius + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius + YBRectX(rect)); + if (arrowPosition < topLeftRadius + arrowWidth / 2) { + arrowPosition = topLeftRadius + arrowWidth / 2; + }else if (arrowPosition > YBRectWidth(rect) - topRightRadius - arrowWidth / 2) { + arrowPosition = YBRectWidth(rect) - topRightRadius - arrowWidth / 2; + } + [bezierPath moveToPoint:CGPointMake(arrowPosition - arrowWidth / 2, arrowHeight + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(arrowPosition, YBRectTop(rect) + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(arrowPosition + arrowWidth / 2, arrowHeight + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - topRightRadius, arrowHeight + YBRectX(rect))]; + [bezierPath addArcWithCenter:topRightArcCenter radius:topRightRadius startAngle:M_PI * 3 / 2 endAngle:2 * M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius - YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomRightArcCenter radius:bottomRightRadius startAngle:0 endAngle:M_PI_2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) + YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomLeftArcCenter radius:bottomLeftRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectX(rect), arrowHeight + topLeftRadius + YBRectX(rect))]; + [bezierPath addArcWithCenter:topLeftArcCenter radius:topLeftRadius startAngle:M_PI endAngle:M_PI * 3 / 2 clockwise:YES]; + + }else if (arrowDirection == YBPopupMenuArrowDirectionBottom) { + topLeftArcCenter = CGPointMake(topLeftRadius + YBRectX(rect),topLeftRadius + YBRectX(rect)); + topRightArcCenter = CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect), topRightRadius + YBRectX(rect)); + bottomLeftArcCenter = CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) - bottomLeftRadius + YBRectX(rect) - arrowHeight); + bottomRightArcCenter = CGPointMake(YBRectWidth(rect) - bottomRightRadius + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius + YBRectX(rect) - arrowHeight); + if (arrowPosition < bottomLeftRadius + arrowWidth / 2) { + arrowPosition = bottomLeftRadius + arrowWidth / 2; + }else if (arrowPosition > YBRectWidth(rect) - bottomRightRadius - arrowWidth / 2) { + arrowPosition = YBRectWidth(rect) - bottomRightRadius - arrowWidth / 2; + } + [bezierPath moveToPoint:CGPointMake(arrowPosition + arrowWidth / 2, YBRectHeight(rect) - arrowHeight + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(arrowPosition, YBRectHeight(rect) + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(arrowPosition - arrowWidth / 2, YBRectHeight(rect) - arrowHeight + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) - arrowHeight + YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomLeftArcCenter radius:bottomLeftRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectX(rect), topLeftRadius + YBRectX(rect))]; + [bezierPath addArcWithCenter:topLeftArcCenter radius:topLeftRadius startAngle:M_PI endAngle:M_PI * 3 / 2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect), YBRectX(rect))]; + [bezierPath addArcWithCenter:topRightArcCenter radius:topRightRadius startAngle:M_PI * 3 / 2 endAngle:2 * M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius - YBRectX(rect) - arrowHeight)]; + [bezierPath addArcWithCenter:bottomRightArcCenter radius:bottomRightRadius startAngle:0 endAngle:M_PI_2 clockwise:YES]; + + }else if (arrowDirection == YBPopupMenuArrowDirectionLeft) { + topLeftArcCenter = CGPointMake(topLeftRadius + YBRectX(rect) + arrowHeight,topLeftRadius + YBRectX(rect)); + topRightArcCenter = CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect), topRightRadius + YBRectX(rect)); + bottomLeftArcCenter = CGPointMake(bottomLeftRadius + YBRectX(rect) + arrowHeight, YBRectHeight(rect) - bottomLeftRadius + YBRectX(rect)); + bottomRightArcCenter = CGPointMake(YBRectWidth(rect) - bottomRightRadius + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius + YBRectX(rect)); + if (arrowPosition < topLeftRadius + arrowWidth / 2) { + arrowPosition = topLeftRadius + arrowWidth / 2; + }else if (arrowPosition > YBRectHeight(rect) - bottomLeftRadius - arrowWidth / 2) { + arrowPosition = YBRectHeight(rect) - bottomLeftRadius - arrowWidth / 2; + } + [bezierPath moveToPoint:CGPointMake(arrowHeight + YBRectX(rect), arrowPosition + arrowWidth / 2)]; + [bezierPath addLineToPoint:CGPointMake(YBRectX(rect), arrowPosition)]; + [bezierPath addLineToPoint:CGPointMake(arrowHeight + YBRectX(rect), arrowPosition - arrowWidth / 2)]; + [bezierPath addLineToPoint:CGPointMake(arrowHeight + YBRectX(rect), topLeftRadius + YBRectX(rect))]; + [bezierPath addArcWithCenter:topLeftArcCenter radius:topLeftRadius startAngle:M_PI endAngle:M_PI * 3 / 2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - topRightRadius, YBRectX(rect))]; + [bezierPath addArcWithCenter:topRightArcCenter radius:topRightRadius startAngle:M_PI * 3 / 2 endAngle:2 * M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius - YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomRightArcCenter radius:bottomRightRadius startAngle:0 endAngle:M_PI_2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(arrowHeight + bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) + YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomLeftArcCenter radius:bottomLeftRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES]; + + }else if (arrowDirection == YBPopupMenuArrowDirectionRight) { + topLeftArcCenter = CGPointMake(topLeftRadius + YBRectX(rect),topLeftRadius + YBRectX(rect)); + topRightArcCenter = CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect) - arrowHeight, topRightRadius + YBRectX(rect)); + bottomLeftArcCenter = CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) - bottomLeftRadius + YBRectX(rect)); + bottomRightArcCenter = CGPointMake(YBRectWidth(rect) - bottomRightRadius + YBRectX(rect) - arrowHeight, YBRectHeight(rect) - bottomRightRadius + YBRectX(rect)); + if (arrowPosition < topRightRadius + arrowWidth / 2) { + arrowPosition = topRightRadius + arrowWidth / 2; + }else if (arrowPosition > YBRectHeight(rect) - bottomRightRadius - arrowWidth / 2) { + arrowPosition = YBRectHeight(rect) - bottomRightRadius - arrowWidth / 2; + } + [bezierPath moveToPoint:CGPointMake(YBRectWidth(rect) - arrowHeight + YBRectX(rect), arrowPosition - arrowWidth / 2)]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) + YBRectX(rect), arrowPosition)]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - arrowHeight + YBRectX(rect), arrowPosition + arrowWidth / 2)]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - arrowHeight + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius - YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomRightArcCenter radius:bottomRightRadius startAngle:0 endAngle:M_PI_2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) + YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomLeftArcCenter radius:bottomLeftRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectX(rect), arrowHeight + topLeftRadius + YBRectX(rect))]; + [bezierPath addArcWithCenter:topLeftArcCenter radius:topLeftRadius startAngle:M_PI endAngle:M_PI * 3 / 2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect) - arrowHeight, YBRectX(rect))]; + [bezierPath addArcWithCenter:topRightArcCenter radius:topRightRadius startAngle:M_PI * 3 / 2 endAngle:2 * M_PI clockwise:YES]; + + }else if (arrowDirection == YBPopupMenuArrowDirectionNone) { + topLeftArcCenter = CGPointMake(topLeftRadius + YBRectX(rect), topLeftRadius + YBRectX(rect)); + topRightArcCenter = CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect), topRightRadius + YBRectX(rect)); + bottomLeftArcCenter = CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) - bottomLeftRadius + YBRectX(rect)); + bottomRightArcCenter = CGPointMake(YBRectWidth(rect) - bottomRightRadius + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius + YBRectX(rect)); + [bezierPath moveToPoint:CGPointMake(topLeftRadius + YBRectX(rect), YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - topRightRadius, YBRectX(rect))]; + [bezierPath addArcWithCenter:topRightArcCenter radius:topRightRadius startAngle:M_PI * 3 / 2 endAngle:2 * M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius - YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomRightArcCenter radius:bottomRightRadius startAngle:0 endAngle:M_PI_2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) + YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomLeftArcCenter radius:bottomLeftRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectX(rect), arrowHeight + topLeftRadius + YBRectX(rect))]; + [bezierPath addArcWithCenter:topLeftArcCenter radius:topLeftRadius startAngle:M_PI endAngle:M_PI * 3 / 2 clockwise:YES]; + } + + [bezierPath closePath]; + return bezierPath; +} + +@end diff --git a/MRMobileRun/MRMineView/YBPopupMenu/YBRectConst.h b/MRMobileRun/MRMineView/YBPopupMenu/YBRectConst.h new file mode 100755 index 0000000..c2481d4 --- /dev/null +++ b/MRMobileRun/MRMineView/YBPopupMenu/YBRectConst.h @@ -0,0 +1,54 @@ +// +// YBRectMake.h +// YBPopupMenu +// +// Created by lyb on 2017/5/9. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import + +UIKIT_STATIC_INLINE CGFloat YBRectWidth(CGRect rect) +{ + return rect.size.width; +} + +UIKIT_STATIC_INLINE CGFloat YBRectHeight(CGRect rect) +{ + return rect.size.height; +} + +UIKIT_STATIC_INLINE CGFloat YBRectX(CGRect rect) +{ + return rect.origin.x; +} + +UIKIT_STATIC_INLINE CGFloat YBRectY(CGRect rect) +{ + return rect.origin.y; +} + +UIKIT_STATIC_INLINE CGFloat YBRectTop(CGRect rect) +{ + return rect.origin.y; +} + +UIKIT_STATIC_INLINE CGFloat YBRectBottom(CGRect rect) +{ + return rect.origin.y + rect.size.height; +} + +UIKIT_STATIC_INLINE CGFloat YBRectLeft(CGRect rect) +{ + return rect.origin.x; +} + +UIKIT_STATIC_INLINE CGFloat YBRectRight(CGRect rect) +{ + return rect.origin.x + rect.size.width; +} + + + + + diff --git a/MRMobileRun/MRMineView/YBPopupMenu/YBRectConst.m b/MRMobileRun/MRMineView/YBPopupMenu/YBRectConst.m new file mode 100755 index 0000000..1819b46 --- /dev/null +++ b/MRMobileRun/MRMineView/YBPopupMenu/YBRectConst.m @@ -0,0 +1,11 @@ +// +// YBRectMake.m +// YBPopupMenu +// +// Created by lyb on 2017/5/9. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import "YBRectConst.h" + + diff --git a/MRMobileRun/MRRankView/.DS_Store b/MRMobileRun/MRRankView/.DS_Store deleted file mode 100644 index 27def84..0000000 Binary files a/MRMobileRun/MRRankView/.DS_Store and /dev/null differ diff --git a/MRMobileRun/MRRankView/GYYRankChildViewController.h b/MRMobileRun/MRRankView/GYYRankChildViewController.h new file mode 100644 index 0000000..5073688 --- /dev/null +++ b/MRMobileRun/MRRankView/GYYRankChildViewController.h @@ -0,0 +1,26 @@ +// +// GYYRankChildViewController.h +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/21. +// + +#import + + +typedef NS_ENUM(NSUInteger, RankType) { + RankTypeDay = 0, + RankTypeWeek, + RankTypeMonth +}; + +NS_ASSUME_NONNULL_BEGIN + +@interface GYYRankChildViewController : UIViewController + +@property (nonatomic, assign)RankType rankType; +@property (nonatomic, assign)NSInteger isFaculty; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRankView/GYYRankChildViewController.m b/MRMobileRun/MRRankView/GYYRankChildViewController.m new file mode 100644 index 0000000..790f0cf --- /dev/null +++ b/MRMobileRun/MRRankView/GYYRankChildViewController.m @@ -0,0 +1,233 @@ +// +// GYYRankChildViewController.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/21. +// + +#import "GYYRankChildViewController.h" +#import "GYYRankHeaderMainView.h" +#import "GYYRankTableViewCell.h" +#import +#import +#import "UIImageView+WebCache.h" +#import +#import +#import + +static NSString *const rankCellIdentifier = @"rankCell"; + +@interface GYYRankChildViewController () + +@property (nonatomic, strong)UITableView *tableView; + + //明确数组里要存放什么类型的对象 + //视觉上直观,操作有便利 +@property (nonatomic, strong) NSMutableArray *dataArr; +@property (nonatomic, strong) GYYRankModel *myRankModel; + +@end + +@implementation GYYRankChildViewController +{ + NSInteger currentPage; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self createSubviews]; //创建视图 + currentPage = 1; + [self requestData]; //网络请求 异步进行 + // Do any additional setup after loading the view. +} + +- (void)refreshHeaderAction{ + currentPage = 1; //0 0 0 0 00 + [self requestData]; +} + +- (void)refreshFooterAction{ + currentPage ++; // currentPage + 1; + [self requestData]; +} + +- (void)requestData{ + /** + 是AFURLSessionManager的子类,为了便利使用HTTP请求。当一个baseURL提供时,用相对路径构造GET/POST等便利的方法来创建请求。 + */ + AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; + + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *token = [user objectForKey:@"token"]; + // 请求 TCP/IP http + AFHTTPRequestSerializer *requestSerializer = [AFHTTPRequestSerializer serializer]; + //添加请求头 + [requestSerializer setValue:token forHTTPHeaderField:@"token"]; + [manager setRequestSerializer:requestSerializer]; + + // 响应 + AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer]; + [responseSerializer setRemovesKeysWithNullValues:YES]; //去除空值 + responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObjectsFromSet:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", @"text/plain",@"application/atom+xml",@"application/xml",@"text/xml",nil]]; //设置接收内容的格式 + // 缓存位置 + NSString *path = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject]; + // 生成路径 + NSString *pathLast = [NSString stringWithFormat:@"/Caches/MRMoblieRun/%lu.plist", (unsigned long)[@"https://cyxbsmobile.redrock.team/wxapi/mobile-run/rank" hash]]; + NSString *PathName = [path stringByAppendingString:pathLast]; + + // 判断本地是否缓存过,为了减少用户等待,如果缓存过先展示本地的,请求成功之后再刷新 + if ([[NSFileManager defaultManager] fileExistsAtPath:PathName]) { + id result = [NSMutableDictionary dictionaryWithContentsOfFile:PathName]; + //直接在这里刷新UI + + + } + [manager setResponseSerializer:responseSerializer]; + + //HUD 加载菊花 +// MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; + + NSString *studentid = [[NSUserDefaults standardUserDefaults] objectForKey:@"studentID"]; + NSDictionary *param = @{@"studentid" : studentid, + @"page" : @(self->currentPage), //++ 第几次请求 + @"count" : @"15", //一次请求多少个 + @"type" : @(self.isFaculty), + @"subtype" : @(self.rankType)}; + [manager POST:@"https://cyxbsmobile.redrock.team/wxapi/mobile-run/rank" parameters:param success:^(NSURLSessionDataTask *task, id responseObject) { +// [hud hideAnimated:YES]; + // 本地数据库存一下 + [responseObject writeToFile:PathName atomically:YES]; + // 刷新UI + + if (self->currentPage == 1) { + [self.dataArr removeAllObjects]; + } + + //单个模型赋值 + self.myRankModel = [GYYRankModel mj_objectWithKeyValues:responseObject[@"data"][@"UserData"]]; + + + //模型数组赋值 注意方法以及参数 + NSArray *tempArr = [GYYRankModel mj_objectArrayWithKeyValuesArray:responseObject[@"rankdata"][@"List"]]; + //page conut + [self.dataArr addObjectsFromArray:tempArr]; + // 0 10 = 10 + // 10 10 = 20 + // 20 + [self.tableView reloadData]; // UI刷新是有开销的 + + if (tempArr.count < 15) { //假设我一页请求3条,但是这次只给我返回了 0 1 2 总之小于3 那么我可以断定 已经没有更多数据了,除非是后台出错了 + [self.tableView.mj_footer endRefreshingWithNoMoreData]; //脚部标记 没有更多数据,禁止上拉 + }else{ + [self.tableView.mj_footer endRefreshing]; + } + [self.tableView.mj_header endRefreshing]; + } failure:^(NSURLSessionDataTask *task, NSError *error) { +// [hud hideAnimated:YES]; + + [self.tableView.mj_footer endRefreshing]; + [self.tableView.mj_header endRefreshing]; + }]; +} + +- (void)createSubviews{ + [self.view addSubview:self.tableView]; + [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.mas_equalTo(UIEdgeInsetsZero); + }]; +} + +#pragma mark ======== UITableViewDelegate & UITableViewDataSource ======== +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { //分几个区 + return 1; +} + +/** + 下面三个方法 必须实现 + */ +//每个分区有多少个cell +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { //每个区有几个cell + return self.dataArr.count; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { //每个cell的高度 + return 78; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + GYYRankTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:rankCellIdentifier forIndexPath:indexPath]; + cell.rankModel = self.dataArr[indexPath.row]; + return cell; +} + +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ + UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, 103)]; + + if (self.myRankModel) { + GYYRankHeaderMainView *mainView = [[GYYRankHeaderMainView alloc] init]; + [headerView addSubview:mainView]; + mainView.rankModel = self.myRankModel; + [mainView mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.mas_equalTo(UIEdgeInsetsMake(10, 15, 5, 15)); + }]; + } + return headerView; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ + return 103; +} + +- (UITableView *)tableView{ + if (!_tableView) { + _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; + if (@available(iOS 11.0, *)) { + _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + } else { + self.automaticallyAdjustsScrollViewInsets = NO; + } + + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + _tableView.backgroundColor = GYYColor; + } else { + _tableView.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + _tableView.showsVerticalScrollIndicator = NO; //右侧 竖条 + _tableView.delegate = self; + _tableView.dataSource = self; + _tableView.estimatedRowHeight = 78; + _tableView.estimatedSectionHeaderHeight = 103; + [_tableView registerClass:[GYYRankTableViewCell class] forCellReuseIdentifier:rankCellIdentifier]; + _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + + MJRefreshNormalHeader *refreshHeader = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(refreshHeaderAction)]; + refreshHeader.lastUpdatedTimeLabel.hidden = NO; + [refreshHeader setTitle:@"正在刷新排行中………"forState:MJRefreshStateRefreshing]; + [refreshHeader setTitle:@"松开刷新排行" forState:MJRefreshStatePulling]; + [refreshHeader setTitle:@"下拉刷新排行" forState:MJRefreshStateIdle]; + _tableView.mj_header = refreshHeader; + + MJRefreshBackNormalFooter *refreshFooter = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(refreshFooterAction)]; + _tableView.mj_footer = refreshFooter; + [refreshFooter setTitle:@"已加载完全部排行" forState:MJRefreshStateNoMoreData]; + [refreshFooter setTitle:@"正在加载更多排行数据………" forState:MJRefreshStateRefreshing]; + } + return _tableView; +} + +- (NSMutableArray *)dataArr{ + if (!_dataArr) { + _dataArr = [NSMutableArray array]; + } + return _dataArr;; +} + +@end diff --git a/MRMobileRun/MRRankView/GYYRankHeaderMainView.h b/MRMobileRun/MRRankView/GYYRankHeaderMainView.h new file mode 100644 index 0000000..66a8054 --- /dev/null +++ b/MRMobileRun/MRRankView/GYYRankHeaderMainView.h @@ -0,0 +1,20 @@ +// +// GYYRankHeaderMainView.h +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/14. +// + +#import + +@class GYYRankModel; + +NS_ASSUME_NONNULL_BEGIN + +@interface GYYRankHeaderMainView : UIView + +@property (nonatomic, strong)GYYRankModel *rankModel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRankView/GYYRankHeaderMainView.m b/MRMobileRun/MRRankView/GYYRankHeaderMainView.m new file mode 100644 index 0000000..330bd4d --- /dev/null +++ b/MRMobileRun/MRRankView/GYYRankHeaderMainView.m @@ -0,0 +1,187 @@ +// +// GYYRankHeaderMainView.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/14. +// + +#import "GYYRankHeaderMainView.h" +#import "GYYRankModel.h" +#import +#import "UIImageView+WebCache.h" + +@interface GYYRankHeaderMainView() + +@property (nonatomic, strong)UIImageView *headImg; +@property (nonatomic, strong)UILabel *nameLab; +@property (nonatomic, strong)UILabel *distanceLab; +@property (nonatomic, strong)UILabel *rankLab; + + +@end + +@implementation GYYRankHeaderMainView + +- (instancetype)init{ + self = [super init]; + if (self) { + self.backgroundColor = [UIColor whiteColor]; + + self.layer.cornerRadius = 49; //圆角 + + self.layer.shadowColor = [COLOR_WITH_HEX(0xAAB9C0) colorWithAlphaComponent:0.1].CGColor; //阴影的颜色 + self.layer.shadowOffset = CGSizeMake(0, 3); //偏移量 + self.layer.shadowOpacity = 1; //不透明度 + self.layer.shadowRadius = 6; //阴影半径 阴影 + + // self.clipsToBounds = YES; //default is NO; + // self.layer.masksToBounds = YES; //default is NO; + + [self createSubviews]; + } + return self; +} + +- (void)createSubviews{ + [self addSubview:self.headImg]; + [self addSubview:self.rankLab]; + [self addSubview:self.nameLab]; + [self addSubview:self.distanceLab]; + + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFFFFFF); + } + else { + return COLOR_WITH_HEX(0x4A4D52); + } + }]; + self.backgroundColor = GYYColor; + } else { + self.backgroundColor = COLOR_WITH_HEX(0xFFFFFF); + } + UILabel *tipLab = [[UILabel alloc] init]; + [self addSubview:tipLab]; + tipLab.text = @"排名"; + tipLab.textColor = COLOR_WITH_HEX(0xB2B2B2); + tipLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size:10]; + [tipLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.rankLab); + make.bottom.mas_equalTo(-21); + }]; + + + [self.rankLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.mas_equalTo(-33); + make.top.mas_equalTo(21); + }]; + [self.headImg mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.left.mas_equalTo(9); + make.size.mas_equalTo(CGSizeMake(72, 72)); + }]; + [self.nameLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.headImg.mas_top).offset(8); + make.left.equalTo(self.headImg.mas_right).offset(15); + }]; + [self.distanceLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.nameLab); + make.bottom.mas_equalTo(-13); + }]; +} + +- (void)setRankModel:(GYYRankModel *)rankModel{ + _rankModel = rankModel; + + // 对图片的网络请求进行封装,对请求的图片进行缓存,如果没有请求过,进行网络请求,如果请求过,从缓存取值。 url = @"http:xxxxxxx/xxxxx/xxx.png" 转换成哈希值,存在哈希结构里。 + NSURL *url = [NSURL URLWithString:_rankModel.AvatarUrl]; //把字符串 转化为 NSUrl + NSLog(@"GYY%@",_rankModel.AvatarUrl); + [_headImg sd_setImageWithURL:url]; + //plaeceholder 占位图 + //[_headImg sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"logo头像"]]; + _nameLab.text = _rankModel.Nickname; + + NSString *unit; + if (!_rankModel.Unit) { + unit = @"km"; + }else{ + unit = _rankModel.Unit; + } + NSString *targetStr = [NSString stringWithFormat:@"%@%@", _rankModel.DistanceValue, unit]; + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:targetStr]; + [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Semibold" size:26] range:[targetStr rangeOfString:_rankModel.DistanceValue]]; + [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Semibold" size:18] range:[targetStr rangeOfString:unit]]; + _distanceLab.attributedText = attributedString; + _rankLab.text = [NSString stringWithFormat:@"%@", _rankModel.Rank]; +} + +- (UILabel *)rankLab{ + if (!_rankLab) { + _rankLab = [[UILabel alloc] init]; + _rankLab.textColor = COLOR_WITH_HEX(0xF06272); + _rankLab.font =[UIFont fontWithName:@"PingFangSC-Medium" size:25]; + } + return _rankLab; +} + +- (UIImageView *)headImg{ + if (!_headImg) { + _headImg = [[UIImageView alloc] init]; + _headImg.layer.masksToBounds = YES; + _headImg.layer.cornerRadius = 36; + } + return _headImg; +} + +- (UILabel *)nameLab{ + if (!_nameLab) { + _nameLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x333739); + } + else { + return COLOR_WITH_HEX(0xFFFFFF); + } + }]; + self->_nameLab.textColor = rankColor; + } else { + _nameLab.textColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + _nameLab.font = [UIFont fontWithName:@"PingFangSC-Medium" size:16]; + } + return _nameLab; +} + +- (UILabel *)distanceLab{ + if (!_distanceLab) { + _distanceLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x333739); + } + else { + return COLOR_WITH_HEX(0xFFFFFF); + } + }]; + self->_distanceLab.textColor = rankColor; + } else { + _distanceLab.textColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + } + return _distanceLab; +} +/* +// Only override drawRect: if you perform custom drawing. +// An empty implementation adversely affects performance during animation. +- (void)drawRect:(CGRect)rect { + // Drawing code +} +*/ + +@end diff --git a/MRMobileRun/MRRankView/GYYRankModel.h b/MRMobileRun/MRRankView/GYYRankModel.h new file mode 100644 index 0000000..a933b3c --- /dev/null +++ b/MRMobileRun/MRRankView/GYYRankModel.h @@ -0,0 +1,24 @@ +// +// GYYRankModel.h +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/12. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface GYYRankModel : NSObject + +@property (nonatomic, copy)NSString *AvatarUrl; +@property (nonatomic, copy)NSString *Name; +@property (nonatomic, copy)NSString *Nickname; +@property (nonatomic, copy)NSString *Rank; +@property (nonatomic, copy)NSString *Signature; +@property (nonatomic, copy)NSString *Unit; +@property (nonatomic, copy)NSString *DistanceValue; //Vaule + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRankView/GYYRankModel.m b/MRMobileRun/MRRankView/GYYRankModel.m new file mode 100644 index 0000000..3943168 --- /dev/null +++ b/MRMobileRun/MRRankView/GYYRankModel.m @@ -0,0 +1,34 @@ +// +// GYYRankModel.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/12. +// + +#import "GYYRankModel.h" +#import + +@implementation GYYRankModel + +//// NSNumer -> NSString 一劳永逸 +//- (void)setValue:(id)value forUndefinedKey:(NSString *)key{ +// if ([key isEqualToString:@"Value"]) { +// self.DistanceValue = [NSString stringWithFormat:@"%.2f", [value floatValue]]; +// } +//} + +//property 属性 根据属性名拦截value做基本数据操作 +- (id)mj_newValueFromOldValue:(id)oldValue property:(MJProperty *)property{ + if ([property.name isEqualToString:@"DistanceValue"]) { + return [NSString stringWithFormat:@"%.2f", [oldValue floatValue]]; + } + return oldValue; +} + + //替换 ++ (NSDictionary *)mj_replacedKeyFromPropertyName{ + return @{@"DistanceValue" : @"Value"}; + //新值 //数据返回值 这个可能有冲突 所以选择新值替换 +} + +@end diff --git a/MRMobileRun/MRRankView/GYYRankTableViewCell.h b/MRMobileRun/MRRankView/GYYRankTableViewCell.h new file mode 100644 index 0000000..047010c --- /dev/null +++ b/MRMobileRun/MRRankView/GYYRankTableViewCell.h @@ -0,0 +1,19 @@ +// +// GYYRankTableViewCell.h +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/12. +// + +#import +#import "GYYRankModel.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface GYYRankTableViewCell : UITableViewCell + +@property (nonatomic, strong) GYYRankModel *rankModel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRankView/GYYRankTableViewCell.m b/MRMobileRun/MRRankView/GYYRankTableViewCell.m new file mode 100644 index 0000000..e4fdaaf --- /dev/null +++ b/MRMobileRun/MRRankView/GYYRankTableViewCell.m @@ -0,0 +1,223 @@ +// +// GYYRankTableViewCell.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/12. +// + +#import "GYYRankTableViewCell.h" +#import +#import "UIImageView+WebCache.h" //SDWebImage头文件 + +@interface GYYRankTableViewCell() + +@property (nonatomic, strong)UIImageView *rankIcon; +@property (nonatomic, strong)UILabel *rankLab; +@property (nonatomic, strong)UIImageView *headImg; +@property (nonatomic, strong)UILabel *nameLab; +@property (nonatomic, strong)UILabel *signLab; +@property (nonatomic, strong)UILabel *distanceLab; + +@end + +@implementation GYYRankTableViewCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + self.selectionStyle = UITableViewCellSelectionStyleNone; + [self createSubviews]; + } + return self; +} + +- (void)createSubviews { + [self.contentView addSubview:self.rankIcon]; + [self.contentView addSubview:self.rankLab]; + [self.contentView addSubview:self.headImg]; + [self.contentView addSubview:self.nameLab]; + [self.contentView addSubview:self.signLab]; + [self.contentView addSubview:self.distanceLab]; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + self.contentView.backgroundColor = GYYColor; + } else { + self.contentView.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + + [self.rankIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.left.mas_equalTo(15); + make.size.mas_equalTo(CGSizeMake(24, 24)); + }]; + [self.rankLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.centerX.mas_equalTo(-(screenWidth / 2 - 27)); + }]; + [self.headImg mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.mas_equalTo(0); + make.left.mas_equalTo(43); + make.size.mas_equalTo(CGSizeMake(50, 50)); + }]; + [self.nameLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.headImg.mas_top).offset(4); + make.left.equalTo(self.headImg.mas_right).offset(9); + }]; + [self.signLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.nameLab.mas_bottom).offset(1); + make.left.equalTo(self.headImg.mas_right).offset(9); + }]; + [self.distanceLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.nameLab); + make.right.mas_equalTo(-15); + }]; +} + +- (void)setRankModel:(GYYRankModel *)rankModel{ + _rankModel = rankModel; + + // 对图片的网络请求进行封装,对请求的图片进行缓存,如果没有请求过,进行网络请求,如果请求过,从缓存取值。 url = @"http:xxxxxxx/xxxxx/xxx.png" 转换成哈希值,存在哈希结构里。 + NSURL *url = [NSURL URLWithString:_rankModel.AvatarUrl]; //把字符串 转化为 NSUrl + [_headImg sd_setImageWithURL:url]; + //plaeceholder 占位图 + [_headImg sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"logo头像"]]; + _nameLab.text = _rankModel.Nickname; + _signLab.text = _rankModel.Signature; + //@"%.6f" OC 取几位小数 .后面放几 + //@"%03ld" + + + NSString *targetStr = [NSString stringWithFormat:@"%@%@", _rankModel.DistanceValue, _rankModel.Unit]; + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:targetStr]; + [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Semibold" size:18] range:[targetStr rangeOfString:_rankModel.DistanceValue]]; + [attributedString addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Semibold" size:12] range:[targetStr rangeOfString:_rankModel.Unit]]; + _distanceLab.attributedText = attributedString; + + if ([_rankModel.Rank integerValue] <= 3) { + _rankLab.hidden = YES; + _rankIcon.hidden = NO; + + _rankIcon.image = [UIImage imageNamed:[NSString stringWithFormat:@"rank_%@", _rankModel.Rank]]; + }else{ + _rankLab.hidden = NO; + _rankIcon.hidden = YES; + + _rankLab.text = [NSString stringWithFormat:@"%@", _rankModel.Rank]; // + } + +} + +- (UIImageView *)rankIcon{ + if (!_rankIcon) { + _rankIcon = [[UIImageView alloc] init]; + } + return _rankIcon; +} + +- (UILabel *)rankLab{ + if (!_rankLab) { + _rankLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x64686F); + } + else { + return COLOR_WITH_HEX(0xFFFFFF); + } + }]; + self->_rankLab.textColor = rankColor; + } else { + _rankLab.textColor = COLOR_WITH_HEX(0x64686F); + // Fallback on earlier versions + } + _rankLab.font = [UIFont systemFontOfSize:16]; + } + return _rankLab; +} + +- (UIImageView *)headImg{ + if (!_headImg) { + _headImg = [[UIImageView alloc] init]; + _headImg.layer.masksToBounds = YES; + _headImg.layer.cornerRadius = 25; + } + return _headImg; +} + +- (UILabel *)nameLab{ + if (!_nameLab) { + _nameLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x333739); + } + else { + return COLOR_WITH_HEX(0xFFFFFF); + } + }]; + self->_nameLab.textColor = rankColor; + } else { + _nameLab.textColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + _nameLab.font = [UIFont systemFontOfSize:15]; + } + return _nameLab; +} + +- (UILabel *)signLab{ + if (!_signLab) { + _signLab = [[UILabel alloc] init]; + _signLab.textColor = COLOR_WITH_HEX(0xA0A0A0); + _signLab.font = [UIFont systemFontOfSize:11]; + _signLab.numberOfLines = 1; + } + return _signLab; +} + +- (UILabel *)distanceLab{ + if (!_distanceLab) { + _distanceLab = [[UILabel alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *rankColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0x333739); + } + else { + return COLOR_WITH_HEX(0xA0A0A0); + } + }]; + self->_distanceLab.textColor = rankColor; + } else { + _distanceLab.textColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + } + return _distanceLab; +} + +/* + + */ +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + + +@end diff --git a/MRMobileRun/MRRankView/GYYRankUnitViewController.h b/MRMobileRun/MRRankView/GYYRankUnitViewController.h new file mode 100644 index 0000000..22b2e79 --- /dev/null +++ b/MRMobileRun/MRRankView/GYYRankUnitViewController.h @@ -0,0 +1,14 @@ +// +// GYYRankUnitViewController.h +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/21. +// + +#import + +@interface GYYRankUnitViewController : UIViewController + +@property (nonatomic, assign)NSInteger isFaculty; + +@end diff --git a/MRMobileRun/MRRankView/GYYRankUnitViewController.m b/MRMobileRun/MRRankView/GYYRankUnitViewController.m new file mode 100644 index 0000000..628dc2a --- /dev/null +++ b/MRMobileRun/MRRankView/GYYRankUnitViewController.m @@ -0,0 +1,170 @@ +// +// GYYRankUnitViewController.m +// MRMobileRun +// +// Created by 郭蕴尧 on 2020/8/21. +// + +#import "GYYRankUnitViewController.h" +#import "GYYRankChildViewController.h" +#import "TYPagerController.h" +#import "TYTabPagerBar.h" + +@interface GYYRankUnitViewController () + +@property (nonatomic, strong) TYTabPagerBar *tabBar; +@property (nonatomic, strong) TYPagerController *pagerController; + +@property (nonatomic, strong) NSArray *datas; + +@end + +@implementation GYYRankUnitViewController + +- (void)viewWillLayoutSubviews { + [super viewWillLayoutSubviews]; + _tabBar.frame = CGRectMake(10, 0, screenWidth - 10, 39); + _pagerController.view.frame = CGRectMake(0, CGRectGetMaxY(_tabBar.frame), screenWidth, screenHeigth - CGRectGetMaxY(_tabBar.frame) - kTabBarHeight - (55 + (kIs_iPhoneX ? 44 : 20))); +} + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + [self createSubviews]; +} + +- (void)createSubviews{ + [self addTabPagerBar]; + [self addPagerController]; + [self reloadData]; +} + +#pragma mark - TYTabPagerBarDataSource +- (NSInteger)numberOfItemsInPagerTabBar { + return self.datas.count; +} + +- (UICollectionViewCell *)pagerTabBar:(TYTabPagerBar *)pagerTabBar cellForItemAtIndex:(NSInteger)index { + UICollectionViewCell *cell = [pagerTabBar dequeueReusableCellWithReuseIdentifier:[TYTabPagerBarCell cellIdentifier] forIndex:index]; + cell.titleLabel.text = self.datas[index]; + return cell; +} + +#pragma mark - TYTabPagerBarDelegate +//每组标题 +- (CGFloat)pagerTabBar:(TYTabPagerBar *)pagerTabBar widthForItemAtIndex:(NSInteger)index { + return 42; +} + +- (void)pagerTabBar:(TYTabPagerBar *)pagerTabBar didSelectItemAtIndex:(NSInteger)index { + [_pagerController scrollToControllerAtIndex:index animate:YES]; +} + +#pragma mark - TYPagerControllerDataSource +- (NSInteger)numberOfControllersInPagerController { + return self.datas.count; +} + +- (UIViewController *)pagerController:(TYPagerController *)pagerController controllerForIndex:(NSInteger)index prefetching:(BOOL)prefetching { + GYYRankChildViewController *rankChildVC = [[GYYRankChildViewController alloc] init]; + rankChildVC.isFaculty = self.isFaculty; + rankChildVC.rankType = index; + return rankChildVC; +} + +#pragma mark - TYPagerControllerDelegate +- (void)pagerController:(TYPagerController *)pagerController transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animated:(BOOL)animated { + [_tabBar scrollToItemFromIndex:fromIndex toIndex:toIndex animate:animated]; +} + +- (void)pagerController:(TYPagerController *)pagerController transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress { + [_tabBar scrollToItemFromIndex:fromIndex toIndex:toIndex progress:progress]; +} + +#pragma mark ======== tab布局 ======== +- (void)addTabPagerBar { + TYTabPagerBar *tabBar = [[TYTabPagerBar alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + tabBar.backgroundColor = GYYColor; + } else { + tabBar.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + tabBar.layout.barStyle = TYPagerBarStyleProgressView; + tabBar.layout.progressWidth = 42; + tabBar.layout.progressHeight = 4; + tabBar.layout.progressColor = COLOR_WITH_HEX(0x55D5E2); + tabBar.progressView.layer.cornerRadius = 2.0; + tabBar.layout.progressVerEdging = 0; + tabBar.dataSource = self; + tabBar.delegate = self; + tabBar.layout.cellEdging = 7.5; + tabBar.layout.cellSpacing = 10; + tabBar.layout.adjustContentCellsCenter = NO; + tabBar.layout.selectedTextFont = [UIFont boldSystemFontOfSize:18]; + tabBar.layout.normalTextFont = [UIFont systemFontOfSize:16]; + [tabBar registerClass:[TYTabPagerBarCell class] forCellWithReuseIdentifier:[TYTabPagerBarCell cellIdentifier]]; + [self.view addSubview:tabBar]; + _tabBar = tabBar; +} + +- (void)addPagerController { + TYPagerController *pagerController = [[TYPagerController alloc] init]; + pagerController.layout.prefetchItemCount = 1; + pagerController.dataSource = self; + pagerController.delegate = self; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + pagerController.scrollView.backgroundColor = GYYColor; + } else { + pagerController.scrollView.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + + [self addChildViewController:pagerController]; + [self.view addSubview:pagerController.view]; + _pagerController = pagerController; +} + +- (void)reloadData { + [_tabBar reloadData]; + [_pagerController reloadData]; +} + +#pragma mark ======== 懒加载 ======== +- (NSArray *)datas { + if (!_datas) { + _datas = @[@"日榜", @"周榜", @"月榜"]; + } + return _datas; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/MRMobileRun/MRRankView/TYPagerController/TYPagerController.h b/MRMobileRun/MRRankView/TYPagerController/TYPagerController.h new file mode 100755 index 0000000..380b980 --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TYPagerController.h @@ -0,0 +1,94 @@ +// +// TYPagerController.h +// TYPagerControllerDemo +// +// Created by tanyang on 16/4/13. +// Copyright © 2016年 tanyang. All rights reserved. +// + +#import +#import "TYPagerViewLayout.h" + +NS_ASSUME_NONNULL_BEGIN + +@class TYPagerController; +@protocol TYPagerControllerDataSource + +// viewController's count in pagerController +- (NSInteger)numberOfControllersInPagerController; + +/* 1.viewController at index in pagerController + 2.if prefetching is YES,the controller is preload,not display. + 3.if controller will display,will call viewWillAppear. + 4.you can register && dequeue controller, usage like tableView + */ +- (UIViewController *)pagerController:(TYPagerController *)pagerController controllerForIndex:(NSInteger)index prefetching:(BOOL)prefetching; + +@end + +@protocol TYPagerControllerDelegate + +@optional + +// Display customization +// the same to viewWillAppear, also can use viewController's viewWillAppear +- (void)pagerController:(TYPagerController *)pagerController viewWillAppear:(UIViewController *)viewController forIndex:(NSInteger)index; +- (void)pagerController:(TYPagerController *)pagerController viewDidAppear:(UIViewController *)viewController forIndex:(NSInteger)index; + +// Disappear customization +// the same to viewWillDisappear, also can use viewController's viewWillDisappear +- (void)pagerController:(TYPagerController *)pagerController viewWillDisappear:(UIViewController *)viewController forIndex:(NSInteger)index; +- (void)pagerController:(TYPagerController *)pagerController viewDidDisappear:(UIViewController *)viewController forIndex:(NSInteger)index; + +// Transition animation customization + +- (void)pagerController:(TYPagerController *)pagerController transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animated:(BOOL)animated; + +- (void)pagerController:(TYPagerController *)pagerController transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress; + + +// ScrollViewDelegate + +- (void)pagerControllerDidScroll:(TYPagerController *)pagerController; +- (void)pagerControllerWillBeginScrolling:(TYPagerController *)pagerController animate:(BOOL)animate; +- (void)pagerControllerDidEndScrolling:(TYPagerController *)pagerController animate:(BOOL)animate; + +@end + +@interface TYPagerController : UIViewController + +@property (nonatomic, weak, nullable) id dataSource; +@property (nonatomic, weak, nullable) id delegate; +// pagerController's layout,don't set layout's dataSource to other +@property (nonatomic, strong, readonly) TYPagerViewLayout *layout; +@property (nonatomic, weak, readonly) UIScrollView *scrollView; + +@property (nonatomic, assign, readonly) NSInteger countOfControllers; +@property (nonatomic, assign, readonly) NSInteger curIndex;// default -1 + +@property (nonatomic, strong, nullable, readonly) NSArray *visibleControllers; + +@property (nonatomic, assign) BOOL automaticallySystemManagerViewAppearanceMethods;// default YES.if YES system auto call view Appearance Methods(eg. viewWillAppear...) + +@property (nonatomic, assign) UIEdgeInsets contentInset; + +//if not visible, prefecth, cache view at index, return nil +- (UIViewController *_Nullable)controllerForIndex:(NSInteger)index; + +// register && dequeue's usage like tableView +- (void)registerClass:(Class)Class forControllerWithReuseIdentifier:(NSString *)identifier; +- (void)registerNib:(UINib *)nib forControllerWithReuseIdentifier:(NSString *)identifier; +- (UIViewController *)dequeueReusableControllerWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index; + +// scroll to index +- (void)scrollToControllerAtIndex:(NSInteger)index animate:(BOOL)animate; + +// update data and layout,but don't reset propertys(curIndex,visibleDatas,prefechDatas) +- (void)updateData; + +// reload data and reset propertys +- (void)reloadData; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRankView/TYPagerController/TYPagerController.m b/MRMobileRun/MRRankView/TYPagerController/TYPagerController.m new file mode 100755 index 0000000..8ac49cb --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TYPagerController.m @@ -0,0 +1,275 @@ +// +// TYPagerController.m +// TYPagerControllerDemo +// +// Created by tanyang on 16/4/13. +// Copyright © 2016年 tanyang. All rights reserved. +// + +#import "TYPagerController.h" + +@interface TYPagerController () { + // private + struct { + unsigned int viewWillAppearForIndex :1; + unsigned int viewDidAppearForIndex :1; + unsigned int viewWillDisappearForIndex :1; + unsigned int viewDidDisappearForIndex :1; + + unsigned int transitionFromIndexToIndex :1; + unsigned int transitionFromIndexToIndexProgress :1; + unsigned int viewDidScroll: 1; + unsigned int viewWillBeginScrolling: 1; + unsigned int viewDidEndScrolling: 1; + }_delegateFlags; +} + +// Data +@property (nonatomic, strong) TYPagerViewLayout *layout; + +@end + + +@implementation TYPagerController + +- (TYPagerViewLayout *)layout { + if (!_layout) { + UIScrollView *scrollView = [[UIScrollView alloc]init]; + TYPagerViewLayout *layout = [[TYPagerViewLayout alloc]initWithScrollView:scrollView]; + layout.dataSource = self; + layout.delegate = self; + layout.adjustScrollViewInset = YES; + _layout = layout; + } + return _layout; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super initWithCoder:aDecoder]) { + _automaticallySystemManagerViewAppearanceMethods = YES; + } + return self; +} + +- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + _automaticallySystemManagerViewAppearanceMethods = YES; + } + return self; +} + +#pragma mark - life cycle + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + self.view.backgroundColor = [UIColor whiteColor]; + + [self.view addSubview:self.layout.scrollView]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + _layout.scrollView.frame = UIEdgeInsetsInsetRect(self.view.bounds,_contentInset); +} + +- (void)viewWillLayoutSubviews +{ + [super viewWillLayoutSubviews]; + _layout.scrollView.frame = UIEdgeInsetsInsetRect(self.view.bounds,_contentInset); +} + +#pragma mark - getter && setter + +- (void)setDelegate:(id)delegate +{ + _delegate = delegate; + + _delegateFlags.viewWillAppearForIndex = [delegate respondsToSelector:@selector(pagerController:viewWillAppear:forIndex:)]; + _delegateFlags.viewDidAppearForIndex = [delegate respondsToSelector:@selector(pagerController:viewDidAppear:forIndex:)]; + _delegateFlags.viewWillDisappearForIndex = [delegate respondsToSelector:@selector(pagerController:viewWillDisappear:forIndex:)]; + _delegateFlags.viewDidDisappearForIndex = [delegate respondsToSelector:@selector(pagerController:viewDidDisappear:forIndex:)]; + + _delegateFlags.transitionFromIndexToIndex = [delegate respondsToSelector:@selector(pagerController:transitionFromIndex:toIndex:animated:)]; + _delegateFlags.transitionFromIndexToIndexProgress = [delegate respondsToSelector:@selector(pagerController:transitionFromIndex:toIndex:progress:)]; + + _delegateFlags.viewDidScroll = [delegate respondsToSelector:@selector(pagerControllerDidScroll:)]; + _delegateFlags.viewWillBeginScrolling = [delegate respondsToSelector:@selector(pagerControllerWillBeginScrolling:animate:)]; + _delegateFlags.viewDidEndScrolling = [delegate respondsToSelector:@selector(pagerControllerDidEndScrolling:animate:)]; +} + +- (NSInteger)curIndex { + return _layout.curIndex; +} + +- (NSInteger)countOfControllers { + return _layout.countOfPagerItems; +} + +- (NSArray *)visibleControllers { + return _layout.visibleItems; +} + +- (UIScrollView *)scrollView { + return _layout.scrollView; +} + +- (void)setContentInset:(UIEdgeInsets)contentInset { + _contentInset = contentInset; + [self.view setNeedsLayout]; +} + +- (BOOL)shouldAutomaticallyForwardAppearanceMethods { + return _automaticallySystemManagerViewAppearanceMethods; +} + +- (void)childViewController:(UIViewController *)childViewController BeginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated { + if (!_automaticallySystemManagerViewAppearanceMethods) { + [childViewController beginAppearanceTransition:isAppearing animated:animated]; + } +} + +- (void)childViewControllerEndAppearanceTransition:(UIViewController *)childViewController { + if (!_automaticallySystemManagerViewAppearanceMethods) { + [childViewController endAppearanceTransition]; + } +} + +#pragma mark - public method + +- (UIViewController *)controllerForIndex:(NSInteger)index { + return [_layout itemForIndex:index]; +} + +- (void)scrollToControllerAtIndex:(NSInteger)index animate:(BOOL)animate { + [_layout scrollToItemAtIndex:index animate:animate]; +} + +- (void)updateData { + [_layout updateData]; +} + +- (void)reloadData { + [_layout reloadData]; +} + +- (void)registerClass:(Class)Class forControllerWithReuseIdentifier:(NSString *)identifier { + [_layout registerClass:Class forItemWithReuseIdentifier:identifier]; +} +- (void)registerNib:(UINib *)nib forControllerWithReuseIdentifier:(NSString *)identifier { + [_layout registerNib:nib forItemWithReuseIdentifier:identifier]; +} +- (UIViewController *)dequeueReusableControllerWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index { + return [_layout dequeueReusableItemWithReuseIdentifier:identifier forIndex:index]; +} + +#pragma mark - private + +- (void)willBeginScrollingAnimate:(BOOL)animate { + if (_delegateFlags.viewWillBeginScrolling) { + [_delegate pagerControllerWillBeginScrolling:self animate:animate]; + } +} + +- (void)didEndScrollingAnimate:(BOOL)animate { + if (_delegateFlags.viewDidEndScrolling) { + [_delegate pagerControllerDidEndScrolling:self animate:animate]; + } +} + +#pragma mark - TYPagerViewLayoutDataSource + +- (NSInteger)numberOfItemsInPagerViewLayout { + return [_dataSource numberOfControllersInPagerController]; +} + +- (id)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout itemForIndex:(NSInteger)index prefetching:(BOOL)prefetching { + return [_dataSource pagerController:self controllerForIndex:index prefetching:prefetching]; +} +- (UIView *)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout viewForItem:(id)item atIndex:(NSInteger)index { + UIViewController *viewController = item; + return viewController.view; +} + +- (UIViewController *)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout viewControllerForItem:(id)item atIndex:(NSInteger)index { + return item; +} + +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout addVisibleItem:(id)item atIndex:(NSInteger)index { + UIViewController *viewController = item; + if (_delegateFlags.viewWillAppearForIndex) { + [_delegate pagerController:self viewWillAppear:viewController forIndex:index]; + } + // addChildViewController + [self addChildViewController:viewController]; + [self childViewController:viewController BeginAppearanceTransition:YES animated:YES]; + [pagerViewLayout.scrollView addSubview:viewController.view]; + [self childViewControllerEndAppearanceTransition:viewController]; + [viewController didMoveToParentViewController:self]; + if (_delegateFlags.viewDidAppearForIndex) { + [_delegate pagerController:self viewDidAppear:viewController forIndex:index]; + } +} + +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout removeInVisibleItem:(id)item atIndex:(NSInteger)index { + UIViewController *viewController = item; + if (_delegateFlags.viewWillDisappearForIndex) { + [_delegate pagerController:self viewWillDisappear:viewController forIndex:index]; + } + // removeChildViewController + [viewController willMoveToParentViewController:nil]; + [self childViewController:viewController BeginAppearanceTransition:NO animated:YES]; + [viewController.view removeFromSuperview]; + [self childViewControllerEndAppearanceTransition:viewController]; + [viewController removeFromParentViewController]; + if (_delegateFlags.viewDidDisappearForIndex) { + [_delegate pagerController:self viewDidDisappear:viewController forIndex:index]; + } +} + +#pragma mark - TYPagerViewLayoutDelegate + +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animated:(BOOL)animated { + if (_delegateFlags.transitionFromIndexToIndex) { + [_delegate pagerController:self transitionFromIndex:fromIndex toIndex:toIndex animated:animated]; + } +} + +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress { + if (_delegateFlags.transitionFromIndexToIndexProgress) { + [_delegate pagerController:self transitionFromIndex:fromIndex toIndex:toIndex progress:progress]; + } +} + +- (void)pagerViewLayoutDidScroll:(TYPagerViewLayout *)pagerViewLayout { + if (_delegateFlags.viewDidScroll) { + [_delegate pagerControllerDidScroll:self]; + } +} + +- (void)pagerViewLayoutWillBeginDragging:(TYPagerViewLayout *)pagerViewLayout { + [self willBeginScrollingAnimate:YES]; +} + +- (void)pagerViewLayoutWillBeginScrollToView:(TYPagerViewLayout *)pagerViewLayout animate:(BOOL)animate { + [self willBeginScrollingAnimate:animate]; +} + +- (void)pagerViewLayoutDidEndDecelerating:(TYPagerViewLayout *)pagerViewLayout { + [self didEndScrollingAnimate:YES]; +} + +- (void)pagerViewLayoutDidEndScrollToView:(TYPagerViewLayout *)pagerViewLayout animate:(BOOL)animate { + [self didEndScrollingAnimate:animate]; +} + +- (void)pagerViewLayoutDidEndScrollingAnimation:(TYPagerViewLayout *)pagerViewLayout { + [self didEndScrollingAnimate:YES]; +} + +- (void)dealloc +{ + _layout = nil; +} + +@end diff --git a/MRMobileRun/MRRankView/TYPagerController/TYPagerView.h b/MRMobileRun/MRRankView/TYPagerController/TYPagerView.h new file mode 100755 index 0000000..fdcf425 --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TYPagerView.h @@ -0,0 +1,93 @@ +// +// TYPagerView.h +// TYPagerControllerDemo +// +// Created by tany on 2017/7/5. +// Copyright © 2017年 tanyang. All rights reserved. +// + +#import +#import "TYPagerViewLayout.h" + +NS_ASSUME_NONNULL_BEGIN + +@class TYPagerView; +@protocol TYPagerViewDataSource + +- (NSInteger)numberOfViewsInPagerView; + +/* 1.if prefetching is YES, the prefetch view not display. + 2.if view will diaplay,will call willAppearView:forIndex:. + 3.layout.frameForItemAtIndex can get view's frame + 4.you can register && dequeue view, usage like tableView + */ +- (UIView *)pagerView:(TYPagerView *)pagerView viewForIndex:(NSInteger)index prefetching:(BOOL)prefetching; + +@end + +@protocol TYPagerViewDelegate +@optional + +// Display customization +// if want do something in view will display,you can implement this +- (void)pagerView:(TYPagerView *)pagerView willAppearView:(UIView *)view forIndex:(NSInteger)index; +- (void)pagerView:(TYPagerView *)pagerView didAppearView:(UIView *)view forIndex:(NSInteger)index; + +// Disappear customization + +- (void)pagerView:(TYPagerView *)pagerView willDisappearView:(UIView *)view forIndex:(NSInteger)index; +- (void)pagerView:(TYPagerView *)pagerView didDisappearView:(UIView *)view forIndex:(NSInteger)index; + +// Transition animation customization + +// if you implement ↓↓↓transitionFromIndex:toIndex:progress:,only tap change index will call this, you can set progressAnimateEnabel NO that not call progress method +- (void)pagerView:(TYPagerView *)pagerView transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animated:(BOOL)animated; + +// if you implement the method,also you need implement ↑↑↑transitionFromIndex:toIndex:animated:,deal with tap change index animate +- (void)pagerView:(TYPagerView *)pagerView transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress; + +// scrollView delegate + +- (void)pagerViewDidScroll:(TYPagerView *)pageView; +- (void)pagerViewWillBeginScrolling:(TYPagerView *)pageView animate:(BOOL)animate; +- (void)pagerViewDidEndScrolling:(TYPagerView *)pageView animate:(BOOL)animate; + + +@end + +@interface TYPagerView : UIView + +@property (nonatomic, weak, nullable) id dataSource; +@property (nonatomic, weak, nullable) id delegate; +// pagerView's layout,don't set layout's dataSource to other +@property (nonatomic, strong, readonly) TYPagerViewLayout *layout; +@property (nonatomic, strong, readonly) UIScrollView *scrollView; + +@property (nonatomic, assign, readonly) NSInteger countOfPagerViews; +@property (nonatomic, assign, readonly) NSInteger curIndex;// default -1 + +@property (nonatomic, assign, nullable, readonly) NSArray *visibleViews; + +@property (nonatomic, assign) UIEdgeInsets contentInset; + +//if not visible, prefecth, cache view at index, return nil +- (UIView *_Nullable)viewForIndex:(NSInteger)index; + +// register && dequeue's usage like tableView +- (void)registerClass:(Class)Class forViewWithReuseIdentifier:(NSString *)identifier; +- (void)registerNib:(UINib *)nib forViewWithReuseIdentifier:(NSString *)identifier; +- (UIView *)dequeueReusableViewWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index; + +// scroll to index +- (void)scrollToViewAtIndex:(NSInteger)index animate:(BOOL)animate; + +// update data and layout,but don't reset propertys(curIndex,visibleDatas,prefechDatas) +- (void)updateData; + +// reload data and reset propertys +- (void)reloadData; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/MRMobileRun/MRRankView/TYPagerController/TYPagerView.m b/MRMobileRun/MRRankView/TYPagerController/TYPagerView.m new file mode 100755 index 0000000..b869362 --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TYPagerView.m @@ -0,0 +1,238 @@ +// +// TYPagerView.m +// TYPagerControllerDemo +// +// Created by tany on 2017/7/5. +// Copyright © 2017年 tanyang. All rights reserved. +// + +#import "TYPagerView.h" + +@interface TYPagerView () { + // private + struct { + unsigned int willAppearViewForIndex :1; + unsigned int didAppearViewForIndex :1; + unsigned int willDisappearViewForIndex :1; + unsigned int didDisappearViewForIndex :1; + unsigned int transitionFromIndexToIndex :1; + unsigned int transitionFromIndexToIndexProgress :1; + unsigned int viewDidScroll: 1; + unsigned int viewWillBeginScrolling: 1; + unsigned int viewDidEndScrolling: 1; + }_delegateFlags; +} + +// Data +@property (nonatomic, strong) TYPagerViewLayout *layout; + +@end + +@implementation TYPagerView + +#pragma mark - life cycle + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + self.backgroundColor = [UIColor clearColor]; + // prevent sysytem automaticallyAdjustsScrollViewInsets + [self addFixAutoAdjustInsetScrollView]; + [self addLayoutScrollView]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super initWithCoder:aDecoder]) { + self.backgroundColor = [UIColor clearColor]; + // prevent sysytem automaticallyAdjustsScrollViewInsets + [self addFixAutoAdjustInsetScrollView]; + [self addLayoutScrollView]; + } + return self; +} + +- (void)addFixAutoAdjustInsetScrollView { + UIView *view = [[UIView alloc]init]; + [self addSubview:view]; +} + +- (void)addLayoutScrollView { + UIScrollView *contentView = [[UIScrollView alloc]init]; + TYPagerViewLayout *layout = [[TYPagerViewLayout alloc]initWithScrollView:contentView]; + layout.dataSource = self; + layout.delegate = self; + [self addSubview:contentView]; + _layout = layout; + _layout.scrollView.frame = self.bounds; +} + +#pragma mark - getter && setter + +- (NSInteger)curIndex { + return _layout.curIndex; +} + +- (NSInteger)countOfPagerViews { + return _layout.countOfPagerItems; +} + +- (NSArray *)visibleViews { + return _layout.visibleItems; +} + +- (UIScrollView *)scrollView { + return _layout.scrollView; +} + +- (void)setContentInset:(UIEdgeInsets)contentInset { + _contentInset = contentInset; + [self setNeedsLayout]; +} + +- (void)setDelegate:(id)delegate { + _delegate = delegate; + + _delegateFlags.willAppearViewForIndex = [delegate respondsToSelector:@selector(pagerView:willAppearView:forIndex:)]; + _delegateFlags.didAppearViewForIndex = [delegate respondsToSelector:@selector(pagerView:didAppearView:forIndex:)]; + _delegateFlags.willDisappearViewForIndex = [delegate respondsToSelector:@selector(pagerView:willDisappearView:forIndex:)]; + _delegateFlags.didDisappearViewForIndex = [delegate respondsToSelector:@selector(pagerView:didDisappearView:forIndex:)]; + + _delegateFlags.transitionFromIndexToIndex = [delegate respondsToSelector:@selector(pagerView:transitionFromIndex:toIndex:animated:)]; + _delegateFlags.transitionFromIndexToIndexProgress = [delegate respondsToSelector:@selector(pagerView:transitionFromIndex:toIndex:progress:)]; + + _delegateFlags.viewDidScroll = [delegate respondsToSelector:@selector(pagerViewDidScroll:)]; + _delegateFlags.viewWillBeginScrolling = [delegate respondsToSelector:@selector(pagerViewWillBeginScrolling:animate:)]; + _delegateFlags.viewDidEndScrolling = [delegate respondsToSelector:@selector(pagerViewDidEndScrolling:animate:)]; +} + +#pragma mark - public + +- (void)updateData { + [_layout updateData]; +} + +- (void)reloadData { + [_layout reloadData]; +} + +- (void)scrollToViewAtIndex:(NSInteger)index animate:(BOOL)animate { + [_layout scrollToItemAtIndex:index animate:animate]; +} + +- (UIView *)viewForIndex:(NSInteger)idx { + return [_layout itemForIndex:idx]; +} + +- (void)registerClass:(Class)Class forViewWithReuseIdentifier:(NSString *)identifier { + [_layout registerClass:Class forItemWithReuseIdentifier:identifier]; +} +- (void)registerNib:(UINib *)nib forViewWithReuseIdentifier:(NSString *)identifier { + [_layout registerNib:nib forItemWithReuseIdentifier:identifier]; +} +- (UIView *)dequeueReusableViewWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index { + return [_layout dequeueReusableItemWithReuseIdentifier:identifier forIndex:index]; +} + +#pragma mark - private + +- (void)willBeginScrollingAnimate:(BOOL)animate { + if (_delegateFlags.viewWillBeginScrolling) { + [_delegate pagerViewWillBeginScrolling:self animate:animate]; + } +} + +- (void)didEndScrollingAnimate:(BOOL)animate { + if (_delegateFlags.viewDidEndScrolling) { + [_delegate pagerViewDidEndScrolling:self animate:animate]; + } +} + +#pragma mark - TYPagerViewLayoutDataSource + +- (NSInteger)numberOfItemsInPagerViewLayout { + return [_dataSource numberOfViewsInPagerView]; +} + +- (id)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout itemForIndex:(NSInteger)index prefetching:(BOOL)prefetching { + return [_dataSource pagerView:self viewForIndex:index prefetching:prefetching]; +} + +- (UIView *)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout viewForItem:(id)item atIndex:(NSInteger)index { + return item; +} + +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout addVisibleItem:(id)item atIndex:(NSInteger)index { + UIView *visibleView = item; + if (_delegateFlags.willAppearViewForIndex) { + [_delegate pagerView:self willAppearView:visibleView forIndex:index]; + } + [pagerViewLayout.scrollView addSubview:visibleView]; + if (_delegateFlags.didAppearViewForIndex) { + [_delegate pagerView:self didAppearView:visibleView forIndex:index]; + } +} + +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout removeInVisibleItem:(id)item atIndex:(NSInteger)index { + UIView *invisibleView = item; + if (_delegateFlags.willDisappearViewForIndex) { + [_delegate pagerView:self willDisappearView:invisibleView forIndex:index]; + } + [invisibleView removeFromSuperview]; + if (_delegateFlags.didDisappearViewForIndex) { + [_delegate pagerView:self didDisappearView:invisibleView forIndex:index]; + } +} + +#pragma mark - TYPagerViewLayoutDelegate + +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animated:(BOOL)animated { + if (_delegateFlags.transitionFromIndexToIndex) { + [_delegate pagerView:self transitionFromIndex:fromIndex toIndex:toIndex animated:animated]; + } +} + +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress { + if (_delegateFlags.transitionFromIndexToIndexProgress) { + [_delegate pagerView:self transitionFromIndex:fromIndex toIndex:toIndex progress:progress]; + } +} + +- (void)pagerViewLayoutDidScroll:(TYPagerViewLayout *)pagerViewLayout { + if (_delegateFlags.viewDidScroll) { + [_delegate pagerViewDidScroll:self]; + } +} + +- (void)pagerViewLayoutWillBeginDragging:(TYPagerViewLayout *)pagerViewLayout { + [self willBeginScrollingAnimate:YES]; +} + +- (void)pagerViewLayoutWillBeginScrollToView:(TYPagerViewLayout *)pagerViewLayout animate:(BOOL)animate { + [self willBeginScrollingAnimate:animate]; +} + +- (void)pagerViewLayoutDidEndDecelerating:(TYPagerViewLayout *)pagerViewLayout { + [self didEndScrollingAnimate:YES]; +} + +- (void)pagerViewLayoutDidEndScrollToView:(TYPagerViewLayout *)pagerViewLayout animate:(BOOL)animate { + [self didEndScrollingAnimate:animate]; +} + +- (void)pagerViewLayoutDidEndScrollingAnimation:(TYPagerViewLayout *)pagerViewLayout { + [self didEndScrollingAnimate:YES]; +} + +#pragma mark - layoutSubviews + +- (void)layoutSubviews { + [super layoutSubviews]; + _layout.scrollView.frame = UIEdgeInsetsInsetRect(self.bounds,_contentInset); +} + +- (void)dealloc { + _layout = nil; +} + +@end diff --git a/MRMobileRun/MRRankView/TYPagerController/TYPagerViewLayout.h b/MRMobileRun/MRRankView/TYPagerController/TYPagerViewLayout.h new file mode 100755 index 0000000..06b9d70 --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TYPagerViewLayout.h @@ -0,0 +1,134 @@ +// +// TYPagerViewLayout.h +// TYPagerControllerDemo +// +// Created by tanyang on 2017/7/9. +// Copyright © 2017年 tany. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSObject (TY_PagerReuseIdentify) +// resueId +@property (nonatomic, strong, readonly, nullable) NSString *ty_pagerReuseIdentify; + +@end + +@class TYPagerViewLayout; +@protocol TYPagerViewLayoutDataSource + +- (NSInteger)numberOfItemsInPagerViewLayout; + +// if item is preload, prefetch will YES +- (id)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout itemForIndex:(NSInteger)index prefetching:(BOOL)prefetching; + +// return item's view +- (UIView *)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout viewForItem:(id)item atIndex:(NSInteger)index; + +// see TYPagerView&&TYPagerController, add&&remove item ,must implement scrollView addSubView item's view +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout addVisibleItem:(id)item atIndex:(NSInteger)index; +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout removeInVisibleItem:(id)item atIndex:(NSInteger)index; + +@optional + +// if have not viewController return nil. +- (UIViewController *)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout viewControllerForItem:(id)item atIndex:(NSInteger)index; + +@end + +@protocol TYPagerViewLayoutDelegate + +@optional + +// Transition animation customization + +// if you implement ↓↓↓transitionFromIndex:toIndex:progress:,only tap change index will call this, you can set progressAnimateEnabel NO that not call progress method +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animated:(BOOL)animated; + +// if you implement the method,also you need implement ↑↑↑transitionFromIndex:toIndex:animated:,deal with tap change index animate +- (void)pagerViewLayout:(TYPagerViewLayout *)pagerViewLayout transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress; + +// ScrollViewDelegate + +- (void)pagerViewLayoutDidScroll:(TYPagerViewLayout *)pagerViewLayout; +- (void)pagerViewLayoutWillBeginScrollToView:(TYPagerViewLayout *)pagerViewLayout animate:(BOOL)animate; +- (void)pagerViewLayoutDidEndScrollToView:(TYPagerViewLayout *)pagerViewLayout animate:(BOOL)animate; +- (void)pagerViewLayoutWillBeginDragging:(TYPagerViewLayout *)pagerViewLayout; +- (void)pagerViewLayoutDidEndDragging:(TYPagerViewLayout *)pagerViewLayout willDecelerate:(BOOL)decelerate; +- (void)pagerViewLayoutWillBeginDecelerating:(TYPagerViewLayout *)pagerViewLayout; +- (void)pagerViewLayoutDidEndDecelerating:(TYPagerViewLayout *)pagerViewLayout; +- (void)pagerViewLayoutDidEndScrollingAnimation:(TYPagerViewLayout *)pagerViewLayout; + +@end + +@interface TYPagerViewLayout<__covariant ItemType> : NSObject + +@property (nonatomic, weak, nullable) id dataSource; +@property (nonatomic, weak, nullable) id delegate; + +// strong,will control the delegate,don't set delegate on other place. +@property (nonatomic, strong, readonly) UIScrollView *scrollView; +// if viewcontroller's automaticallyAdjustsScrollViewInsets YES ,will cause frame problems, you can set YES, default YES +@property (nonatomic, assign) BOOL adjustScrollViewInset; + +@property (nonatomic, assign, readonly) NSInteger countOfPagerItems; +@property (nonatomic, assign, readonly) NSInteger curIndex;// default -1 + +@property (nonatomic, strong, readonly) NSCache *memoryCache;; // will cache pagerView,you can set countLimit +@property (nonatomic, assign) BOOL autoMemoryCache; // default YES + +@property (nonatomic, assign) NSInteger prefetchItemCount;// preload left and right item's count , default 0 +// because when superview add subview(have tableView) will call relodData,if set Yes will optimize. default NO +@property (nonatomic, assign) BOOL prefetchItemWillAddToSuperView; + +@property (nonatomic, assign, readonly) NSRange prefetchRange; +@property (nonatomic, assign, readonly) NSRange visibleRange; + +@property (nonatomic, strong, nullable, readonly) NSArray * visibleIndexs; +@property (nonatomic, strong, nullable, readonly) NSArray * visibleItems; + +// default YES, if NO,will not call delegate transitionFromIndex:toIndex:progress:,but will call transitionFromIndex:toIndex: +@property (nonatomic, assign) BOOL progressAnimateEnabel; + +// default NO, when scroll visible range change will add item.If YES add item only when scroll animate end, suggest set prefetchItemCount 1 or more +@property (nonatomic, assign) BOOL addVisibleItemOnlyWhenScrollAnimatedEnd; + +// default 0.5,when scroll progress percent will change index, only progressAnimateEnabel is NO or don't implement delegate transitionFromIndex: toIndex: progress: +@property (nonatomic, assign) CGFloat changeIndexWhenScrollProgress; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +/** + initializer will strong scrollView,and control delegate,don't set delegate on other place. + */ +- (instancetype)initWithScrollView:(UIScrollView *)scrollView NS_DESIGNATED_INITIALIZER; // strong scrollView + +- (ItemType _Nullable)itemForIndex:(NSInteger)idx; + +- (UIView *)viewForItem:(ItemType)item atIndex:(NSInteger)index; +// if have not viewController return nil. +- (UIViewController *_Nullable)viewControllerForItem:(id)item atIndex:(NSInteger)index; + +// view's frame at index +- (CGRect)frameForItemAtIndex:(NSInteger)index; + +// register && dequeue's usage like tableView +- (void)registerClass:(Class)Class forItemWithReuseIdentifier:(NSString *)identifier; +- (void)registerNib:(UINib *)nib forItemWithReuseIdentifier:(NSString *)identifier; +- (ItemType)dequeueReusableItemWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index; + +// scroll to index +- (void)scrollToItemAtIndex:(NSInteger)index animate:(BOOL)animate; + +// update data and layout,the same to relaodData,but don't reset propertys(curIndex,visibleDatas,prefechDatas) +- (void)updateData; + +// reload data and reset propertys +- (void)reloadData; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRankView/TYPagerController/TYPagerViewLayout.m b/MRMobileRun/MRRankView/TYPagerController/TYPagerViewLayout.m new file mode 100755 index 0000000..d0adff8 --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TYPagerViewLayout.m @@ -0,0 +1,819 @@ +// +// TYPagerViewLayout.m +// TYPagerControllerDemo +// +// Created by tanyang on 2017/7/9. +// Copyright © 2017年 tany. All rights reserved. +// + +#import "TYPagerViewLayout.h" +#import + +@interface TYAutoPurgeCache : NSCache +@end + +@implementation TYAutoPurgeCache + +- (nonnull instancetype)init { + if (self = [super init]) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +} +@end + +static char ty_pagerReuseIdentifyKey; + +@implementation NSObject (TY_PagerReuseIdentify) + +- (NSString *)ty_pagerReuseIdentify { + return objc_getAssociatedObject(self, &ty_pagerReuseIdentifyKey); +} + +- (void)setTy_pagerReuseIdentify:(NSString *)ty_pagerReuseIdentify { + objc_setAssociatedObject(self, &ty_pagerReuseIdentifyKey, ty_pagerReuseIdentify, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end + +typedef NS_ENUM(NSUInteger, TYPagerScrollingDirection) { + TYPagerScrollingLeft, + TYPagerScrollingRight, +}; + +NS_INLINE CGRect frameForItemAtIndex(NSInteger index, CGRect frame) +{ + return CGRectMake(index * CGRectGetWidth(frame), 0, CGRectGetWidth(frame), CGRectGetHeight(frame)); +} + +// caculate visilble range in offset +NS_INLINE NSRange visibleRangWithOffset(CGFloat offset,CGFloat width, NSInteger maxIndex) +{ + if (width <= 0) { + return NSMakeRange(0, 0); + } + NSInteger startIndex = offset/width; + NSInteger endIndex = ceil((offset + width)/width); + + if (startIndex < 0) { + startIndex = 0; + } else if (startIndex > maxIndex) { + startIndex = maxIndex; + } + + if (endIndex > maxIndex) { + endIndex = maxIndex; + } + + NSUInteger length = endIndex - startIndex; + if (length > 5) { + length = 5; + } + return NSMakeRange(startIndex, length); +} + +NS_INLINE NSRange prefetchRangeWithVisibleRange(NSRange visibleRange,NSInteger prefetchItemCount, NSInteger countOfPagerItems) { + if (prefetchItemCount <= 0) { + return NSMakeRange(0, 0); + } + NSInteger leftIndex = MAX((NSInteger)visibleRange.location - prefetchItemCount, 0); + NSInteger rightIndex = MIN(visibleRange.location+visibleRange.length+prefetchItemCount, countOfPagerItems); + return NSMakeRange(leftIndex, rightIndex - leftIndex); +} + +static const NSInteger kMemoryCountLimit = 16; + +@interface TYPagerViewLayout () { + // Private + BOOL _needLayoutContent; + BOOL _scrollAnimated; + BOOL _isTapScrollMoved; + CGFloat _preOffsetX; + NSInteger _firstScrollToIndex; + BOOL _didReloadData; + BOOL _didLayoutSubViews; + + struct { + unsigned int addVisibleItem :1; + unsigned int removeInVisibleItem :1; + }_dataSourceFlags; + + struct { + unsigned int transitionFromIndexToIndex :1; + unsigned int transitionFromIndexToIndexProgress :1; + unsigned int pagerViewLayoutDidScroll: 1; + }_delegateFlags; + +} + +// UI + +@property (nonatomic, strong) UIScrollView *scrollView; + +// Data + +@property (nonatomic, assign) NSInteger countOfPagerItems; +@property (nonatomic, assign) NSInteger curIndex; + +@property (nonatomic, strong) NSCache *memoryCache; + +@property (nonatomic, assign) NSRange visibleRange; +@property (nonatomic, assign) NSRange prefetchRange; + +@property (nonatomic, strong) NSDictionary *visibleIndexItems; +@property (nonatomic, strong) NSDictionary *prefetchIndexItems; + +//reuse Class and nib +@property (nonatomic, strong) NSMutableDictionary *reuseIdentifyClassOrNib; +// reuse items +@property (nonatomic, strong) NSMutableDictionary *reuseIdentifyItems; + +@end + +static NSString * kScrollViewFrameObserverKey = @"scrollView.frame"; + +@implementation TYPagerViewLayout + +#pragma mark - init + +- (instancetype)initWithScrollView:(UIScrollView *)scrollView { + if (self = [super init]) { + NSParameterAssert(scrollView!=nil); + _scrollView = scrollView; + + [self configurePropertys]; + + [self configureScrollView]; + + [self addScrollViewObservers]; + } + return self; +} + +#pragma mark - configure + +- (void)configurePropertys { + _curIndex = -1; + _preOffsetX = 0; + _changeIndexWhenScrollProgress = 0.5; + _didReloadData = NO; + _didLayoutSubViews = NO; + _firstScrollToIndex = 0; + _prefetchItemWillAddToSuperView = NO; + _addVisibleItemOnlyWhenScrollAnimatedEnd = NO; + _progressAnimateEnabel = YES; + _adjustScrollViewInset = YES; + _scrollAnimated = YES; + _autoMemoryCache = YES; +} + +- (void)configureScrollView { + _scrollView.showsHorizontalScrollIndicator = NO; + _scrollView.showsVerticalScrollIndicator = NO; + _scrollView.pagingEnabled = YES; + _scrollView.delegate = self; +} + +- (void)resetPropertys { + [self clearMemoryCache]; + [self removeVisibleItems]; + _scrollAnimated = NO; + _curIndex = -1; + _preOffsetX = 0; +} + +#pragma mark - getter setter + +- (NSArray *)visibleItems { + return _visibleIndexItems.allValues; +} + +- (NSArray *)visibleIndexs { + return _visibleIndexItems.allKeys; +} + +- (NSMutableDictionary *)reuseIdentifyItems { + if (!_reuseIdentifyItems) { + _reuseIdentifyItems = [NSMutableDictionary dictionary]; + } + return _reuseIdentifyItems; +} + +- (NSMutableDictionary *)reuseIdentifyClassOrNib { + if (!_reuseIdentifyClassOrNib) { + _reuseIdentifyClassOrNib = [NSMutableDictionary dictionary]; + } + return _reuseIdentifyClassOrNib; +} + +- (NSCache *)memoryCache { + if (!_memoryCache) { + _memoryCache = [[TYAutoPurgeCache alloc]init]; + _memoryCache.countLimit = kMemoryCountLimit; + } + return _memoryCache; +} + +- (void)setAutoMemoryCache:(BOOL)autoMemoryCache { + _autoMemoryCache = autoMemoryCache; + if(!_autoMemoryCache && _memoryCache){ + [_memoryCache removeAllObjects]; + _memoryCache = nil; + } +} + +- (void)setPrefetchItemCount:(NSInteger)prefetchItemCount { + _prefetchItemCount = prefetchItemCount; + if (prefetchItemCount <= 0 && _prefetchIndexItems) { + _prefetchIndexItems = nil; + } +} + +- (void)setDataSource:(id)dataSource { + _dataSource = dataSource; + _dataSourceFlags.addVisibleItem = [dataSource respondsToSelector:@selector(pagerViewLayout:addVisibleItem:atIndex:)]; + _dataSourceFlags.removeInVisibleItem = [dataSource respondsToSelector:@selector(pagerViewLayout:removeInVisibleItem:atIndex:)]; +} + +- (void)setDelegate:(id)delegate { + _delegate = delegate; + _delegateFlags.transitionFromIndexToIndex = [delegate respondsToSelector:@selector(pagerViewLayout:transitionFromIndex:toIndex:animated:)]; + _delegateFlags.transitionFromIndexToIndexProgress = [delegate respondsToSelector:@selector(pagerViewLayout:transitionFromIndex:toIndex:progress:)]; + _delegateFlags.pagerViewLayoutDidScroll = [delegate respondsToSelector:@selector(pagerViewLayoutDidScroll:)]; +} + +#pragma mark - public + +- (void)reloadData { + [self resetPropertys]; + + [self updateData]; +} + +// update don't reset propertys(curIndex) +- (void)updateData { + [self clearMemoryCache]; + _didReloadData = YES; + _countOfPagerItems = [_dataSource numberOfItemsInPagerViewLayout]; + [self setNeedLayout]; +} + +/** + scroll to item at index + */ +- (void)scrollToItemAtIndex:(NSInteger)index animate:(BOOL)animate { + if (index < 0 || index >= _countOfPagerItems) { + if (!_didReloadData && index >= 0) { + _firstScrollToIndex = index; + } + return; + } + + if (!_didLayoutSubViews && CGRectIsEmpty(_scrollView.frame)) { + _firstScrollToIndex = index; + } + + [self scrollViewWillScrollToView:_scrollView animate:animate]; + [_scrollView setContentOffset:CGPointMake(index * CGRectGetWidth(_scrollView.frame),0) animated:NO]; + [self scrollViewDidScrollToView:_scrollView animate:animate]; +} + +- (id)itemForIndex:(NSInteger)idx { + NSNumber *index = @(idx); + // 1.from visibleViews + id visibleItem = [_visibleIndexItems objectForKey:index]; + if (!visibleItem && _prefetchItemCount > 0) { + // 2.from prefetch + visibleItem = [_prefetchIndexItems objectForKey:index]; + } + if (!visibleItem) { + // 3.from cache + visibleItem = [self cacheItemForKey:index]; + } + return visibleItem; +} + +- (UIView *)viewForItem:(id)item atIndex:(NSInteger)index { + UIView *view = [_dataSource pagerViewLayout:self viewForItem:item atIndex:index]; + return view; +} + +- (UIViewController *)viewControllerForItem:(id)item atIndex:(NSInteger)index { + if ([_dataSource respondsToSelector:@selector(pagerViewLayout:viewControllerForItem:atIndex:)]) { + return [_dataSource pagerViewLayout:self viewControllerForItem:item atIndex:index]; + } + return nil; +} + +- (CGRect)frameForItemAtIndex:(NSInteger)index { + CGRect frame = frameForItemAtIndex(index, _scrollView.frame); + if (_adjustScrollViewInset) { + frame.size.height -= _scrollView.contentInset.top; + } + return frame; +} + +#pragma mark - register && dequeue + +- (void)registerClass:(Class)Class forItemWithReuseIdentifier:(NSString *)identifier { + [self.reuseIdentifyClassOrNib setObject:Class forKey:identifier]; +} + +- (void)registerNib:(UINib *)nib forItemWithReuseIdentifier:(NSString *)identifier { + [self.reuseIdentifyClassOrNib setObject:nib forKey:identifier]; +} + +- (id)dequeueReusableItemWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index { + NSAssert(_reuseIdentifyClassOrNib.count != 0, @"you don't register any identifiers!"); + NSObject *item = [self.reuseIdentifyItems objectForKey:identifier]; + if (item) { + [self.reuseIdentifyItems removeObjectForKey:identifier]; + return item; + } + id itemClassOrNib = [self.reuseIdentifyClassOrNib objectForKey:identifier]; + if (!itemClassOrNib) { + NSString *error = [NSString stringWithFormat:@"you don't register this identifier->%@",identifier]; + NSAssert(NO, error); + return nil; + } + + if (class_isMetaClass(object_getClass(itemClassOrNib))) { + // is class + item = [[((Class)itemClassOrNib) alloc]init]; + }else if ([itemClassOrNib isKindOfClass:[UINib class]]) { + // is nib + item =[((UINib *)itemClassOrNib)instantiateWithOwner:nil options:nil].firstObject; + } + if (!item){ + NSString *error = [NSString stringWithFormat:@"you register identifier->%@ is not class or nib!",identifier]; + NSAssert(NO, error); + return nil; + } + [item setTy_pagerReuseIdentify:identifier]; + UIView *view = [_dataSource pagerViewLayout:self viewForItem:item atIndex:index]; + view.frame = [self frameForItemAtIndex:index]; + return item; +} + +- (void)enqueueReusableItem:(NSObject *)reuseItem prefetchRange:(NSRange)prefetchRange atIndex:(NSInteger)index{ + if (reuseItem.ty_pagerReuseIdentify.length == 0 || NSLocationInRange(index, prefetchRange)) { + return; + } + [self.reuseIdentifyItems setObject:reuseItem forKey:reuseItem.ty_pagerReuseIdentify]; +} + +#pragma mark - layout content + +- (void)setNeedLayout { + // 1. get count Of pager Items + if (_countOfPagerItems <= 0) { + _countOfPagerItems = [_dataSource numberOfItemsInPagerViewLayout]; + } + _needLayoutContent = YES; + if (_curIndex >= _countOfPagerItems) { + _curIndex = _countOfPagerItems - 1; + } + + BOOL needLayoutSubViews = NO; + if (!_didLayoutSubViews && !CGRectIsEmpty(_scrollView.frame) && _firstScrollToIndex < _countOfPagerItems) { + _didLayoutSubViews = YES; + needLayoutSubViews = YES; + } + + // 2.set contentSize and offset + CGFloat contentWidth = CGRectGetWidth(_scrollView.frame); + _scrollView.contentSize = CGSizeMake(_countOfPagerItems * contentWidth, 0); + _scrollView.contentOffset = CGPointMake(MAX(needLayoutSubViews ? _firstScrollToIndex : _curIndex, 0)*contentWidth, _scrollView.contentOffset.y); + + // 3.layout content + if (_curIndex < 0 || needLayoutSubViews) { + [self scrollViewDidScroll:_scrollView]; + }else { + [self layoutIfNeed]; + } +} + +- (void)layoutIfNeed { + if (CGRectIsEmpty(_scrollView.frame)) { + return; + } + // 1.caculate visible range + CGFloat offsetX = _scrollView.contentOffset.x; + NSRange visibleRange = visibleRangWithOffset(offsetX, CGRectGetWidth(_scrollView.frame), _countOfPagerItems); + if (NSEqualRanges(_visibleRange, visibleRange) && !_needLayoutContent) { + // visible range not change + return; + } + _visibleRange = visibleRange; + _needLayoutContent = NO; + + BOOL afterPrefetchIfNoVisibleItems = !_visibleIndexItems; + if (!afterPrefetchIfNoVisibleItems) { + // 2.prefetch left and right Items + [self addPrefetchItemsOutOfVisibleRange:_visibleRange]; + } + // 3.remove invisible Items + [self removeVisibleItemsOutOfVisibleRange:_visibleRange]; + // 4.add visiible Items + [self addVisibleItemsInVisibleRange:_visibleRange]; + if (afterPrefetchIfNoVisibleItems) { + [self addPrefetchItemsOutOfVisibleRange:_visibleRange]; + } +} + +#pragma mark - remove && add visibleViews + +- (void)removeVisibleItems { + [_scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + _visibleIndexItems = nil; + _prefetchIndexItems = nil; + if (_reuseIdentifyItems) { + [_reuseIdentifyItems removeAllObjects]; + } +} + +- (void)removeVisibleItemsOutOfVisibleRange:(NSRange)visibleRange { + [_visibleIndexItems enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id item, BOOL * stop) { + NSInteger index = [key integerValue]; + if (!NSLocationInRange(index, visibleRange)) { + // out of visible + [self removeInvisibleItem:item atIndex:index]; + } + }]; +} + +- (void)removeInvisibleItem:(id)invisibleItem atIndex:(NSInteger)index{ + UIView *invisibleView = [self viewForItem:invisibleItem atIndex:index]; + if (!invisibleView.superview) { + return; + } + if (_dataSourceFlags.removeInVisibleItem) { + [_dataSource pagerViewLayout:self removeInVisibleItem:invisibleItem atIndex:index]; + }else { + NSAssert(NO, @"must implememt datasource pagerViewLayout:removeInVisibleItem:atIndex:!"); + } + + NSObject *reuseItem = invisibleItem; + if (_reuseIdentifyClassOrNib.count > 0 && reuseItem.ty_pagerReuseIdentify.length > 0) { + // reuse + [self enqueueReusableItem:reuseItem prefetchRange:_prefetchRange atIndex:index]; + }else { + [self cacheItem:invisibleItem forKey:@(index)]; + } +} + +- (void)addVisibleItemsInVisibleRange:(NSRange)visibleRange { + NSMutableDictionary *visibleIndexItems = [NSMutableDictionary dictionary]; + // add visible views + for (NSInteger idx = visibleRange.location ; idx < visibleRange.location + visibleRange.length; ++idx) { + // from visibleViews,prefetch,cache + id visibleItem = [self itemForIndex:idx]; + if (!visibleItem && (!_addVisibleItemOnlyWhenScrollAnimatedEnd || visibleRange.length == 1)) { + // ↑↑↑ if _addVisibleItemOnlyWhenScrollAnimatedEnd is NO ,scroll visible range change will add item from dataSource, else is YES only scroll animate end(visibleRange.length == 1) will add item from dataSource + visibleItem = [_dataSource pagerViewLayout:self itemForIndex:idx prefetching:NO]; + } + if (visibleItem) { + [self addVisibleItem:visibleItem atIndex:idx]; + visibleIndexItems[@(idx)] = visibleItem; + } + } + + if (visibleIndexItems.count > 0) { + _visibleIndexItems = [visibleIndexItems copy]; + }else { + _visibleIndexItems = nil; + } +} + +- (void)addVisibleItem:(id)visibleItem atIndex:(NSInteger)index{ + if (!visibleItem) { + NSAssert(visibleItem != nil, @"visibleView must not nil!"); + return; + } + UIView *view = [self viewForItem:visibleItem atIndex:index]; + if (view.superview && view.superview != _scrollView) { + [view removeFromSuperview]; + } + CGRect frame = [self frameForItemAtIndex:index]; + if (!CGRectEqualToRect(view.frame, frame)) { + view.frame = frame; + } + if (!_prefetchItemWillAddToSuperView && view.superview) { + return; + } + + if (_prefetchItemWillAddToSuperView && view.superview) { + UIViewController *viewController = [self viewControllerForItem:visibleItem atIndex:index]; + if (!viewController || viewController.parentViewController) { + return; + } + } + + if (_dataSourceFlags.addVisibleItem) { + [_dataSource pagerViewLayout:self addVisibleItem:visibleItem atIndex:index]; + }else { + NSAssert(NO, @"must implement datasource pagerViewLayout:addVisibleItem:frame:atIndex:!"); + } +} + +- (void)addPrefetchItemsOutOfVisibleRange:(NSRange)visibleRange{ + if (_prefetchItemCount <= 0) { + return; + } + NSRange prefetchRange = prefetchRangeWithVisibleRange(visibleRange, _prefetchItemCount, _countOfPagerItems); + if (visibleRange.length == 1) { + // ↑↑↑mean: scroll animate end + NSMutableDictionary *prefetchIndexItems = [NSMutableDictionary dictionary]; + // add prefetch items + for (NSInteger index = prefetchRange.location; index < NSMaxRange(prefetchRange); ++index) { + id prefetchItem = nil; + if (NSLocationInRange(index, visibleRange)) { + prefetchItem = [_visibleIndexItems objectForKey:@(index)]; + }else { + prefetchItem = [self prefetchInvisibleItemAtIndex:index]; + } + if (prefetchItem) { + [prefetchIndexItems setObject:prefetchItem forKey:@(index)]; + } + } + + BOOL haveReuseIdentifyClassOrNib = _reuseIdentifyClassOrNib.count > 0; + if (haveReuseIdentifyClassOrNib || _prefetchItemWillAddToSuperView) { + [_prefetchIndexItems enumerateKeysAndObjectsUsingBlock:^(NSNumber * key, id obj, BOOL * stop) { + NSInteger index = [key integerValue]; + if (haveReuseIdentifyClassOrNib) { + // resuse item + [self enqueueReusableItem:obj prefetchRange:prefetchRange atIndex:index]; + } + if (_prefetchItemWillAddToSuperView && !NSLocationInRange(index, prefetchRange)) { + // remove prefetch item to superView + UIView *view = [self viewForItem:obj atIndex:index]; + if (view.superview == _scrollView && ![_visibleIndexItems objectForKey:key]) { + [view removeFromSuperview]; + } + } + }]; + } + if (prefetchIndexItems.count > 0) { + _prefetchRange = prefetchRange; + _prefetchIndexItems = [prefetchIndexItems copy]; + }else { + _prefetchRange = NSMakeRange(0, 0); + _prefetchIndexItems = nil; + } + }else if (NSIntersectionRange(visibleRange, _prefetchRange).length == 0) { + // visible and prefetch intersection, remove all prefetchItems + if (_prefetchItemWillAddToSuperView) { + [_prefetchIndexItems enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, id obj, BOOL *stop) { + UIView *view = [self viewForItem:obj atIndex:[key integerValue]]; + if (view.superview == _scrollView && ![_visibleIndexItems objectForKey:key]) { + [view removeFromSuperview]; + } + }]; + } + _prefetchRange = NSMakeRange(0, 0); + _prefetchIndexItems = nil; + } +} + +- (UIView *)prefetchInvisibleItemAtIndex:(NSInteger)index { + id prefetchItem = [_prefetchIndexItems objectForKey:@(index)]; + if (!prefetchItem) { + prefetchItem = [_visibleIndexItems objectForKey:@(index)]; + } + if (!prefetchItem) { + prefetchItem = [self cacheItemForKey:@(index)]; + } + if (!prefetchItem) { + prefetchItem = [_dataSource pagerViewLayout:self itemForIndex:index prefetching:YES]; + UIView *view = [self viewForItem:prefetchItem atIndex:index]; + CGRect frame = [self frameForItemAtIndex:index]; + if (!CGRectEqualToRect(view.frame, frame)) { + view.frame = frame; + } + if (_prefetchItemWillAddToSuperView && view.superview != _scrollView) { + [_scrollView addSubview:view]; + } + } + return prefetchItem; +} + +#pragma mark - caculate index + +- (void)caculateIndexWithOffsetX:(CGFloat)offsetX direction:(TYPagerScrollingDirection)direction{ + if (CGRectIsEmpty(_scrollView.frame)) { + return; + } + if (_countOfPagerItems <= 0) { + _curIndex = -1; + return; + } + // scrollView width + CGFloat width = CGRectGetWidth(_scrollView.frame); + NSInteger index = 0; + // when scroll to progress(changeIndexWhenScrollProgress) will change index + double percentChangeIndex = _changeIndexWhenScrollProgress; + if (_changeIndexWhenScrollProgress >= 1.0 || [self progressCaculateEnable]) { + percentChangeIndex = 0.999999999; + } + + // caculate cur index + if (direction == TYPagerScrollingLeft) { + index = ceil(offsetX/width-percentChangeIndex); + }else { + index = floor(offsetX/width+percentChangeIndex); + } + + if (index < 0) { + index = 0; + }else if (index >= _countOfPagerItems) { + index = _countOfPagerItems-1; + } + if (index == _curIndex) { + // if index not same,change index + return; + } + + NSInteger fromIndex = MAX(_curIndex, 0); + _curIndex = index; + if (_delegateFlags.transitionFromIndexToIndex /*&& ![self progressCaculateEnable]*/) { + [_delegate pagerViewLayout:self transitionFromIndex:fromIndex toIndex:_curIndex animated:_scrollAnimated]; + } + _scrollAnimated = YES; +} + +- (void)caculateIndexByProgressWithOffsetX:(CGFloat)offsetX direction:(TYPagerScrollingDirection)direction{ + if (CGRectIsEmpty(_scrollView.frame)) { + return; + } + if (_countOfPagerItems <= 0) { + _curIndex = -1; + return; + } + CGFloat width = CGRectGetWidth(_scrollView.frame); + CGFloat floadIndex = offsetX/width; + NSInteger floorIndex = floor(floadIndex); + if (floorIndex < 0 || floorIndex >= _countOfPagerItems || floadIndex > _countOfPagerItems-1) { + return; + } + + CGFloat progress = offsetX/width-floorIndex; + NSInteger fromIndex = 0, toIndex = 0; + if (direction == TYPagerScrollingLeft) { + fromIndex = floorIndex; + toIndex = MIN(_countOfPagerItems -1, fromIndex + 1); + if (fromIndex == toIndex && toIndex == _countOfPagerItems-1) { + fromIndex = _countOfPagerItems-2; + progress = 1.0; + } + }else { + toIndex = floorIndex; + fromIndex = MIN(_countOfPagerItems-1, toIndex +1); + progress = 1.0 - progress; + } + + if (_delegateFlags.transitionFromIndexToIndexProgress) { + [_delegate pagerViewLayout:self transitionFromIndex:fromIndex toIndex:toIndex progress:progress]; + } +} + +- (BOOL)progressCaculateEnable { + return _delegateFlags.transitionFromIndexToIndexProgress && _progressAnimateEnabel && !_isTapScrollMoved; +} + +#pragma mark - memoryCache + +- (void)clearMemoryCache { + if (_autoMemoryCache && _memoryCache) { + [_memoryCache removeAllObjects]; + } +} + +- (void)cacheItem:(id)item forKey:(NSNumber *)key { + if (_autoMemoryCache && key) { + UIView *cacheItem = [self.memoryCache objectForKey:key]; + if (cacheItem && cacheItem == item) { + return; + } + [self.memoryCache setObject:item forKey:key]; + } +} + +- (id)cacheItemForKey:(NSNumber *)key { + if (_autoMemoryCache && _memoryCache && key) { + return [_memoryCache objectForKey:key]; + } + return nil; +} + +#pragma mark - UIScrollViewDelegate + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView { + if (!scrollView.superview) { + return; + } + // get scrolling direction + CGFloat offsetX = scrollView.contentOffset.x; + TYPagerScrollingDirection direction = offsetX >= _preOffsetX ? TYPagerScrollingLeft : TYPagerScrollingRight; + + // caculate index and progress + if ([self progressCaculateEnable]) { + [self caculateIndexByProgressWithOffsetX:offsetX direction:direction]; + } + [self caculateIndexWithOffsetX:offsetX direction:direction]; + + // layout items + [self layoutIfNeed]; + _isTapScrollMoved = NO; + + if (_delegateFlags.pagerViewLayoutDidScroll) { + [_delegate pagerViewLayoutDidScroll:self]; + } +} + +- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView +{ + _preOffsetX = scrollView.contentOffset.x; + if ([_delegate respondsToSelector:@selector(pagerViewLayoutWillBeginDragging:)]) { + [_delegate pagerViewLayoutWillBeginDragging:self]; + } +} + +- (void)scrollViewWillScrollToView:(UIScrollView *)scrollView animate:(BOOL)animate { + _preOffsetX = scrollView.contentOffset.x; + _isTapScrollMoved = YES; + _scrollAnimated = animate; + if ([_delegate respondsToSelector:@selector(pagerViewLayoutWillBeginScrollToView:animate:)]) { + [_delegate pagerViewLayoutWillBeginScrollToView:self animate:animate]; + } +} + +- (void)scrollViewDidScrollToView:(UIScrollView *)scrollView animate:(BOOL)animate { + if ([_delegate respondsToSelector:@selector(pagerViewLayoutDidEndScrollToView:animate:)]) { + [_delegate pagerViewLayoutDidEndScrollToView:self animate:animate]; + } +} + +- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { + if ([_delegate respondsToSelector:@selector(pagerViewLayoutDidEndDragging:willDecelerate:)]) { + [_delegate pagerViewLayoutDidEndDragging:self willDecelerate:decelerate]; + } +} + +- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView { + if ([_delegate respondsToSelector:@selector(pagerViewLayoutWillBeginDecelerating:)]) { + [_delegate pagerViewLayoutWillBeginDecelerating:self]; + } +} + +- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { + if ([_delegate respondsToSelector:@selector(pagerViewLayoutDidEndDecelerating:)]) { + [_delegate pagerViewLayoutDidEndDecelerating:self]; + } +} + +- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { + if ([_delegate respondsToSelector:@selector(pagerViewLayoutDidEndScrollingAnimation:)]) { + [_delegate pagerViewLayoutDidEndScrollingAnimation:self]; + } +} + +#pragma mark - Observer + +- (void)addScrollViewObservers { + [self addObserver:self forKeyPath:kScrollViewFrameObserverKey options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + if ([keyPath isEqualToString:kScrollViewFrameObserverKey]) { + CGRect newFrame = [[change objectForKey:NSKeyValueChangeNewKey]CGRectValue]; + CGRect oldFrame = [[change objectForKey:NSKeyValueChangeOldKey]CGRectValue]; + BOOL needLayoutContent = !CGRectEqualToRect(newFrame, oldFrame); + if (needLayoutContent) { + [self setNeedLayout]; + } + } +} + +- (void)removeScrollViewObservers { + [self removeObserver:self forKeyPath:kScrollViewFrameObserverKey context:nil]; +} + +- (void)dealloc { + [self removeScrollViewObservers]; + _scrollView.delegate = nil; + _scrollView = nil; + if (_reuseIdentifyItems) { + [_reuseIdentifyItems removeAllObjects]; + } + if (_reuseIdentifyClassOrNib) { + [_reuseIdentifyClassOrNib removeAllObjects]; + } + [self clearMemoryCache]; +} + +@end diff --git a/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBar.h b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBar.h new file mode 100755 index 0000000..ff4bd2a --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBar.h @@ -0,0 +1,82 @@ +// +// TYTabPagerBar.h +// TYPagerControllerDemo +// +// Created by tany on 2017/7/13. +// Copyright © 2017年 tany. All rights reserved. +// + +#import +#import "TYTabPagerBarLayout.h" + +NS_ASSUME_NONNULL_BEGIN + +@class TYTabPagerBar; +@protocol TYTabPagerBarDataSource + +- (NSInteger)numberOfItemsInPagerTabBar; + +- (UICollectionViewCell *)pagerTabBar:(TYTabPagerBar *)pagerTabBar cellForItemAtIndex:(NSInteger)index; + +@end + +@protocol TYTabPagerBarDelegate + +@optional + +// configure layout +- (void)pagerTabBar:(TYTabPagerBar *)pagerTabBar configureLayout:(TYTabPagerBarLayout *)layout; + +// if cell wdith is not variable,you can set layout.cellWidth. otherwise ,you can implement this return cell width. cell width not contain cell edge +- (CGFloat)pagerTabBar:(TYTabPagerBar *)pagerTabBar widthForItemAtIndex:(NSInteger)index; + +// did select cell item +- (void)pagerTabBar:(TYTabPagerBar *)pagerTabBar didSelectItemAtIndex:(NSInteger)index; + +// transition frome cell to cell with animated +- (void)pagerTabBar:(TYTabPagerBar *)pagerTabBar transitionFromeCell:(UICollectionViewCell * _Nullable)fromCell toCell:(UICollectionViewCell * _Nullable)toCell animated:(BOOL)animated; + +// transition frome cell to cell with progress +- (void)pagerTabBar:(TYTabPagerBar *)pagerTabBar transitionFromeCell:(UICollectionViewCell * _Nullable)fromCell toCell:(UICollectionViewCell * _Nullable)toCell progress:(CGFloat)progress; + +@end + +@interface TYTabPagerBar : UIView + +@property (nonatomic, weak, readonly) UICollectionView *collectionView; +@property (nonatomic, strong) UIView *progressView; +// automatically resized to self.bounds +@property (nonatomic, strong) UIView *backgroundView; + +@property (nonatomic, weak, nullable) id dataSource; + +@property (nonatomic, weak, nullable) id delegate; + +@property (nonatomic, strong) TYTabPagerBarLayout *layout; + +@property (nonatomic, assign) BOOL autoScrollItemToCenter; + +@property (nonatomic, assign, readonly) NSInteger countOfItems; + +@property (nonatomic, assign, readonly) NSInteger curIndex; + +@property (nonatomic, assign) UIEdgeInsets contentInset; + +- (void)registerClass:(Class)Class forCellWithReuseIdentifier:(NSString *)identifier; +- (void)registerNib:(UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier; + +- (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index; + +- (void)reloadData; + +- (void)scrollToItemFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animate:(BOOL)animate; +- (void)scrollToItemFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress; +- (void)scrollToItemAtIndex:(NSInteger)index atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated; + +- (CGFloat)cellWidthForTitle:(NSString * _Nullable)title; +- (CGRect)cellFrameWithIndex:(NSInteger)index; +- (nullable UICollectionViewCell *)cellForIndex:(NSInteger)index; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBar.m b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBar.m new file mode 100755 index 0000000..b17c34d --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBar.m @@ -0,0 +1,312 @@ +// +// TYTabPagerBar.m +// TYPagerControllerDemo +// +// Created by tany on 2017/7/13. +// Copyright © 2017年 tany. All rights reserved. +// + +#import "TYTabPagerBar.h" + +@interface TYTabPagerBar () { + struct { + unsigned int transitionFromeCellAnimated :1; + unsigned int transitionFromeCellProgress :1; + unsigned int widthForItemAtIndex :1; + }_delegateFlags; + TYTabPagerBarLayout *_layout; +} + +// UI +@property (nonatomic, weak) UICollectionView *collectionView; + +// Data + +@property (nonatomic, assign) NSInteger countOfItems; + +@property (nonatomic, assign) NSInteger curIndex; + +@property (nonatomic, assign) BOOL isFirstLayout; +@property (nonatomic, assign) BOOL didLayoutSubViews; + +@end + +@implementation TYTabPagerBar + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + _isFirstLayout = YES; + _didLayoutSubViews = NO; + _autoScrollItemToCenter = YES; + self.backgroundColor = [UIColor clearColor]; + [self addFixAutoAdjustInsetScrollView]; + [self addCollectionView]; + [self addUnderLineView]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super initWithCoder:aDecoder]) { + _isFirstLayout = YES; + _didLayoutSubViews = NO; + _autoScrollItemToCenter = YES; + self.backgroundColor = [UIColor clearColor]; + [self addFixAutoAdjustInsetScrollView]; + [self addCollectionView]; + [self addUnderLineView]; + } + return self; +} + +- (void)addFixAutoAdjustInsetScrollView { + UIView *view = [[UIView alloc]init]; + [self addSubview:view]; +} + +- (void)addCollectionView { + UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init]; + layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; + UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:UIEdgeInsetsInsetRect(self.bounds, _contentInset) collectionViewLayout:layout]; + collectionView.backgroundColor = [UIColor clearColor]; + collectionView.showsHorizontalScrollIndicator = NO; + collectionView.showsVerticalScrollIndicator = NO; + if ([collectionView respondsToSelector:@selector(setPrefetchingEnabled:)]) { + collectionView.prefetchingEnabled = NO; + } + collectionView.delegate = self; + collectionView.dataSource = self; + [self addSubview:collectionView]; + _collectionView = collectionView; +} + +- (void)addUnderLineView { + UIView *progressView = [[UIView alloc] init]; + progressView.backgroundColor = [UIColor whiteColor]; + + [_collectionView addSubview:progressView]; + _progressView = progressView; +} + +#pragma mark - getter setter +- (void)setProgressView:(UIView *)progressView { + if (_progressView == progressView) { + return; + } + if (_progressView) { + [_progressView removeFromSuperview]; + } + if (_layout && _layout.barStyle == TYPagerBarStyleCoverView) { + progressView.layer.zPosition = -1; + [_collectionView insertSubview:progressView atIndex:0]; + }else { + [_collectionView addSubview:progressView]; + } + if (_layout && self.superview) { + [_layout layoutSubViews]; + } +} + +- (void)setBackgroundView:(UIView *)backgroundView { + if (_backgroundView) { + [_backgroundView removeFromSuperview]; + } + _backgroundView = backgroundView; + backgroundView.frame = self.bounds; + [self insertSubview:backgroundView atIndex:0]; +} + +- (void)setDelegate:(id)delegate { + _delegate = delegate; + _delegateFlags.transitionFromeCellAnimated = [delegate respondsToSelector:@selector(pagerTabBar:transitionFromeCell:toCell:animated:)]; + _delegateFlags.transitionFromeCellProgress = [delegate respondsToSelector:@selector(pagerTabBar:transitionFromeCell:toCell:progress:)]; + _delegateFlags.widthForItemAtIndex = [delegate respondsToSelector:@selector(pagerTabBar:widthForItemAtIndex:)]; +} + +- (void)setLayout:(TYTabPagerBarLayout *)layout { + BOOL updateLayout = _layout && _layout != layout; + _layout = layout; + if (updateLayout) { + [self reloadData]; + } +} + +- (TYTabPagerBarLayout *)layout { + if (!_layout) { + _layout = [[TYTabPagerBarLayout alloc]initWithPagerTabBar:self]; + } + return _layout; +} + +#pragma mark - public + +- (void)reloadData { + _countOfItems = [_dataSource numberOfItemsInPagerTabBar]; + if (_curIndex >= _countOfItems) { + _curIndex = _countOfItems - 1; + } + if ([_delegate respondsToSelector:@selector(pagerTabBar:configureLayout:)]) { + [_delegate pagerTabBar:self configureLayout:self.layout]; + } + [self.layout layoutIfNeed]; + [_collectionView reloadData]; + [self.layout adjustContentCellsCenterInBar]; + [self.layout layoutSubViews]; +} + +- (void)registerClass:(Class)Class forCellWithReuseIdentifier:(NSString *)identifier { + [_collectionView registerClass:Class forCellWithReuseIdentifier:identifier]; +} + +- (void)registerNib:(UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier { + [_collectionView registerNib:nib forCellWithReuseIdentifier:identifier]; +} + +- (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index { + UICollectionViewCell *cell = [_collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:[NSIndexPath indexPathForItem:index inSection:0]]; + return cell; +} + +- (CGRect)cellFrameWithIndex:(NSInteger)index +{ + if (index >= _countOfItems) { + return CGRectZero; + } + UICollectionViewLayoutAttributes * cellAttrs = [_collectionView layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]]; + if (!cellAttrs) { + return CGRectZero; + } + return cellAttrs.frame; +} + +- (UICollectionViewCell *)cellForIndex:(NSInteger)index +{ + if (index >= _countOfItems) { + return nil; + } + return (UICollectionViewCell *)[_collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]]; +} + +- (void)scrollToItemFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animate:(BOOL)animate { + if (toIndex < _countOfItems && toIndex >= 0 && fromIndex < _countOfItems && fromIndex >= 0) { + _curIndex = toIndex; + [self transitionFromIndex:fromIndex toIndex:toIndex animated:animate]; + if (_autoScrollItemToCenter) { + if (!_didLayoutSubViews) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self scrollToItemAtIndex:toIndex atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:animate]; + }); + }else { + [self scrollToItemAtIndex:toIndex atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:animate]; + } + } + } +} + +- (void)scrollToItemFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress { + if (toIndex < _countOfItems && toIndex >= 0 && fromIndex < _countOfItems && fromIndex >= 0) { + [self transitionFromIndex:fromIndex toIndex:toIndex progress:progress]; + } +} + +- (void)scrollToItemAtIndex:(NSInteger)index atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated { + [_collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0] atScrollPosition:scrollPosition animated:animated]; +} + +- (CGFloat)cellWidthForTitle:(NSString *)title { + if (!title) { + return CGSizeZero.width; + } + //iOS 7 + CGRect frame = [title boundingRectWithSize:CGSizeMake(1000, 1000) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{ NSFontAttributeName:self.layout.selectedTextFont} context:nil]; + return CGSizeMake(ceil(frame.size.width), ceil(frame.size.height) + 1).width; +} + +#pragma mark - UICollectionViewDataSource + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + _countOfItems = [_dataSource numberOfItemsInPagerTabBar]; + return _countOfItems; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + UICollectionViewCell *cell = [_dataSource pagerTabBar:self cellForItemAtIndex:indexPath.item]; + [self.layout transitionFromCell:(indexPath.item == _curIndex ? nil : cell) toCell:(indexPath.item == _curIndex ? cell : nil) animate:NO]; + return cell; +} + +#pragma mark - UICollectionViewDelegateFlowLayout + +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + if ([_delegate respondsToSelector:@selector(pagerTabBar:didSelectItemAtIndex:)]) { + [_delegate pagerTabBar:self didSelectItemAtIndex:indexPath.item]; + } +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath +{ + if (self.layout.cellWidth > 0) { + return CGSizeMake(self.layout.cellWidth+self.layout.cellEdging*2, CGRectGetHeight(_collectionView.frame)); + }else if(_delegateFlags.widthForItemAtIndex){ + CGFloat width = [_delegate pagerTabBar:self widthForItemAtIndex:indexPath.item]+self.layout.cellEdging*2; + return CGSizeMake(width, CGRectGetHeight(_collectionView.frame)); + }else { + NSAssert(NO, @"you must return cell width!"); + } + return CGSizeZero; +} + +#pragma mark - transition cell + +- (void)transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animated:(BOOL)animated +{ + UICollectionViewCell *fromCell = [self cellForIndex:fromIndex]; + UICollectionViewCell *toCell = [self cellForIndex:toIndex]; + if (_delegateFlags.transitionFromeCellAnimated) { + [_delegate pagerTabBar:self transitionFromeCell:fromCell toCell:toCell animated:animated]; + }else { + [self.layout transitionFromCell:fromCell toCell:toCell animate:animated]; + } + [self.layout setUnderLineFrameWithIndex:toIndex animated:fromCell && animated ? animated: NO]; +} + +- (void)transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress +{ + UICollectionViewCell *fromCell = [self cellForIndex:fromIndex]; + UICollectionViewCell *toCell = [self cellForIndex:toIndex]; + if (_delegateFlags.transitionFromeCellProgress) { + [_delegate pagerTabBar:self transitionFromeCell:fromCell toCell:toCell progress:progress]; + }else { + [self.layout transitionFromCell:fromCell toCell:toCell progress:progress]; + } + [self.layout setUnderLineFrameWithfromIndex:fromIndex toIndex:toIndex progress:progress]; +} + +-(void)layoutSubviews { + [super layoutSubviews]; + _backgroundView.frame = self.bounds; + CGRect frame = UIEdgeInsetsInsetRect(self.bounds, _contentInset); + BOOL needUpdateLayout = (frame.size.height > 0 && _collectionView.frame.size.height != frame.size.height) || (frame.size.width > 0 && _collectionView.frame.size.width != frame.size.width); + _collectionView.frame = frame; + if (!_didLayoutSubViews && !CGRectIsEmpty(_collectionView.frame)) { + _didLayoutSubViews = YES; + } + if (needUpdateLayout) { + [_layout invalidateLayout]; + } + if (frame.size.height > 0 && frame.size.width > 0) { + [_layout adjustContentCellsCenterInBar]; + } + _isFirstLayout = NO; + [_layout layoutSubViews]; +} + +- (void)dealloc { + _collectionView.dataSource = nil; + _collectionView.delegate = nil; +} + +@end diff --git a/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarCell.h b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarCell.h new file mode 100755 index 0000000..c71070f --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarCell.h @@ -0,0 +1,25 @@ +// +// TYTabTitleViewCell.h +// TYPagerControllerDemo +// +// Created by tany on 16/5/4. +// Copyright © 2016年 tanyang. All rights reserved. +// + +#import +NS_ASSUME_NONNULL_BEGIN +@protocol TYTabPagerBarCellProtocol + +/** + font ,textColor will use TYTabPagerBarLayout's textFont,textColor + */ +@property (nonatomic, strong, readonly) UILabel *titleLabel; + +@end + +@interface TYTabPagerBarCell : UICollectionViewCell +@property (nonatomic, weak,readonly) UILabel *titleLabel; + ++ (NSString *)cellIdentifier; +@end +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarCell.m b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarCell.m new file mode 100755 index 0000000..69bfee7 --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarCell.m @@ -0,0 +1,53 @@ +// +// TYTabTitleViewCell.m +// TYPagerControllerDemo +// +// Created by tany on 16/5/4. +// Copyright © 2016年 tanyang. All rights reserved. +// + +#import "TYTabPagerBarCell.h" + +@interface TYTabPagerBarCell () +@property (nonatomic, weak) UILabel *titleLabel; +@end + +@implementation TYTabPagerBarCell + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + [self addTabTitleLabel]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + if (self = [super initWithCoder:aDecoder]) { + [self addTabTitleLabel]; + } + return self; +} + +- (void)addTabTitleLabel +{ + UILabel *titleLabel = [[UILabel alloc]init]; + titleLabel.font = [UIFont systemFontOfSize:15]; + titleLabel.textColor = [UIColor darkTextColor]; + titleLabel.textAlignment = NSTextAlignmentCenter; + [self.contentView addSubview:titleLabel]; + _titleLabel = titleLabel; +} + ++ (NSString *)cellIdentifier { + return @"TYTabPagerBarCell"; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + _titleLabel.frame = self.contentView.bounds; +} + +@end diff --git a/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarLayout.h b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarLayout.h new file mode 100755 index 0000000..525b19a --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarLayout.h @@ -0,0 +1,84 @@ +// +// TYTabPagerBarLayout.h +// TYPagerControllerDemo +// +// Created by tanyang on 2017/7/17. +// Copyright © 2017年 tany. All rights reserved. +// + +#import +#import "TYTabPagerBarCell.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSUInteger, TYPagerBarStyle) { + TYPagerBarStyleNoneView, + TYPagerBarStyleProgressView, + TYPagerBarStyleProgressBounceView, + TYPagerBarStyleProgressElasticView, + TYPagerBarStyleCoverView, +}; + +@class TYTabPagerBar; +@interface TYTabPagerBarLayout : NSObject + +@property (nonatomic, weak, readonly) TYTabPagerBar *pagerTabBar; +@property (nonatomic, assign, readonly) CGFloat selectFontScale; + +// set barStyle will reset propertys, so you should first time set it, +@property (nonatomic, assign) TYPagerBarStyle barStyle; // default TYPagerBarStyleProgressElasticView + +@property (nonatomic, assign) UIEdgeInsets sectionInset; + +// progress view +@property (nonatomic, assign) CGFloat progressHeight; // default 2 +@property (nonatomic, assign) CGFloat progressWidth; //if > 0 progress width is equal,else progress width is cell width +@property (nonatomic, strong, nullable) UIColor *progressColor; + +@property (nonatomic, assign) CGFloat progressRadius; // height/2 +@property (nonatomic, assign) CGFloat progressBorderWidth; +@property (nonatomic, strong, nullable) UIColor *progressBorderColor; + +@property (nonatomic, assign) CGFloat progressHorEdging; // default 6, if < 0 width + edge ,if >0 width - edge +@property (nonatomic, assign) CGFloat progressVerEdging; // default 0, cover style is 3. + +// cell frame +@property (nonatomic, assign) CGFloat cellWidth; // default 0, if > 0 cells width is equal,else if = 0 cell will call delegate +@property (nonatomic, assign) CGFloat cellSpacing; // default 2,cell space +@property (nonatomic, assign) CGFloat cellEdging; // default 0,cell left right edge +@property (nonatomic, assign) BOOL adjustContentCellsCenter;// default NO, cells center if contentSize < bar's width ,will set sectionInset + +// TYTabPagerBarCellProtocol -> cell's label +@property (nonatomic, strong) UIFont *normalTextFont; // default 15 +@property (nonatomic, strong) UIFont *selectedTextFont; // default 17 +@property (nonatomic, strong) UIColor *normalTextColor; // default 51.51.51 +@property (nonatomic, strong) UIColor *selectedTextColor; // default white +@property (nonatomic, assign) BOOL textColorProgressEnable; // default YES + +// animate duration +@property (nonatomic, assign) CGFloat animateDuration; // default 0.2 + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +- (instancetype)initWithPagerTabBar:(TYTabPagerBar *)pagerTabBar NS_DESIGNATED_INITIALIZER; + +- (void)layoutIfNeed; + +- (void)invalidateLayout; + +- (void)layoutSubViews; + +- (void)adjustContentCellsCenterInBar; + +// override +- (void)transitionFromCell:(UICollectionViewCell *_Nullable)fromCell toCell:(UICollectionViewCell *_Nullable)toCell animate:(BOOL)animate; + +- (void)transitionFromCell:(UICollectionViewCell *_Nullable)fromCell toCell:(UICollectionViewCell *_Nullable)toCell progress:(CGFloat)progress; + +- (void)setUnderLineFrameWithIndex:(NSInteger)index animated:(BOOL)animated; + +- (void)setUnderLineFrameWithfromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarLayout.m b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarLayout.m new file mode 100755 index 0000000..d247a44 --- /dev/null +++ b/MRMobileRun/MRRankView/TYPagerController/TabPager/TYTabPagerBarLayout.m @@ -0,0 +1,347 @@ +// +// TYTabPagerBarLayout.m +// TYPagerControllerDemo +// +// Created by tanyang on 2017/7/17. +// Copyright © 2017年 tany. All rights reserved. +// + +#import "TYTabPagerBarLayout.h" +#import "TYTabPagerBar.h" + +@interface TYTabPagerBarLayout () + +@property (nonatomic, weak) TYTabPagerBar *pagerTabBar; + +@property (nonatomic, assign) CGFloat selectFontScale; + +@end + +#define kUnderLineViewHeight 2 + +@implementation TYTabPagerBarLayout + +- (instancetype)initWithPagerTabBar:(TYTabPagerBar *)pagerTabBar { + if (self = [super init]) { + _pagerTabBar = pagerTabBar; + [self configurePropertys]; + self.barStyle = TYPagerBarStyleProgressElasticView; + } + return self; +} + +- (void)configurePropertys { + _cellSpacing = 2; + _cellEdging = 3; + _cellWidth = 0; + _progressHorEdging = 6; + _progressWidth = 0; + _animateDuration = 0.3; + + _normalTextFont = [UIFont systemFontOfSize:14]; + _selectedTextFont = [UIFont boldSystemFontOfSize:15]; + _normalTextColor = COLOR_WITH_HEX(0xB2B2B2); + if (@available(iOS 13.0, *)) { + _selectedTextColor = [UIColor labelColor]; + } else { + _selectedTextColor = COLOR_WITH_HEX(0x333739); + // Fallback on earlier versions + } + _textColorProgressEnable = YES; + //_adjustContentCellsCenter = YES; +} + +#pragma mark - geter setter + +- (void)setProgressRadius:(CGFloat)progressRadius { + _progressRadius = progressRadius; + _pagerTabBar.progressView.layer.cornerRadius = progressRadius; +} + +- (void)setProgressBorderWidth:(CGFloat)progressBorderWidth { + _progressBorderWidth = progressBorderWidth; + _pagerTabBar.progressView.layer.borderWidth = progressBorderWidth; +} + +- (void)setProgressBorderColor:(UIColor *)progressBorderColor { + _progressBorderColor = progressBorderColor; + if (!_progressColor) { + _pagerTabBar.progressView.backgroundColor = [UIColor clearColor]; + } + _pagerTabBar.progressView.layer.borderColor = progressBorderColor.CGColor; +} + +- (void)setProgressColor:(UIColor *)progressColor { + _progressColor = progressColor; + _pagerTabBar.progressView.backgroundColor = progressColor; +} + +- (void)setProgressHeight:(CGFloat)progressHeight { + _progressHeight = progressHeight; + CGRect frame = _pagerTabBar.progressView.frame; + CGFloat height = CGRectGetHeight(_pagerTabBar.collectionView.frame); + frame.origin.y = _barStyle == TYPagerBarStyleCoverView ? (height - _progressHeight)/2:(height - _progressHeight - _progressVerEdging); + frame.size.height = progressHeight; + _pagerTabBar.progressView.frame = frame; +} + +- (UIEdgeInsets)sectionInset { + if (!UIEdgeInsetsEqualToEdgeInsets(_sectionInset, UIEdgeInsetsZero) || _barStyle != TYPagerBarStyleCoverView) { + return _sectionInset; + } + if (_barStyle == TYPagerBarStyleCoverView && _adjustContentCellsCenter) { + return _sectionInset; + } + CGFloat horEdging = -_progressHorEdging+_cellSpacing; + return UIEdgeInsetsMake(0, horEdging, 0, horEdging); +} + +- (void)setAdjustContentCellsCenter:(BOOL)adjustContentCellsCenter { + BOOL change = _adjustContentCellsCenter != adjustContentCellsCenter; + _adjustContentCellsCenter = adjustContentCellsCenter; + if (change && _pagerTabBar.superview) { + [_pagerTabBar setNeedsLayout]; + } +} + +- (void)setBarStyle:(TYPagerBarStyle)barStyle +{ + if (barStyle == _barStyle) { + return; + } + if (_barStyle == TYPagerBarStyleCoverView) { + self.progressBorderWidth = 0; + self.progressBorderColor = nil; + } + _barStyle = barStyle; + switch (barStyle) { + case TYPagerBarStyleProgressView: + self.progressWidth = 0; + self.progressHorEdging = 6; + self.progressVerEdging = 0; + self.progressHeight = kUnderLineViewHeight; + break; + case TYPagerBarStyleProgressBounceView: + case TYPagerBarStyleProgressElasticView: + self.progressWidth = 30; + self.progressVerEdging = 0; + self.progressHorEdging = 0; + self.progressHeight = kUnderLineViewHeight; + break; + case TYPagerBarStyleCoverView: + self.progressWidth = 0; + self.progressHorEdging = -self.progressHeight/4; + self.progressVerEdging = 3; + break; + default: + break; + } + _pagerTabBar.progressView.hidden = barStyle == TYPagerBarStyleNoneView; + if (barStyle == TYPagerBarStyleCoverView) { + _progressRadius = 0; + _pagerTabBar.progressView.layer.zPosition = -1; + [_pagerTabBar.progressView removeFromSuperview]; + [_pagerTabBar.collectionView insertSubview: _pagerTabBar.progressView atIndex:0]; + }else { + self.progressRadius = _progressHeight/2; + if (_pagerTabBar.progressView.layer.zPosition == -1) { + _pagerTabBar.progressView.layer.zPosition = 0; + [_pagerTabBar.progressView removeFromSuperview]; + [_pagerTabBar.collectionView addSubview:_pagerTabBar.progressView]; + } + + } +} + +#pragma mark - public + +- (void)layoutIfNeed { + UICollectionViewFlowLayout *collectionLayout = (UICollectionViewFlowLayout *)_pagerTabBar.collectionView.collectionViewLayout; + collectionLayout.minimumLineSpacing = _cellSpacing; + collectionLayout.minimumInteritemSpacing = _cellSpacing; + _selectFontScale = self.normalTextFont.pointSize/(self.selectedTextFont ? self.selectedTextFont.pointSize:self.normalTextFont.pointSize); + collectionLayout.sectionInset = _sectionInset; +} + +- (void)invalidateLayout { + [_pagerTabBar.collectionView.collectionViewLayout invalidateLayout]; +} + +- (void)adjustContentCellsCenterInBar { + if (!_adjustContentCellsCenter || !_pagerTabBar.superview) { + return; + } + CGRect frame = self.pagerTabBar.collectionView.frame; + if (CGRectIsEmpty(frame)) { + return; + } + + UICollectionViewFlowLayout *collectionLayout = (UICollectionViewFlowLayout *)_pagerTabBar.collectionView.collectionViewLayout; + CGSize contentSize = collectionLayout.collectionViewContentSize; + NSArray *layoutAttribulte = [collectionLayout layoutAttributesForElementsInRect:CGRectMake(0, 0, MAX(contentSize.width, CGRectGetWidth(frame)), MAX(contentSize.height,CGRectGetHeight(frame)))]; + if (layoutAttribulte.count == 0) { + return; + } + + UICollectionViewLayoutAttributes *firstAttribute = layoutAttribulte.firstObject; + UICollectionViewLayoutAttributes *lastAttribute = layoutAttribulte.lastObject; + CGFloat left = CGRectGetMinX(firstAttribute.frame); + CGFloat right = CGRectGetMaxX(lastAttribute.frame); + if (right - left > CGRectGetWidth(self.pagerTabBar.frame)) { + return; + } + CGFloat sapce = (CGRectGetWidth(self.pagerTabBar.frame) - (right - left))/2; + _sectionInset = UIEdgeInsetsMake(_sectionInset.top, sapce, _sectionInset.bottom, sapce); + collectionLayout.sectionInset = _sectionInset; +} + +- (CGRect)cellFrameWithIndex:(NSInteger)index { + return [_pagerTabBar cellFrameWithIndex:index]; +} + +#pragma mark - cell + +- (void)transitionFromCell:(UICollectionViewCell *)fromCell toCell:(UICollectionViewCell *)toCell animate:(BOOL)animate { + if (_pagerTabBar.countOfItems == 0) { + return; + } + void (^animateBlock)() = ^{ + if (fromCell) { + fromCell.titleLabel.font = _selectedTextFont; + fromCell.titleLabel.textColor = _normalTextColor; + fromCell.transform = CGAffineTransformMakeScale(_selectFontScale, _selectFontScale); + } + if (toCell) { + toCell.titleLabel.font = _selectedTextFont; + toCell.titleLabel.textColor = _selectedTextColor; + toCell.transform = CGAffineTransformIdentity; + } + }; + if (animate) { + [UIView animateWithDuration:_animateDuration animations:^{ + animateBlock(); + }]; + }else{ + animateBlock(); + } + +} + +- (void)transitionFromCell:(UICollectionViewCell *)fromCell toCell:(UICollectionViewCell *)toCell progress:(CGFloat)progress { + if (_pagerTabBar.countOfItems == 0 || !_textColorProgressEnable) { + return; + } + CGFloat currentTransform = (1.0 - _selectFontScale)*progress; + fromCell.transform = CGAffineTransformMakeScale(1.0-currentTransform, 1.0-currentTransform); + toCell.transform = CGAffineTransformMakeScale(_selectFontScale+currentTransform, _selectFontScale+currentTransform); + + if (_normalTextColor == _selectedTextColor || !_selectedTextColor) { + return; + } + + CGFloat narR=0,narG=0,narB=0,narA=1; + [_normalTextColor getRed:&narR green:&narG blue:&narB alpha:&narA]; + CGFloat selR=0,selG=0,selB=0,selA=1; + [_selectedTextColor getRed:&selR green:&selG blue:&selB alpha:&selA]; + CGFloat detalR = narR - selR ,detalG = narG - selG,detalB = narB - selB,detalA = narA - selA; + + fromCell.titleLabel.textColor = [UIColor colorWithRed:selR+detalR*progress green:selG+detalG*progress blue:selB+detalB*progress alpha:selA+detalA*progress]; + toCell.titleLabel.textColor = [UIColor colorWithRed:narR-detalR*progress green:narG-detalG*progress blue:narB-detalB*progress alpha:narA-detalA*progress]; +} + +#pragma mark - progress View + +// set up progress view frame +- (void)setUnderLineFrameWithIndex:(NSInteger)index animated:(BOOL)animated +{ + UIView *progressView = _pagerTabBar.progressView; + if (progressView.isHidden || _pagerTabBar.countOfItems == 0) { + return; + } + + CGRect cellFrame = [self cellFrameWithIndex:index]; + CGFloat progressHorEdging = _progressWidth > 0 ? (cellFrame.size.width - _progressWidth)/2 : _progressHorEdging; + CGFloat progressX = cellFrame.origin.x+progressHorEdging; + CGFloat progressY = _barStyle == TYPagerBarStyleCoverView ? (cellFrame.size.height - _progressHeight)/2:(cellFrame.size.height - _progressHeight - _progressVerEdging); + CGFloat width = cellFrame.size.width-2*progressHorEdging; + + if (animated) { + [UIView animateWithDuration:_animateDuration animations:^{ + progressView.frame = CGRectMake(progressX, progressY, width, _progressHeight); + }]; + }else { + progressView.frame = CGRectMake(progressX, progressY, width, _progressHeight); + } +} + +- (void)setUnderLineFrameWithfromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress +{ + UIView *progressView = _pagerTabBar.progressView; + if (progressView.isHidden || _pagerTabBar.countOfItems == 0) { + return; + } + + CGRect fromCellFrame = [self cellFrameWithIndex:fromIndex]; + CGRect toCellFrame = [self cellFrameWithIndex:toIndex]; + + CGFloat progressFromEdging = _progressWidth > 0 ? (fromCellFrame.size.width - _progressWidth)/2 : _progressHorEdging; + CGFloat progressToEdging = _progressWidth > 0 ? (toCellFrame.size.width - _progressWidth)/2 : _progressHorEdging; + CGFloat progressY = _barStyle == TYPagerBarStyleCoverView ? (toCellFrame.size.height - _progressHeight)/2:(toCellFrame.size.height - _progressHeight - _progressVerEdging); + CGFloat progressX = 0, width = 0; + + if (_barStyle == TYPagerBarStyleProgressBounceView) { + if (fromCellFrame.origin.x < toCellFrame.origin.x) { + if (progress <= 0.5) { + progressX = fromCellFrame.origin.x + progressFromEdging; + width = (toCellFrame.size.width-progressToEdging+progressFromEdging+_cellSpacing)*2*progress + fromCellFrame.size.width-2*progressFromEdging; + }else { + progressX = fromCellFrame.origin.x + progressFromEdging + (fromCellFrame.size.width-progressFromEdging+progressToEdging+_cellSpacing)*(progress-0.5)*2; + width = CGRectGetMaxX(toCellFrame)-progressToEdging - progressX; + } + }else { + if (progress <= 0.5) { + progressX = fromCellFrame.origin.x + progressFromEdging - (toCellFrame.size.width-progressToEdging+progressFromEdging+_cellSpacing)*2*progress; + width = CGRectGetMaxX(fromCellFrame) - progressFromEdging - progressX; + }else { + progressX = toCellFrame.origin.x + progressToEdging; + width = (fromCellFrame.size.width-progressFromEdging+progressToEdging + _cellSpacing)*(1-progress)*2 + toCellFrame.size.width - 2*progressToEdging; + } + } + }else if (_barStyle == TYPagerBarStyleProgressElasticView) { + if (fromCellFrame.origin.x < toCellFrame.origin.x) { + if (progress <= 0.5) { + progressX = fromCellFrame.origin.x + progressFromEdging + (fromCellFrame.size.width-2*progressFromEdging)*progress; + width = (toCellFrame.size.width-progressToEdging+progressFromEdging+_cellSpacing)*2*progress - (toCellFrame.size.width-2*progressToEdging)*progress + fromCellFrame.size.width-2*progressFromEdging-(fromCellFrame.size.width-2*progressFromEdging)*progress; + }else { + progressX = fromCellFrame.origin.x + progressFromEdging + (fromCellFrame.size.width-2*progressFromEdging)*0.5 + (fromCellFrame.size.width-progressFromEdging - (fromCellFrame.size.width-2*progressFromEdging)*0.5 +progressToEdging+_cellSpacing)*(progress-0.5)*2; + width = CGRectGetMaxX(toCellFrame)-progressToEdging - progressX - (toCellFrame.size.width-2*progressToEdging)*(1-progress); + } + }else { + if (progress <= 0.5) { + progressX = fromCellFrame.origin.x + progressFromEdging - (toCellFrame.size.width-(toCellFrame.size.width-2*progressToEdging)/2-progressToEdging+progressFromEdging+_cellSpacing)*2*progress; + width = CGRectGetMaxX(fromCellFrame) - (fromCellFrame.size.width-2*progressFromEdging)*progress - progressFromEdging - progressX; + }else { + progressX = toCellFrame.origin.x + progressToEdging+(toCellFrame.size.width-2*progressToEdging)*(1-progress); + width = (fromCellFrame.size.width-progressFromEdging+progressToEdging-(fromCellFrame.size.width-2*progressFromEdging)/2 + _cellSpacing)*(1-progress)*2 + toCellFrame.size.width - 2*progressToEdging - (toCellFrame.size.width-2*progressToEdging)*(1-progress); + } + } + }else { + progressX = (toCellFrame.origin.x+progressToEdging-(fromCellFrame.origin.x+progressFromEdging))*progress+fromCellFrame.origin.x+progressFromEdging; + width = (toCellFrame.size.width-2*progressToEdging)*progress + (fromCellFrame.size.width-2*progressFromEdging)*(1-progress); + } + + progressView.frame = CGRectMake(progressX,progressY, width, _progressHeight); +} + +- (void)layoutSubViews { + if (CGRectIsEmpty(_pagerTabBar.frame)) { + return; + } + if (_barStyle == TYPagerBarStyleCoverView) { + self.progressHeight = CGRectGetHeight(_pagerTabBar.collectionView.frame) -self.progressVerEdging*2; + self.progressRadius = _progressRadius > 0 ? _progressRadius : self.progressHeight/2; + } + [self setUnderLineFrameWithIndex:_pagerTabBar.curIndex animated:NO]; +} + +@end diff --git a/MRMobileRun/MRRankView/ZYLRankViewController.m b/MRMobileRun/MRRankView/ZYLRankViewController.m index 9a2b480..9fedcf9 100644 --- a/MRMobileRun/MRRankView/ZYLRankViewController.m +++ b/MRMobileRun/MRRankView/ZYLRankViewController.m @@ -1,3 +1,4 @@ + // // ZYLRankViewController.m // MRMobileRun @@ -6,38 +7,171 @@ // #import "ZYLRankViewController.h" -#import "XIGSegementView.h" -#import "ZYLAcademyRankViewController.h" -#import "ZYLSchoolRankViewController.h" -#import "YYkit.h" -@interface ZYLRankViewController () +#import "GYYRankUnitViewController.h" +#import "TYPagerController.h" +#import "TYTabPagerBar.h" + +@interface ZYLRankViewController () + +@property (nonatomic, strong) TYTabPagerBar *tabBar; +@property (nonatomic, strong) TYPagerController *pagerController; + +@property (nonatomic, strong) NSArray *datas; @end @implementation ZYLRankViewController --(void)viewWillAppear:(BOOL)animated{ - self.navigationController.navigationBar.hidden = YES; -} +- (void)viewWillLayoutSubviews { + [super viewWillLayoutSubviews]; + _tabBar.frame = CGRectMake(0, 10 + (kIs_iPhoneX ? 44 : 20), screenWidth, 45); + _pagerController.view.frame = CGRectMake(0, CGRectGetMaxY(_tabBar.frame), screenWidth, screenHeigth - (55 + (kIs_iPhoneX ? 44 : 20))); +} - (void)viewDidLoad { [super viewDidLoad]; - self.view.backgroundColor = [UIColor whiteColor]; - self.automaticallyAdjustsScrollViewInsets = NO; - ZYLSchoolRankViewController *view1 = [[ZYLSchoolRankViewController alloc]init]; - view1.title = @"校园排行"; - ZYLAcademyRankViewController *view2 = [[ZYLAcademyRankViewController alloc]init]; - view2.title = @"学院排行"; - NSArray *viewArray = @[view1,view2]; - - XIGSegementView *segementView = [[XIGSegementView alloc]initWithFrame:CGRectMake(0, 50, screenWidth, self.view.height - NVGBARHEIGHT - STATUSBARHEIGHT) andControllers:viewArray WithStyle:@"systom"]; - segementView.titleTextFocusColor = [UIColor colorWithHexString:@"#333739"]; - segementView.titleTextNormalColor = [UIColor colorWithHexString:@"#B2B2B2"]; - [self.view addSubview:segementView]; - // Do any additional setup after loading the view. + [self createSubviews]; +} + +- (void)createSubviews{ + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + self.view.backgroundColor = GYYColor; + } else { + self.view.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + [self addTabPagerBar]; + [self addPagerController]; + [self reloadData]; +} + +#pragma mark - TYTabPagerBarDataSource +- (NSInteger)numberOfItemsInPagerTabBar { + return self.datas.count; +} + +- (UICollectionViewCell *)pagerTabBar:(TYTabPagerBar *)pagerTabBar cellForItemAtIndex:(NSInteger)index { + UICollectionViewCell *cell = [pagerTabBar dequeueReusableCellWithReuseIdentifier:[TYTabPagerBarCell cellIdentifier] forIndex:index]; + cell.titleLabel.text = self.datas[index]; + return cell; +} + +#pragma mark - TYTabPagerBarDelegate +//每组标题 +- (CGFloat)pagerTabBar:(TYTabPagerBar *)pagerTabBar widthForItemAtIndex:(NSInteger)index { + return 120; +} + +- (void)pagerTabBar:(TYTabPagerBar *)pagerTabBar didSelectItemAtIndex:(NSInteger)index { + [_pagerController scrollToControllerAtIndex:index animate:YES]; +} + +#pragma mark - TYPagerControllerDataSource +- (NSInteger)numberOfControllersInPagerController { + return self.datas.count; +} + +- (UIViewController *)pagerController:(TYPagerController *)pagerController controllerForIndex:(NSInteger)index prefetching:(BOOL)prefetching { + GYYRankUnitViewController *rankUnitVC = [[GYYRankUnitViewController alloc] init]; + rankUnitVC.isFaculty = index; + return rankUnitVC; +} + +#pragma mark - TYPagerControllerDelegate +- (void)pagerController:(TYPagerController *)pagerController transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animated:(BOOL)animated { + [_tabBar scrollToItemFromIndex:fromIndex toIndex:toIndex animate:animated]; +} + +- (void)pagerController:(TYPagerController *)pagerController transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress { + [_tabBar scrollToItemFromIndex:fromIndex toIndex:toIndex progress:progress]; +} + +#pragma mark ======== tab布局 ======== +- (void)addTabPagerBar { + TYTabPagerBar *tabBar = [[TYTabPagerBar alloc] init]; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + tabBar.backgroundColor = GYYColor; + } else { + tabBar.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + tabBar.layout.barStyle = TYPagerBarStyleNoneView; + tabBar.dataSource = self; + tabBar.delegate = self; + tabBar.layout.cellSpacing = 20; + tabBar.layout.adjustContentCellsCenter = YES; + tabBar.layout.selectedTextFont = [UIFont fontWithName:@"PingFangSC-Medium" size:20]; + tabBar.layout.normalTextFont = [UIFont fontWithName:@"PingFangSC-Medium" size:18]; + [tabBar registerClass:[TYTabPagerBarCell class] forCellWithReuseIdentifier:[TYTabPagerBarCell cellIdentifier]]; + [self.view addSubview:tabBar]; + _tabBar = tabBar; } +- (void)addPagerController { + TYPagerController *pagerController = [[TYPagerController alloc] init]; + pagerController.layout.prefetchItemCount = 1; + pagerController.dataSource = self; + pagerController.delegate = self; + if (@available(iOS 13.0, *)) { + UIColor *GYYColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return COLOR_WITH_HEX(0xFCFCFC); + } + else { + return COLOR_WITH_HEX(0x3C3F43); + } + }]; + pagerController.scrollView.backgroundColor = GYYColor; + } else { + pagerController.scrollView.backgroundColor = COLOR_WITH_HEX(0xFCFCFC); + } + + [self addChildViewController:pagerController]; + [self.view addSubview:pagerController.view]; + _pagerController = pagerController; +} + +- (void)reloadData { + [_tabBar reloadData]; + [_pagerController reloadData]; +} + +#pragma mark ======== 懒加载 ======== +- (NSArray *)datas { + if (!_datas) { + _datas = @[@"校园排行", @"学院排行"]; + } + return _datas; +} +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ @end diff --git a/MRMobileRun/MRRunning/.DS_Store b/MRMobileRun/MRRunning/.DS_Store deleted file mode 100644 index 20c1c23..0000000 Binary files a/MRMobileRun/MRRunning/.DS_Store and /dev/null differ diff --git a/MRMobileRun/MRRunning/Impact.ttf b/MRMobileRun/MRRunning/Impact.ttf new file mode 100644 index 0000000..8f6da36 Binary files /dev/null and b/MRMobileRun/MRRunning/Impact.ttf differ diff --git a/MRMobileRun/MRRunning/LongPressView.h b/MRMobileRun/MRRunning/LongPressView.h new file mode 100644 index 0000000..785bb47 --- /dev/null +++ b/MRMobileRun/MRRunning/LongPressView.h @@ -0,0 +1,32 @@ +// +// LongPressView.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/20. +// + + +#import +#import "SVGKit.h" +#import "SVGKImage.h" +#import "SVGKParser.h" + +NS_ASSUME_NONNULL_BEGIN + +//解锁、结束时长按手势的解锁,配上slider的颜色 + +@interface LongPressView : UIView +@property (nonatomic, strong)UIImageView *imgView; //png格式 +//@property (nonatomic, strong)SVGKLayeredImageView *imgview; //SVG格式 +@property (nonatomic, strong)UILabel *titleLbl; +@property (nonatomic, strong)UIView *bgView; + +@property (nonatomic, strong)UIColor *sideColor; +@property (nonatomic,strong) CAShapeLayer *arcLayer; + +- (void)initLongPressView; +- (void)addTarget:(id)target select:(SEL)selectAction; +- (void)stopDraw; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/LongPressView.m b/MRMobileRun/MRRunning/LongPressView.m new file mode 100644 index 0000000..4ea802a --- /dev/null +++ b/MRMobileRun/MRRunning/LongPressView.m @@ -0,0 +1,140 @@ +// +// LongPressView.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/20. +// + +#import "LongPressView.h" +#import +#define DEGREES_TO_RADOANS(x) (M_PI * (x) / 180.0) // 将角度转为弧度 + +@interface LongPressView() +{ + SEL _action; +} +@property (unsafe_unretained,nonatomic) id target; +@end + +@implementation LongPressView + +- (void)initLongPressView{ + //背景色(深色模式适配) + if (@available(iOS 11.0, *)) { + self.backgroundColor = WhiteColor; + } else { + // Fallback on earlier versions + } + + self.sideColor = [UIColor colorWithRed:123/255.0 green:183/255.0 blue:196/255.0 alpha:1.0]; + + //中心背景的颜色 + self.bgView = [[UIView alloc] init]; + [self addSubview:self.bgView]; + [self.bgView mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self); + make.size.mas_equalTo(CGSizeMake(90, 90)); + }]; + //将其设置为原型 + self.bgView.layer.cornerRadius = 45; + self.bgView.layer.masksToBounds = 45 ? YES : NO; + + + self.imgView = [[UIImageView alloc] init]; + [self.bgView addSubview:self.imgView]; + [self.imgView mas_makeConstraints:^(MASConstraintMaker *make) { +// make.center.equalTo(self); + make.centerX.equalTo(self); + make.centerY.equalTo(self).offset(-5); + make.size.mas_equalTo(CGSizeMake(30, 30)); + }]; +// self.imgview = [SVGKLayeredImageView new]; +// self.imgview.frame = CGRectMake(30, 21, 30, 30); +// +// [self.bgView addSubview:self.imgview]; +// [self.imgview mas_makeConstraints:^(MASConstraintMaker *make) { +// make.center.equalTo(self); +// make.centerX.equalTo(self); +// make.centerY.equalTo(self).offset(-5); +// make.size.mas_equalTo(CGSizeMake(30, 30)); +// }]; + + + + self.titleLbl = [[UILabel alloc] init]; + [self.bgView addSubview:self.titleLbl]; + [self.titleLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.imgView); + make.top.equalTo(self.imgView.mas_bottom); +// make.centerX.equalTo(self); +// make.top.equalTo(self).offset(61); + make.size.mas_equalTo(CGSizeMake(70, 17)); + }]; + self.titleLbl.textAlignment = NSTextAlignmentCenter; + self.titleLbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + +} + +//让这个View可以添加目标,实现方法 +- (void)addTarget:(id)target select:(SEL)selectAction{ + _target = target; + _action = selectAction; +} + +//绘制长按时边缘的动画 +- (void)drawRoundView:(CGPoint)centerPoint withStartAngle:(CGFloat)startAngle withEndAngle:(CGFloat)endAngle withRadius:(CGFloat)radius { + + UIBezierPath *path = [UIBezierPath bezierPath]; + [path addArcWithCenter:centerPoint radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; + _arcLayer = [CAShapeLayer layer]; + _arcLayer.strokeColor = self.sideColor.CGColor; + _arcLayer.fillColor = [UIColor clearColor].CGColor; + _arcLayer.path = path.CGPath; + + _arcLayer.lineWidth = 6; + _arcLayer.frame = self.bounds; + [self.layer addSublayer:_arcLayer]; + + + CABasicAnimation *bas = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + bas.duration = 1; + bas.fromValue = [NSNumber numberWithInteger:0]; + bas.toValue = [NSNumber numberWithInteger:1]; + bas.removedOnCompletion = NO; + bas.delegate = self; + [_arcLayer addAnimation:bas forKey:@"key"]; +} + +// 核心动画结束 +- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { + if (flag) + { + [_target performSelector:_action withObject:nil afterDelay:0.0]; + } +} + +//开始绘制 +- (void)startDrawRound{ + [self drawRoundView:CGPointMake(self.frame.size.width/2, self.frame.size.height/2) withStartAngle:DEGREES_TO_RADOANS(-90) withEndAngle:DEGREES_TO_RADOANS(270) withRadius:self.frame.size.height/2-1]; + +} + +//结束绘制 +- (void)stopDraw{ + if (_arcLayer) { + [_arcLayer removeAllAnimations]; + [_arcLayer removeFromSuperlayer]; +// _arcLayer = nil; + } +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ + [self startDrawRound]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ + [self stopDraw]; +} + + +@end diff --git a/MRMobileRun/MRRunning/MASmoothPathTool.h b/MRMobileRun/MRRunning/MASmoothPathTool.h new file mode 100644 index 0000000..1d3428d --- /dev/null +++ b/MRMobileRun/MRRunning/MASmoothPathTool.h @@ -0,0 +1,65 @@ +// +// MASmoothPathTool.h +// iOS-path-smooth +// +// Created by shaobin on 2017/10/12. +// Copyright © 2017年 autonavi. All rights reserved. +// + +#import +/* +为处理轨迹使轨迹平滑而用到的工具类 + +高斯去噪、卡尔曼滤波、抽稀算法 + 该ios demo 网址:https://github.com/amap-demo/iOS-path-smooth +*/ + +@interface MALonLatPoint : NSObject +@property (nonatomic, assign) double lat; +@property (nonatomic, assign) double lon; +@end + +@interface MASmoothPathTool : NSObject + +@property (nonatomic, assign) int intensity; +@property (nonatomic, assign) float threshHold; +@property (nonatomic, assign) int noiseThreshhold; + +/** + * 轨迹平滑优化 + * @param originlist 原始轨迹list,list.size大于2 + * @return 优化后轨迹list + */ +- (NSArray*)pathOptimize:(NSArray*)originlist; + +/** + * 轨迹线路滤波 + * @param originlist 原始轨迹list,list.size大于2 + * @return 滤波处理后的轨迹list + */ +- (NSArray*)kalmanFilterPath:(NSArray*)originlist; + + +/** + * 轨迹去噪,删除垂距大于20m的点 + * @param originlist 原始轨迹list,list.size大于2 + * @return 去燥后的list + */ +- (NSArray*)removeNoisePoint:(NSArray*)originlist; + +/** + * 单点滤波 + * @param lastLoc 上次定位点坐标 + * @param curLoc 本次定位点坐标 + * @return 滤波后本次定位点坐标值 + */ +- (MALonLatPoint*)kalmanFilterPoint:(MALonLatPoint*)lastLoc curLoc:(MALonLatPoint*)curLoc; + +/** + * 轨迹抽稀 + * @param inPoints 待抽稀的轨迹list,至少包含两个点,删除垂距小于mThreshhold的点 + * @return 抽稀后的轨迹list + */ +- (NSArray*)reducerVerticalThreshold:(NSArray*)inPoints; + +@end diff --git a/MRMobileRun/MRRunning/MASmoothPathTool.m b/MRMobileRun/MRRunning/MASmoothPathTool.m new file mode 100644 index 0000000..6430ea0 --- /dev/null +++ b/MRMobileRun/MRRunning/MASmoothPathTool.m @@ -0,0 +1,299 @@ +// +// MASmoothPathTool.m +// iOS-path-smooth +// +// Created by shaobin on 2017/10/12. +// Copyright © 2017年 autonavi. All rights reserved. +// + + +#import "MASmoothPathTool.h" +#import + + +@implementation MALonLatPoint +@end + +@implementation MASmoothPathTool +{ + double lastLocation_x; //上次位置 + double currentLocation_x;//这次位置 + double lastLocation_y; //上次位置 + double currentLocation_y;//这次位置 + double estimate_x; //修正后数据 + double estimate_y; //修正后数据 + double pdelt_x; //自预估偏差 + double pdelt_y; //自预估偏差 + double mdelt_x; //上次模型偏差 + double mdelt_y; //上次模型偏差 + double gauss_x; //高斯噪音偏差 + double gauss_y; //高斯噪音偏差 + double kalmanGain_x; //卡尔曼增益 + double kalmanGain_y; //卡尔曼增益 + + double m_R; + double m_Q; +} + +- (id)init { + self = [super init]; + + if(self) { + self.intensity = 3; + self.threshHold = 0.3f; + self.noiseThreshhold = 10; + } + + return self; +} +/** + * 轨迹平滑优化 + * @param originlist 原始轨迹list,list.size大于2 + * @return 优化后轨迹list + */ +- (NSArray*)pathOptimize:(NSArray*)originlist { + + NSArray* list = [self removeNoisePoint:originlist];//去噪 + NSArray* afterList = [self kalmanFilterPath:list intensity:self.intensity];//滤波 + NSArray* pathoptimizeList = [self reducerVerticalThreshold:afterList threshHold:self.threshHold];//抽稀 + return pathoptimizeList; +} + +/** + * 轨迹线路滤波 + * @param originlist 原始轨迹list,list.size大于2 + * @return 滤波处理后的轨迹list + */ +- (NSArray*)kalmanFilterPath:(NSArray*)originlist { + return [self kalmanFilterPath:originlist intensity:self.intensity]; +} + + +/** + * 轨迹去噪,删除垂距大于20m的点 + * @param originlist 原始轨迹list,list.size大于2 + * @return 去燥后的list + */ +- (NSArray*)removeNoisePoint:(NSArray*)originlist{ + return [self reduceNoisePoint:originlist threshHold:self.noiseThreshhold]; +} + +/** + * 单点滤波 + * @param lastLoc 上次定位点坐标 + * @param curLoc 本次定位点坐标 + * @return 滤波后本次定位点坐标值 + */ +- (MALonLatPoint*)kalmanFilterPoint:(MALonLatPoint*)lastLoc curLoc:(MALonLatPoint*)curLoc { + return [self kalmanFilterPoint:lastLoc curLoc:curLoc intensity:self.intensity]; +} + +/** + * 轨迹抽稀 + * @param inPoints 待抽稀的轨迹list,至少包含两个点,删除垂距小于mThreshhold的点 + * @return 抽稀后的轨迹list + */ +- (NSArray*)reducerVerticalThreshold:(NSArray*)inPoints { + return [self reducerVerticalThreshold:inPoints threshHold:self.threshHold]; +} + +/********************************************************************************************************/ +/** + * 轨迹线路滤波 + * @param originlist 原始轨迹list,list.size大于2 + * @param intensity 滤波强度(1—5) + * @return 滤波后的list + */ +- (NSArray*)kalmanFilterPath:(NSArray*)originlist intensity:(int)intensity { + if (!originlist || originlist.count <= 2) { + return nil; + } + + NSMutableArray* kalmanFilterList = [NSMutableArray array]; + + [self initial];//初始化滤波参数 + + MALonLatPoint* point = nil; + MALonLatPoint* lastLoc = [[MALonLatPoint alloc] init]; + lastLoc.lat = [originlist objectAtIndex:0].lat; + lastLoc.lon = [originlist objectAtIndex:0].lon; + [kalmanFilterList addObject:lastLoc]; + + for (int i = 1; i < originlist.count; i++) { + MALonLatPoint* curLoc = [originlist objectAtIndex:i]; + point = [self kalmanFilterPoint:lastLoc curLoc:curLoc intensity:intensity]; + if (point) { + [kalmanFilterList addObject:point]; + lastLoc = point; + } + } + return kalmanFilterList; +} + +/** + * 单点滤波 + * @param lastLoc 上次定位点坐标 + * @param curLoc 本次定位点坐标 + * @param intensity 滤波强度(1—5) + * @return 滤波后本次定位点坐标值 + */ +- (MALonLatPoint*)kalmanFilterPoint:(MALonLatPoint*)lastLoc curLoc:(MALonLatPoint*)curLoc intensity:(int)intensity { + if (!lastLoc || !curLoc){ + return nil; + } + + if (pdelt_x == 0 || pdelt_y == 0 ){ + [self initial]; + } + + MALonLatPoint* point = nil; + if (intensity < 1){ + intensity = 1; + } else if (intensity > 5){ + intensity = 5; + } + for (int j = 0; j < intensity; j++){ + point = [self kalmanFilter:lastLoc.lon value_x:curLoc.lon oldValue_y:lastLoc.lat value_y:curLoc.lat]; + curLoc = point; + } + return point; +} + + +/***************************卡尔曼滤波开始********************************/ + +//初始模型 +- (void)initial { + pdelt_x = 0.001; + pdelt_y = 0.001; + // mdelt_x = 0; + // mdelt_y = 0; + mdelt_x = 5.698402909980532E-4; + mdelt_y = 5.698402909980532E-4; +} + +- (MALonLatPoint*)kalmanFilter:(double)oldValue_x value_x:(double)value_x oldValue_y:(double)oldValue_y value_y:(double)value_y{ + lastLocation_x = oldValue_x; + currentLocation_x= value_x; + + gauss_x = sqrt(pdelt_x * pdelt_x + mdelt_x * mdelt_x)+m_Q; //计算高斯噪音偏差 + kalmanGain_x = sqrt((gauss_x * gauss_x)/(gauss_x * gauss_x + pdelt_x * pdelt_x)) +m_R; //计算卡尔曼增益 + estimate_x = kalmanGain_x * (currentLocation_x - lastLocation_x) + lastLocation_x; //修正定位点 + mdelt_x = sqrt((1-kalmanGain_x) * gauss_x *gauss_x); //修正模型偏差 + + lastLocation_y = oldValue_y; + currentLocation_y = value_y; + gauss_y = sqrt(pdelt_y * pdelt_y + mdelt_y * mdelt_y)+m_Q; //计算高斯噪音偏差 + kalmanGain_y = sqrt((gauss_y * gauss_y)/(gauss_y * gauss_y + pdelt_y * pdelt_y)) +m_R; //计算卡尔曼增益 + estimate_y = kalmanGain_y * (currentLocation_y - lastLocation_y) + lastLocation_y; //修正定位点 + mdelt_y = sqrt((1-kalmanGain_y) * gauss_y * gauss_y); //修正模型偏差 + + MALonLatPoint *point = [[MALonLatPoint alloc] init]; + point.lon = estimate_x; + point.lat = estimate_y; + + return point; +} +/***************************卡尔曼滤波结束**********************************/ + +/***************************抽稀算法*************************************/ +- (NSArray*)reducerVerticalThreshold:(NSArray*)inPoints threshHold:(float)threshHold { + if(inPoints.count < 2) { + return inPoints; + } + + NSMutableArray *ret = [NSMutableArray arrayWithCapacity:inPoints.count]; + + for(int i = 0; i < inPoints.count; ++i) { + MALonLatPoint *pre = ret.lastObject; + MALonLatPoint *cur = [inPoints objectAtIndex:i]; + + + if (!pre || i == inPoints.count - 1) { + [ret addObject:[inPoints objectAtIndex:i]]; + continue; + } + + MALonLatPoint *next = [inPoints objectAtIndex:(i + 1)]; + + MAMapPoint curP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(cur.lat, cur.lon)); + MAMapPoint prevP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(pre.lat, pre.lon)); + MAMapPoint nextP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(next.lat, next.lon)); + double distance = [self calculateDistanceFromPoint:curP lineBegin:prevP lineEnd:nextP]; + if (distance >= threshHold) { + [ret addObject:cur]; + } + } + + return ret; +} + +- (MALonLatPoint*)getLastLocation:(NSArray*)oneGraspList { + if (!oneGraspList || oneGraspList.count == 0) { + return nil; + } + NSInteger locListSize = oneGraspList.count; + MALonLatPoint* lastLocation = [oneGraspList objectAtIndex:(locListSize - 1)]; + return lastLocation; +} + +/** + * 计算当前点到线的垂线距离 + * @param pt 当前点 + * @param begin 线的起点 + * @param end 线的终点 + * + */ +- (double)calculateDistanceFromPoint:(MAMapPoint)pt + lineBegin:(MAMapPoint)begin + lineEnd:(MAMapPoint)end { + + MAMapPoint mappedPoint; + double dx = begin.x - end.x; + double dy = begin.y - end.y; + if(fabs(dx) < 0.00000001 && fabs(dy) < 0.00000001 ) { + mappedPoint = begin; + } else { + double u = (pt.x - begin.x)*(begin.x - end.x) + + (pt.y - begin.y)*(begin.y - end.y); + u = u/((dx*dx)+(dy*dy)); + + mappedPoint.x = begin.x + u*dx; + mappedPoint.y = begin.y + u*dy; + } + + return MAMetersBetweenMapPoints(pt, mappedPoint); +} +/***************************抽稀算法结束*********************************/ + +- (NSArray*)reduceNoisePoint:(NSArray*)inPoints threshHold:(float)threshHold { + if (!inPoints) { + return nil; + } + if (inPoints.count <= 2) { + return inPoints; + } + + NSMutableArray* ret = [NSMutableArray array]; + for (int i = 0; i < inPoints.count; i++) { + MALonLatPoint* pre = [self getLastLocation:ret]; + MALonLatPoint* cur = [inPoints objectAtIndex:i]; + if (!pre || i == inPoints.count - 1) { + [ret addObject:cur]; + continue; + } + MALonLatPoint* next = [inPoints objectAtIndex:(i + 1)]; + + MAMapPoint curP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(cur.lat, cur.lon)); + MAMapPoint prevP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(pre.lat, pre.lon)); + MAMapPoint nextP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(next.lat, next.lon)); + double distance = [self calculateDistanceFromPoint:curP lineBegin:prevP lineEnd:nextP]; + if (distance < threshHold){ + [ret addObject:cur]; + } + } + return ret; +} + + +@end diff --git a/MRMobileRun/MRRunning/MGDButtonsView.h b/MRMobileRun/MRRunning/MGDButtonsView.h new file mode 100644 index 0000000..cdeab5e --- /dev/null +++ b/MRMobileRun/MRRunning/MGDButtonsView.h @@ -0,0 +1,22 @@ +// +// MGDButtonsView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDButtonsView : UIView +//背景view +@property (nonatomic, strong) UIView *backView; +//完成按钮 +@property (nonatomic, strong) UIButton *overBtn; +//分享按钮 +@property (nonatomic, strong) UIButton *shareBtn; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/MGDButtonsView.m b/MRMobileRun/MRRunning/MGDButtonsView.m new file mode 100644 index 0000000..057880b --- /dev/null +++ b/MRMobileRun/MRRunning/MGDButtonsView.m @@ -0,0 +1,84 @@ +// +// MGDButtonsView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + +#import "MGDButtonsView.h" +#import + +//页面底部的buttonView,完成和分享按钮,两个按钮的点击事件在ViewController中来写 + +@implementation MGDButtonsView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + _backView = [[UIView alloc] init]; + _backView.backgroundColor = [UIColor clearColor]; + _backView.userInteractionEnabled = YES; + [self addSubview:_backView]; + + _overBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + _overBtn.layer.cornerRadius = 12; + //测试颜色 + [_overBtn setBackgroundColor:[UIColor colorWithRed:100/255.0 green:104/255.0 blue:111/255.0 alpha:1.0]]; + [_overBtn setTitle:@"完成" forState:UIControlStateNormal]; + [self.backView addSubview:_overBtn]; + + _shareBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + _shareBtn.layer.cornerRadius = 12; + //测试颜色 + [_shareBtn setBackgroundColor:[UIColor colorWithRed:85/255.0 green:213/255.0 blue:226/255.0 alpha:1.0]]; + [_shareBtn setTitle:@"分享" forState:UIControlStateNormal]; + [_shareBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [self.backView addSubview:_shareBtn]; + + + if (@available(iOS 11.0, *)) { + [self.overBtn setTitleColor:OverColor forState:UIControlStateNormal]; + [self.overBtn setBackgroundColor:OverBackColor]; + } else { + // Fallback on earlier versions + } + } + return self; +} + +- (void)layoutSubviews { + if (kIs_iPhoneX) { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth * 0.3497); + }]; + + }else { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth * 0.262); + }]; + + } + [_overBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.015); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.048); + make.width.mas_equalTo(screenWidth * 0.4373); + make.height.equalTo(@44); + }]; + + [_shareBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.overBtn); + make.left.mas_equalTo(self.overBtn.mas_right).mas_offset(screenWidth * 0.0293); + make.right.mas_equalTo(self.mas_right).mas_offset(-(screenWidth * 0.048)); + make.height.mas_equalTo(self.overBtn); + }]; +} + + + +@end + diff --git a/MRMobileRun/MRRunning/MGDCellDataViewController.h b/MRMobileRun/MRRunning/MGDCellDataViewController.h new file mode 100644 index 0000000..20d83ce --- /dev/null +++ b/MRMobileRun/MRRunning/MGDCellDataViewController.h @@ -0,0 +1,52 @@ +// +// MGDCellDataViewController.h +// MRMobileRun +// +// Created by 阿栋 on 2020/8/13. +// + +#import +#import "MGDOverView.h" +#import "MGDDataView.h" +#import "MGDButtonsView.h" +#import "MGDShareView.h" +#import "MGDShareDataView.h" +NS_ASSUME_NONNULL_BEGIN + +API_AVAILABLE(ios(12.0)) +@interface MGDCellDataViewController : UIViewController + +@property (nonatomic, strong) NSString *userIconStr; +@property (nonatomic, strong) NSString *userNmaeStr; +@property (nonatomic, strong) NSString *distanceStr; //距离 +@property (nonatomic, strong) NSString *speedStr; //配速 +@property (nonatomic, strong) NSString *stepFrequencyStr; //步频 +@property (nonatomic, strong) NSString *timeStr; //跑步时间 +@property (nonatomic, strong) NSString *energyStr;//千卡 +@property (nonatomic, strong) NSString *date; //日期 +@property (nonatomic, strong) NSString *time; //时间 +@property (nonatomic, strong) NSString *MaxStepFrequency; //最大步频 +@property (nonatomic, strong) NSString *MaxSpeed; //最大速度 +@property (nonatomic, strong) NSString *degree; //温度 + +@property (nonatomic, strong) NSArray *locationAry; //毛国栋页面采集到的所有位置数据 + +@property (nonatomic, strong) NSArray *speedArray; //毛国栋页面得到的网络速度数据 +@property (nonatomic, strong) NSArray *stepFrequencyArray; //毛国栋页面得到的网络步频数据 + + +@property (nonatomic ,strong) UIScrollView *backScrollView; + +@property (nonatomic ,strong) MGDOverView *overView; + +@property (nonatomic ,strong) MGDDataView *dataView; + +@property (nonatomic ,strong) MGDButtonsView *twoBtnView; + +@property (nonatomic ,strong) MGDShareView *shareView; + +@property (nonatomic ,strong) MGDShareDataView *shareDataView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/MGDCellDataViewController.m b/MRMobileRun/MRRunning/MGDCellDataViewController.m new file mode 100644 index 0000000..5b08b4a --- /dev/null +++ b/MRMobileRun/MRRunning/MGDCellDataViewController.m @@ -0,0 +1,721 @@ +// +// MGDCellDataViewController.m +// MRMobileRun +// +// Created by 阿栋 on 2020/8/13. +// + +#import "MGDCellDataViewController.h" +#import +#import +#import +#import +#import +#import +#import +#import + +#import "MGDShareDataView.h" +#import "RunLocationModel.h" +#import "SZHWaveChart.h" //步频折线图 +#import "SZHChart.h"//速度折线图 +#import "MASmoothPathTool.h" //用来处理轨迹的工具类 +#import "MGDDataViewController.h" +#import "RunLocationModel.h" +#import "MASmoothPathTool.h" +#import "UIImageView+WebCache.h" +#import "ZYLMainViewController.h" +#import "MRTabBarController.h" + +@interface MGDCellDataViewController () +@property (nonatomic, strong) AMapLocationManager *ALocationManager; +@property (nonatomic, strong) NSArray *origTracePoints; //原始轨迹测绘坐标点 +@property (nonatomic, strong) NSArray *smoothedTracePoints; //平滑处理用的轨迹数组点 +@property (nonatomic, strong) MAPolyline *smoothedTrace; + +//大头针 +@property (nonatomic, strong) MAPointAnnotation *beginAnnotataion; +@property (nonatomic, strong) MAPointAnnotation *endAnnotataion; + +@property (nonatomic, strong) NSArray *originalSpeedAry; //原始的速度数组 +@property (nonatomic, strong) NSArray *originalStepsAry; //原始的步频数组 +@property (nonatomic, strong) NSArray *caculateSpeedAry; //处理后的速度数组 +@property (nonatomic, strong) NSArray *caculateStepsAry; //处理后的步频数组 +@property int maxStepFrequenceLatest; //经丢弃处理后的步频数组里最大的速度 +@property double maxSpeedLatest; //经丢弃处理后的速度数组里最大的速度 +@property (nonatomic, strong) NSArray *originalLocationAry; //原始的位置数组 + +@property long int totelMinutes; //总的跑步时间分钟数 +//@property double maxSpeedLatest; +@property __block UIImage *shareImage; +@end + +@implementation MGDCellDataViewController + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + self.tabBarController.tabBar.hidden = YES; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self.navigationController setNavigationBarHidden:YES animated:YES]; //隐藏导航栏 + [self fit]; + [self initLocationManager]; + + //关于一些初始化 + self.originalSpeedAry = [NSArray array]; + self.originalStepsAry = [NSArray array]; + self.caculateSpeedAry = [NSArray array]; + self.caculateStepsAry = [NSArray array]; + self.originalLocationAry = [NSArray array]; + self.maxSpeedLatest = 0; + + self.overView.kmLab.text = self.distanceStr; //跑步距离赋值 + self.overView.speedLab.text = self.speedStr; //配速赋值 + self.overView.timeLab.text = self.timeStr; //跑步时间赋值 + self.overView.calLab.text = self.energyStr; //燃烧千卡赋值 + self.overView.paceLab.text = self.stepFrequencyStr; //步频 + self.overView.date.text = self.date; //日期 + self.overView.currentTime.text = self.time; //时间 + self.overView.degree.text = self.degree; //温度 + self.dataView.speedLab.text = self.MaxSpeed; //最大速度 + self.dataView.paceLab.text = self.MaxStepFrequency; //最大步频 + + self.overView.mapView.delegate = self; //设置地图代理 + + /** + 处理速度、步频、位置数组 + */ + [self separateString]; + [self discardPointsProcess]; //将速度、步频点进行丢弃处理 + + // 步频、速度两个图表 + [self addTwoCharts]; + + /** + 绘制轨迹 + */ + //初始化原始数据数组和处理后的数组 + self.origTracePoints = [NSArray array]; + [self loadTrancePoints]; + + //绘制始终位置大头针 + [self initBeginAndEndAnnotations]; + + // 给分享界面添加手势 + UITapGestureRecognizer *backGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(backevent:)]; + backGesture.delegate = self; + [self.shareView.backView addGestureRecognizer:backGesture]; + + //设置地图中心 + RunLocationModel *model3 = self.originalLocationAry.lastObject; + CLLocationCoordinate2D centerCL = model3.location; + [self.overView.mapView setCenterCoordinate:centerCL]; + self.overView.mapView.zoomLevel = 15; + self.overView.mapView.userInteractionEnabled = YES; + [self.ALocationManager stopUpdatingLocation]; //最后停止定位 + self.overView.mapView.showsUserLocation = NO; //不显示用户的位置 + + //设置右滑返回的手势 + id target = self.navigationController.interactivePopGestureRecognizer.delegate; + UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)]; + panGesture.delegate = self; //设置手势代理,拦截手势触发 + [self.view addGestureRecognizer:panGesture]; + self.navigationController.interactivePopGestureRecognizer.enabled = NO; //禁止系统自带的滑动手势 + + +} + +- (void)handleNavigationTransition:(UIPanGestureRecognizer *)pan { + NSLog(@"右滑返回"); //自定义滑动手势 +} + + +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { + // 当当前控制器是根控制器时,不可以侧滑返回,所以不能使其触发手势 + if(self.navigationController.childViewControllers.count == 1) { + return NO; + } + return YES; +} + + //适配各个View的深色模式以及页面布局 +- (void)fit{ + //适配深色模式 + _backScrollView = [[UIScrollView alloc] init]; + if (@available(iOS 11.0, *)) { + self.view.backgroundColor = bottomColor; + _backScrollView.contentInsetAdjustmentBehavior = UIApplicationBackgroundFetchIntervalNever; + } else { + // Fallback on earlier versions + } + + //根据机型进行控件布局 + if (kIs_iPhoneX) { + _backScrollView.frame = CGRectMake(0, 0, screenWidth, screenHeigth - 100); + + _twoBtnView = [[MGDButtonsView alloc] initWithFrame:CGRectMake(0, screenHeigth - 100, screenWidth, 100)]; + + _dataView = [[MGDDataView alloc] initWithFrame:CGRectMake(0, screenHeigth - 100 + 10, screenWidth, 710 + 35)]; + }else { + _backScrollView.frame = CGRectMake(0, 0, screenWidth, screenHeigth - 66); + + _twoBtnView = [[MGDButtonsView alloc] initWithFrame:CGRectMake(0, screenHeigth - 66, screenWidth, 66)]; + + _dataView = [[MGDDataView alloc] initWithFrame:CGRectMake(0, screenHeigth - 66 + 50, screenWidth, 710 + 35)]; + + } + + //两个butto的View + [_twoBtnView.overBtn addTarget:self action:@selector(Back) forControlEvents:UIControlEventTouchUpInside]; + [_twoBtnView.shareBtn addTarget:self action:@selector(share) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:_twoBtnView]; + + if (kIs_iPhoneX) { + _backScrollView.contentSize = CGSizeMake(screenWidth, screenHeigth + 610); + }else { + _backScrollView.contentSize = CGSizeMake(screenWidth, screenHeigth + 699); + } + [self.view addSubview:_backScrollView]; + + //地图下,统计图上的View,配速、时间、燃烧千卡等label的数据 + _overView = [[MGDOverView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeigth)]; + [self.backScrollView addSubview:_overView]; + self.overView.mapView.delegate = self; + + //绘制统计图的View + [self.backScrollView addSubview:_dataView]; + + //更改地图的样式 + if (@available(iOS 13.0, *)) { + UIUserInterfaceStyle mode = UITraitCollection.currentTraitCollection.userInterfaceStyle; + if (mode == UIUserInterfaceStyleDark) { + NSLog(@"深色模式"); + NSString *path = [[NSBundle mainBundle] pathForResource:@"style" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.overView.mapView setCustomMapStyleOptions:options]; + [self.overView.mapView setCustomMapStyleEnabled:YES]; + } else if (mode == UIUserInterfaceStyleLight) { + NSLog(@"浅色模式"); + NSString *path = [[NSBundle mainBundle] pathForResource:@"style2" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.overView.mapView setCustomMapStyleOptions:options]; + [self.overView.mapView setCustomMapStyleEnabled:YES]; + } else { + NSLog(@"未知模式"); + } + } +} + +//处理从毛国栋传过来的位置、步频、速度数组,将其变为可用的原始数组 +- (void)separateString{ + //速度数组 + NSMutableArray *muteSpeedAry = [NSMutableArray array]; + if (self.speedArray != nil) { + for (int i = 0; i < self.speedArray.count; i++) { + NSString *string = self.speedArray[i]; + NSArray *array = [string componentsSeparatedByString:@","];//根据逗号分割字符串 + NSString *string2 = array[1]; + double speed = [string2 doubleValue]; + //逻辑处理,当速度大于等于0且小于9.97m/s才加入原始可用的速度数组 + if (speed >= 0 && speed < 9.97) { + [muteSpeedAry addObject:string2]; + } + } + self.originalSpeedAry = muteSpeedAry; + NSLog(@"原始的速度数组为%@",self.originalSpeedAry); + } + + + //步频数组 + NSMutableArray *muteStepsAry = [NSMutableArray array]; + if (self.stepFrequencyArray != nil) { + for (int i = 0; i < self.stepFrequencyArray.count; i++) { + NSString *string = self.stepFrequencyArray[i]; + NSArray *array = [string componentsSeparatedByString:@","];//根据逗号分割字符串 + NSString *string2 = array[1]; + [muteStepsAry addObject:string2]; + } + self.originalStepsAry = muteStepsAry; + NSLog(@"原始的步频数组为%@",self.originalStepsAry); + } + + + // //位置数组 + //去除其中的(-1,-1)的坐标点 + NSMutableArray *dealLocationArray = [NSMutableArray arrayWithArray:self.locationAry]; + for (int i = 0; i < dealLocationArray.count; i++) { + NSString *string = dealLocationArray[i]; + if ([string isEqualToString:@"-1,-1"]) { + [dealLocationArray removeObject:string]; + } + } + //将字符串转换为坐标 + NSMutableArray *muteLocationAry = [NSMutableArray array]; + for (int i = 0; i < dealLocationArray.count; i++) { + NSString *string = dealLocationArray[i]; + NSArray *array = [string componentsSeparatedByString:@","];//根据逗号分割字符串 + double lat = [array[0] doubleValue]; + double lon = [array[1] doubleValue]; + RunLocationModel *model = [[RunLocationModel alloc] init]; + model.location = CLLocationCoordinate2DMake(lat, lon); + [muteLocationAry addObject:model]; + } + self.originalLocationAry = muteLocationAry; + + NSLog(@"未处理的位置数组为%@",self.locationAry); +} + +//将可用的速度、步频原始数组进行丢弃点处理 +- (void)discardPointsProcess{ + //步频数组的丢弃点处理 + //初始化处理 + self.maxStepFrequenceLatest = 0; + self.totelMinutes = 0; + + NSMutableArray *stepsMuteAry = [NSMutableArray array]; + self.totelMinutes = self.originalStepsAry.count; //获取总的跑步时间数 + NSLog(@"跑步的总时间数为%ld",self.totelMinutes); + if (self.originalStepsAry.count != 0) { + //五分钟画一个点 + for (int i = 0; i < self.originalStepsAry.count; i += 4) { + NSString *stepStr = self.originalStepsAry[i]; + [stepsMuteAry addObject:stepStr]; + //在步频丢弃点数组内得到最高的步频并赋值 + int stepFrequence = [stepStr intValue]; + if (self.maxStepFrequenceLatest < stepFrequence) { + self.maxStepFrequenceLatest = stepFrequence; + } + } + self.caculateStepsAry = stepsMuteAry; + self.dataView.paceLab.text = [[NSNumber numberWithInt:self.maxStepFrequenceLatest] stringValue]; //最大步频赋值 + NSLog(@"处理后的步频数组为%@",self.caculateStepsAry); + } + + + + //原始可用的速度数组的丢弃点处理 + self.maxSpeedLatest = 0; + if (self.originalSpeedAry.count != 0) { + NSMutableArray *speedMuteAry = [NSMutableArray array]; + //得到大概每分钟打多少个点 + long int space = 0; + if (self.totelMinutes >= 0) { + space = self.originalSpeedAry.count/self.totelMinutes; + } +// NSLog(@"跑步的总时间数为%ld",space); + //大概每隔两分半在统计图上画一个点 + for (int i = 0; i < self.originalSpeedAry.count; i += 4 ) { + NSString *speedStr = self.originalSpeedAry[i]; + [speedMuteAry addObject:speedStr]; + //得到丢弃处理后的速度数组内的最大速度 + double speed = [speedStr doubleValue]; + if (self.maxSpeedLatest < speed) { + self.maxSpeedLatest = speed; + } + } + self.caculateSpeedAry = speedMuteAry; + self.dataView.speedLab.text = [NSString stringWithFormat:@"%0.2f",self.maxSpeedLatest];; //最大速度 +// NSLog(@"处理后的速度数组中最大的数值为%f",self.maxSpeedLatest); + NSLog(@"处理后的速度数组为%@",self.caculateSpeedAry); + } +} + +//添加两个图表 +- (void)addTwoCharts{ + + //画步频的波浪图 + if (self.caculateStepsAry.count != 0) { + //步频的波浪图 + NSArray *paceArray = @[@130,@140,@152,@180,@200,@148,@132,@98]; + SZHWaveChart *paceWaveChart = [[SZHWaveChart alloc] init]; + [paceWaveChart initWithViewsWithBooTomCount:self.caculateStepsAry.count AndLineDataAry:self.caculateStepsAry AndYMaxNumber:250]; +// [paceWaveChart initWithViewsWithBooTomCount:paceArray.count AndLineDataAry:paceArray AndYMaxNumber:250]; + [self.dataView.paceBackView addSubview:paceWaveChart]; + [paceWaveChart mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.dataView.paceBackView); + make.height.mas_equalTo(245); + }]; + paceWaveChart.topYlabel.text = @"步/分"; + paceWaveChart.bottomXLabel.text = @"分钟"; + for (int i = 0; i < paceWaveChart.leftLblAry.count; i++) { + UILabel *label = paceWaveChart.leftLblAry[i]; + label.text = [NSString stringWithFormat:@"%d",(i+1) * 50]; + } + } + + NSLog(@"原始可用的速度数组个数为%lu",(unsigned long)self.caculateSpeedAry.count); + if (self.caculateSpeedAry.count != 0) { + //速度的折线图 + NSArray *array = @[@3,@4.8,@4,@3.8,@4,@4.3,@4.5,@3.7]; + SZHChart *speedChart = [[SZHChart alloc] init]; + [speedChart initWithViewsWithBooTomCount:self.caculateSpeedAry.count/5 AndLineDataAry:self.caculateSpeedAry AndYMaxNumber:6]; +// [speedChart initWithViewsWithBooTomCount:array.count AndLineDataAry:array AndYMaxNumber:6]; + [self.dataView.speedBackView addSubview:speedChart]; + [speedChart mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.dataView.speedBackView); + make.height.mas_equalTo(245); + }]; + speedChart.topYlabel.text = @"米/秒"; + speedChart.bottomXLabel.text = @"分钟"; + for (int i = 0; i < speedChart.leftLblAry.count; i++) { + UILabel *label = speedChart.leftLblAry[i]; + label.text = [NSString stringWithFormat:@"%d", i + 2]; + } + } +} + +- (void)Back{ + [self.navigationController popViewControllerAnimated:YES]; +} + +- (void)share { + _shareView = [[MGDShareView alloc] initWithShotImage:@"" logoImage:@"" QRcodeImage:@""]; + [self.view addSubview:_shareView]; + [_shareView.cancelBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; + [self shareAction]; + // 分享界面的地图截图 + CGRect inRect = self.overView.mapView.frame; + [self.overView.mapView takeSnapshotInRect:inRect withCompletionBlock:^(UIImage *resultImage, NSInteger state) { + state = 1; + self.shareImage = resultImage; + self.shareView.shotImage.image = self.shareImage; + }]; + self->_shareDataView = [[MGDShareDataView alloc] init]; + [self.shareDataView.userIcon sd_setImageWithURL:[NSURL URLWithString:self.userIconStr] placeholderImage:[UIImage imageNamed:@"logo头像"]]; + self.shareDataView.userName.text = self.userNmaeStr; + self.shareDataView.kmLab.text = self.distanceStr; //跑步距离赋值 + self.shareDataView.speedLab.text = self.speedStr; //配速赋值 + self.shareDataView.timeLab.text = self.timeStr; //跑步时间赋值 + self.shareDataView.calLab.text = self.energyStr; //燃烧千卡赋值 + self.shareDataView.paceLab.text = self.stepFrequencyStr; //步频 + self.shareDataView.date.text = self.date; //日期 + self.shareDataView.currentTime.text = self.time; //时间 + self.shareDataView.speedLab.text = self.MaxSpeed; //最大速度 + self.shareDataView.paceLab.text = self.MaxStepFrequency; //最大步频 + [self.shareView.dataView addSubview:_shareDataView]; + + UILongPressGestureRecognizer *QrCodeTap = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(qrCodeLongPress:)]; + self.shareView.QRImage.userInteractionEnabled = YES; + [self.shareView.QRImage addGestureRecognizer:QrCodeTap]; +} + +//暂时未放二维码 +- (void)qrCodeLongPress:(UILongPressGestureRecognizer *)longPress { + //创建上下文context + CIContext *context = [[CIContext alloc] init]; + //创建探测器 + CIDetector *QRCodeDetector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:context options:@{CIDetectorAccuracy: CIDetectorAccuracyLow}]; + //识别图片,获取特征 + CIImage *imgCI = [[CIImage alloc] initWithImage:self.shareView.QRImage.image]; + NSArray *features = [QRCodeDetector featuresInImage:imgCI]; + + //判断是否识别到二维码 + if (features.count > 0) { + + //有二维码 + CIQRCodeFeature *qrcodeFeature = (CIQRCodeFeature *)features[0]; + + __weak typeof(self) weakSelf = self; + UIAlertController *sheet = [UIAlertController alertControllerWithTitle:@"" message:@"识别内容" preferredStyle:UIAlertControllerStyleActionSheet]; + UIAlertAction *dicern = [UIAlertAction actionWithTitle:@"识别图中二维码" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { + + UIViewController *resultVC = [[UIViewController alloc] init]; + [weakSelf.navigationController pushViewController:resultVC animated:YES]; + + }]; + UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { + }]; + + [sheet addAction:dicern]; + [sheet addAction:cancel]; + [self presentViewController:sheet animated:YES completion:nil]; + + }else{ + + //没有二维码,这只是一张普通的图片 + NSLog(@"|没有二维码,这只是一张普通的图片|"); + } + +} + + + +- (void)back { + [UIView animateWithDuration:0.3 animations:^{ + [self.shareView removeFromSuperview]; + }]; +} + +////处理从毛国栋传过来的位置、步频、速度数组 +//- (void)separateString{ +// //速度数组 +// NSMutableArray *muteSpeedAry = [NSMutableArray array]; +// for (int i = 0; i < self.speedArray.count; i++) { +// NSString *string = self.speedArray[i]; +// NSArray *array = [string componentsSeparatedByString:@","];//根据逗号分割字符串 +// NSString *string2 = array[1]; +// [muteSpeedAry addObject:string2]; +// } +// self.originalSpeedAry = muteSpeedAry; +// NSLog(@"原始的速度数组为%@",self.originalSpeedAry); +// +// //步频数组 +// NSMutableArray *muteStepsAry = [NSMutableArray array]; +// for (int i = 0; i < self.stepFrequencyArray.count; i++) { +// NSString *string = self.stepFrequencyArray[i]; +// NSArray *array = [string componentsSeparatedByString:@","];//根据逗号分割字符串 +// NSString *string2 = array[1]; +// [muteStepsAry addObject:string2]; +// } +// self.originalStepsAry = muteStepsAry; +// NSLog(@"原始的步频数组为%@",self.originalStepsAry); +// +// // //位置数组 +// //去除其中的(-1,-1)的坐标点 +// NSMutableArray *dealLocationArray = [NSMutableArray arrayWithArray:self.locationAry]; +// for (int i = 0; i < dealLocationArray.count; i++) { +// NSString *string = dealLocationArray[i]; +// if ([string isEqualToString:@"-1,-1"]) { +// [dealLocationArray removeObject:string]; +// } +// } +// //将字符串转换为坐标 +// NSMutableArray *muteLocationAry = [NSMutableArray array]; +// for (int i = 0; i < dealLocationArray.count; i++) { +// NSString *string = dealLocationArray[i]; +// NSArray *array = [string componentsSeparatedByString:@","];//根据逗号分割字符串 +// double lat = [array[0] doubleValue]; +// double lon = [array[1] doubleValue]; +// RunLocationModel *model = [[RunLocationModel alloc] init]; +// model.location = CLLocationCoordinate2DMake(lat, lon); +// [muteLocationAry addObject:model]; +// } +// self.originalLocationAry = muteLocationAry; +// +// NSLog(@"未处理的位置数组为%@",self.locationAry); +//} + +#pragma mark- 位置管理者 +- (void)initLocationManager{ + self.ALocationManager = [[AMapLocationManager alloc] init]; + self.ALocationManager.delegate = self; + self.ALocationManager.allowsBackgroundLocationUpdates = YES; //开启后台定位 + self.ALocationManager.distanceFilter = 5; //设置移动精度 + self.ALocationManager.locationTimeout = 2; //定位超时时间 + [self.ALocationManager setLocatingWithReGeocode:YES]; + [self.ALocationManager startUpdatingLocation]; + + // 延迟执行取消定位操作 + __weak typeof(self) weakSelf = self; + dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)); + dispatch_after(delayTime, dispatch_get_main_queue(), ^{ + [weakSelf.ALocationManager stopUpdatingLocation]; + }); + +} + +#pragma mark- 轨迹相关 + //因为CLLocationCoordinate2D为只读属性,无法用可变数组直接addobject储存,所以需要以下转化 +- (void)loadTrancePoints{ + CLLocationCoordinate2D lineCoordinates[self.originalLocationAry.count]; + for (int i = 0; i < self.originalLocationAry.count; i++) { + RunLocationModel *model = self.originalLocationAry[i]; + lineCoordinates[i] = model.location; + } + self.smoothedTrace = [MAPolyline polylineWithCoordinates:lineCoordinates count:self.originalLocationAry.count]; + [self.overView.mapView addOverlay:self.smoothedTrace]; +} + +//自定义轨迹线 +- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id)overlay{ + if ([overlay isKindOfClass:[MAPolyline class]]) { + MAPolylineRenderer *polyLineRender = [[MAPolylineRenderer alloc] initWithPolyline:overlay]; + polyLineRender.lineWidth = 8; + polyLineRender.strokeColor = [UIColor colorWithRed:123/255.0 green:183/255.0 blue:196/255.0 alpha:1.0]; //折线颜色 + return polyLineRender; + } + return nil; +} + +#pragma mark- 大头针 + //设置开始,结束位置的大头针 +- (void)initBeginAndEndAnnotations{ + //开始地点 + MAPointAnnotation *beginAnnotation = [[MAPointAnnotation alloc] init]; + RunLocationModel *beginModel = self.originalLocationAry.firstObject; + beginAnnotation.coordinate = beginModel.location; + self.beginAnnotataion = beginAnnotation; + [self.overView.mapView addAnnotation:self.beginAnnotataion]; + + //结束地点 + MAPointAnnotation *endAnnotation = [[MAPointAnnotation alloc] init]; + RunLocationModel *endModel = self.originalLocationAry.lastObject; + endAnnotation.coordinate = endModel.location; + self.endAnnotataion = endAnnotation; + [self.overView.mapView addAnnotation:self.endAnnotataion]; +} + + //设置开始、结束位置大头针的样式 +- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation{ + if ([annotation isKindOfClass:[MAPointAnnotation class]]){ + if (annotation == self.beginAnnotataion) { + static NSString *pointReuseIndentifier = @"pointReuseIndentifier"; + MAPinAnnotationView*annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndentifier]; + if (annotationView == nil){ + annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndentifier]; + } + annotationView.image = [UIImage imageNamed:@"startPointImage"]; + annotationView.animatesDrop = NO; //设置标注动画显示,默认为NO + annotationView.canShowCallout= NO; //设置气泡可以弹出,默认为NO + annotationView.draggable = NO; //设置不可被拖动 + return annotationView; + }else if(annotation == self.endAnnotataion){ + static NSString *end = @"end"; + MAPinAnnotationView*annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:end]; + if (annotationView == nil){ + annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:end]; + } + annotationView.image = [UIImage imageNamed:@"endPointImage"]; + annotationView.animatesDrop = NO; //设置标注动画显示,默认为NO + annotationView.canShowCallout= NO; //设置气泡可以弹出,默认为NO + annotationView.draggable = NO; //设置不可被拖动 + return annotationView; + } + } + return nil; +} + +#pragma mark- 定位回调方法 +- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation{ + CGFloat signal = userLocation.location.horizontalAccuracy; + + if(!updatingLocation) + return ; + + if (signal < 0) + { + return ; + } +} + +- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode{ + CGFloat signal = location.horizontalAccuracy; + if (signal < 0) + { + return ; + } +} + +#pragma mark- 分享的五个按钮的方法 +- (void)shareAction{ + for (int i = 0; i < self.shareView.bootomBtns.count; i++) { + UIButton *btn = [self.shareView.bootomBtns objectAtIndex:i]; + switch (btn.tag) { + case 1: + [btn addTarget:self action:@selector(savePhotoAtLocalAlbum) forControlEvents:UIControlEventTouchUpInside]; + break; + + default: + break; + } + } +} + +//保存截图到本地 +- (void)savePhotoAtLocalAlbum{ + CGRect inRect = self.overView.mapView.frame; + [self.overView.mapView takeSnapshotInRect:inRect withCompletionBlock:^(UIImage *resultImage, NSInteger state) { + state = 1; + + }]; + //截取指定区域的屏幕 + UIImage *imageRet = [[UIImage alloc]init]; + UIGraphicsBeginImageContextWithOptions(self.shareView.popView.frame.size, false, 0.0); + [self.shareView.popView.layer renderInContext:UIGraphicsGetCurrentContext()]; + imageRet = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + +// UIImageView *image123 = [[UIImageView alloc] init]; +// image123.frame = CGRectMake(100, 100, 200, 200); +// image123.backgroundColor = [UIColor redColor]; +// image123.image = imageRet; +// [self.view addSubview:image123]; + //保存截图到本地 +// UIImageWriteToSavedPhotosAlbum(imageRet, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); + UIImageWriteToSavedPhotosAlbum(imageRet, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL); +} +// // 保存图片到相册的回调方法 +- (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void*) contextInfo{ + + NSString *msg = nil ; + if(error != NULL){ + msg = @"保存图片失败" ; + }else{ + msg = @"保存图片成功"; + } + +UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"保存图片结果提示" message:msg + delegate:self + cancelButtonTitle:@"确定" + otherButtonTitles:nil]; +[alert show]; +} + +#pragma mark-关于两个位置管理者的定位代理方法:实现后台定位 + +- (void)amapLocationManager:(AMapLocationManager *)manager doRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} +- (void)mapViewRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} + +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{ + [super traitCollectionDidChange: previousTraitCollection]; + if (@available(iOS 13.0, *)) { + if([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]){ + if (@available(iOS 13.0, *)) { + UIUserInterfaceStyle mode = UITraitCollection.currentTraitCollection.userInterfaceStyle; + if (mode == UIUserInterfaceStyleDark) { + NSLog(@"深色模式"); + //设置深色模式下的自定义地图样式 + NSString *path = [[NSBundle mainBundle] pathForResource:@"style" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.overView.mapView setCustomMapStyleOptions:options]; + [self.overView.mapView setCustomMapStyleEnabled:YES]; + + } else if (mode == UIUserInterfaceStyleLight) { + NSLog(@"浅色模式"); + //设置浅色模式下的自定义地图样式 + NSString *path = [[NSBundle mainBundle] pathForResource:@"style2" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.overView.mapView setCustomMapStyleOptions:options]; + [self.overView.mapView setCustomMapStyleEnabled:YES]; + + } else { + NSLog(@"未知模式"); + } + } + } + } else { + // Fallback on earlier versions + } +} + + +- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo { + if (!error) { + NSLog(@"保存成功"); + } +} +@end diff --git a/MRMobileRun/MRRunning/MGDDataView.h b/MRMobileRun/MRRunning/MGDDataView.h new file mode 100644 index 0000000..ea15b34 --- /dev/null +++ b/MRMobileRun/MRRunning/MGDDataView.h @@ -0,0 +1,37 @@ +// +// MGDDataView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDDataView : UIView +//这个文件是两个图表,速度和步频,大的UIView套上两个小的UIView + +//文字 +@property (nonatomic, strong) UILabel *pace; +@property (nonatomic, strong) UILabel *speed; +@property (nonatomic, strong) UILabel *paceLab; +@property (nonatomic, strong) UILabel *speedLab; +@property (nonatomic, strong) UILabel *descSpeed; +@property (nonatomic, strong) UILabel *descPace; +//圆点 +@property (nonatomic, strong) UIView *speedDotView; +@property (nonatomic, strong) UIView *paceDotView; + +//整体背景 +@property (nonatomic, strong) UIView *backView; + +//速度背景View +@property (nonatomic, strong) UIView *speedBackView; + +//步频背景View +@property (nonatomic, strong) UIView *paceBackView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/MGDDataView.m b/MRMobileRun/MRRunning/MGDDataView.m new file mode 100644 index 0000000..add2db9 --- /dev/null +++ b/MRMobileRun/MRRunning/MGDDataView.m @@ -0,0 +1,177 @@ +// +// MGDDataView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + +#import "MGDDataView.h" +#import +#define DOTCOLOR [UIColor colorWithRed:123/255.0 green:183/255.0 blue:196/255.0 alpha:1.0] +#define DESCCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] + +@implementation MGDDataView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + + //整体View + _backView = [[UIView alloc] init]; + _backView.backgroundColor = [UIColor clearColor]; + [self addSubview:_backView]; + + //速度View + _speedBackView = [[UIView alloc] init]; + _speedBackView.backgroundColor = [UIColor clearColor]; + [self.backView addSubview:_speedBackView]; + + //速度View上的控件 + _speedDotView = [[UIView alloc] init]; + _speedDotView.backgroundColor = DOTCOLOR; + _speedDotView.layer.masksToBounds = YES; + _speedDotView.layer.cornerRadius = 4.0; + [self.speedBackView addSubview:_speedDotView]; + + _speed = [[UILabel alloc] init]; + _speed.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _speed.textAlignment = NSTextAlignmentLeft; + _speed.text = @"速度"; + [self.speedBackView addSubview:_speed]; + + _speedLab = [[UILabel alloc] init]; + _speedLab.font = [UIFont fontWithName:@"Impact" size: 28]; + _speedLab.textAlignment = NSTextAlignmentCenter; + [self.speedBackView addSubview:_speedLab]; + + _descSpeed = [[UILabel alloc] init]; + _descSpeed.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 11]; + _descSpeed.textAlignment = NSTextAlignmentCenter; + _descSpeed.tintColor = DESCCOLOR; + _descSpeed.text = @"最快速度"; + [self.speedBackView addSubview:_descSpeed]; + + //步频View + _paceBackView = [[UIView alloc] init]; + _paceBackView.backgroundColor = [UIColor clearColor]; + [self.backView addSubview:_paceBackView]; + + //步频View上的控件 + _paceDotView = [[UIView alloc] init]; + _paceDotView.backgroundColor = DOTCOLOR; + _paceDotView.layer.masksToBounds = YES; + _paceDotView.layer.cornerRadius = 4.0; + [self.paceBackView addSubview:_paceDotView]; + + _pace = [[UILabel alloc] init]; + _pace.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _pace.textAlignment = NSTextAlignmentLeft; + _pace.text = @"步频"; + [self.paceBackView addSubview:_pace]; + + _paceLab = [[UILabel alloc] init]; + _paceLab.font = [UIFont fontWithName:@"Impact" size: 28]; + _paceLab.textAlignment = NSTextAlignmentCenter; + [self.paceBackView addSubview:_paceLab]; + + _descPace = [[UILabel alloc] init]; + _descPace.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 11]; + _descPace.textAlignment = NSTextAlignmentCenter; + _descPace.text = @"最高步频"; + _descPace.tintColor = DESCCOLOR; + [self.paceBackView addSubview:_descPace]; + + //颜色适配 + if (@available(iOS 11.0, *)) { + self.speedLab.tintColor = bottomTitleColor; + self.paceLab.tintColor = bottomTitleColor; + self.pace.tintColor = bottomTitleColor; + self.speed.tintColor = bottomTitleColor; + } else { + // Fallback on earlier versions + } + } + return self; +} + +//位置约束 +- (void)layoutSubviews { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(@610); + }]; + + [_paceBackView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.equalTo(@308); + }]; + + [_speedBackView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.paceBackView.mas_bottom).mas_offset(50); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.equalTo(@310); + }]; + + [_speedDotView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedBackView.mas_top).mas_offset(7); + make.left.mas_equalTo(self.speedBackView.mas_left).mas_offset(15); + make.width.equalTo(@8); + make.height.equalTo(@8); + }]; + + [_paceDotView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.paceBackView.mas_top).mas_offset(7); + make.left.mas_equalTo(self.paceBackView.mas_left).mas_offset(15); + make.width.equalTo(@8); + make.height.equalTo(@8); + }]; + + [_speed mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedBackView.mas_top); + make.left.mas_equalTo(self.speedBackView.mas_left).mas_offset(29); + make.width.equalTo(@32); + make.height.equalTo(@22); + }]; + + [_pace mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.paceBackView.mas_top); + make.left.mas_equalTo(self.paceBackView.mas_left).mas_offset(29); + make.width.equalTo(@32); + make.height.equalTo(@22); + }]; + + [_speedLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed.mas_bottom); + make.left.mas_equalTo(self.speedBackView.mas_left).mas_offset(screenWidth * 0.3813); + make.right.mas_equalTo(self.speedBackView.mas_right).mas_offset(-screenWidth * 0.3786); + make.height.equalTo(@34); + }]; + + [_paceLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.pace.mas_bottom); + make.left.mas_equalTo(self.paceBackView.mas_left).mas_offset(screenWidth * 0.3866); + make.right.mas_equalTo(self.paceBackView.mas_right).mas_offset(-screenWidth * 0.3733); + make.height.equalTo(@34); + }]; + + [_descSpeed mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab.mas_bottom); + make.left.mas_equalTo(self.speedBackView.mas_left).mas_offset(screenWidth * 0.4026); + make.right.mas_equalTo(self.speedBackView.mas_right).mas_offset(-screenWidth * 0.40); + make.height.equalTo(@16); + }]; + + [_descPace mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.paceLab.mas_bottom); + make.left.mas_equalTo(self.speedBackView.mas_left).mas_offset(screenWidth * 0.4026); + make.right.mas_equalTo(self.speedBackView.mas_right).mas_offset(-screenWidth * 0.40); + make.height.equalTo(@16); + }]; + +} + +@end diff --git a/MRMobileRun/MRRunning/MGDDataViewController.h b/MRMobileRun/MRRunning/MGDDataViewController.h new file mode 100644 index 0000000..d27acc7 --- /dev/null +++ b/MRMobileRun/MRRunning/MGDDataViewController.h @@ -0,0 +1,61 @@ +// +// MGDDataViewController.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + +#import +#import "MGDOverView.h" +#import "MGDDataView.h" +#import "MGDButtonsView.h" +#import "MGDShareView.h" +#import "MGDShareDataView.h" + +NS_ASSUME_NONNULL_BEGIN + +API_AVAILABLE(ios(12.0)) +@interface MGDDataViewController : UIViewController + +@property (nonatomic, strong) NSString *userIconStr; +@property (nonatomic, strong) NSString *userNmaeStr; +@property (nonatomic, strong) NSString *distanceStr; //跑步距离 +@property (nonatomic, strong) NSString *speedStr; //配速 +@property (nonatomic, strong) NSString *stepFrequencyStr; //步频 +@property (nonatomic, strong) NSString *timeStr; //跑步时间 +@property (nonatomic, strong) NSString *energyStr;//千卡 +//这里要获取的是跑步的具体日期,你把时间转换一下传过来就行,具体的形式可以参考我的cell跳转到分享页面时的具体的日期 +@property (nonatomic, strong) NSString *date; //日期 +@property (nonatomic, strong) NSString *time; //时间 + +@property (nonatomic, strong) NSArray *locationAry; //首页中采集到的所有定位点的数据 +@property (nonatomic, strong) NSArray *drawLineAry; //首页中采集到的所有用来绘制轨迹的数据 + +@property (nonatomic, strong) NSArray *caculatedSpeedAry; //首页中处理后的速度数组 +@property (nonatomic, strong) NSArray *cacultedStepsAry; //首页中的处理后步频数组 + +@property int averageStepFrequency; //平均步频 +@property int maxStepFrequencyLastest; //最大步频 +@property double averageSpeed; //平均速度 +@property double maxSpeedLastest; //最大速度 + +@property (nonatomic, strong) NSArray *originStepsAry; //原始的获取到的步频数组; + +@property (nonatomic ,strong) UIScrollView *backScrollView; + +@property (nonatomic ,strong) MGDOverView *overView; + +@property (nonatomic ,strong) MGDDataView *dataView; + +@property (nonatomic ,strong) MGDButtonsView *twoBtnView; + +@property (nonatomic ,strong) MGDShareView *shareView; + +//关于天气 +@property (nonatomic, strong) NSString *temperature; +@property (nonatomic, strong) NSString *weather; +//@property (nonatomic, strong) UIImageView *weatherImageView; //显示天气图片的图片框 +@property (nonatomic ,strong) MGDShareDataView *shareDataView; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/MGDDataViewController.m b/MRMobileRun/MRRunning/MGDDataViewController.m new file mode 100644 index 0000000..129639a --- /dev/null +++ b/MRMobileRun/MRRunning/MGDDataViewController.m @@ -0,0 +1,550 @@ +// +// MGDDataViewController.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + + +#import +#import +#import +#import +#import +#import +#import +#import +#import //搜索库,为获取天气 + +#import "ZYLMainViewController.h" //首页 +#import "ZYLRunningViewController.h" +#import "MRTabBarController.h" +#import "MGDDataViewController.h" +#import "RunLocationModel.h" +#import "MASmoothPathTool.h" +#import "UIImageView+WebCache.h" +#import "SZHChart.h"//速度图表的View +#import "SZHWaveChart.h"//步频的波浪图 +#import "MGDTabBarViewController.h" + +@interface MGDDataViewController () +@property (nonatomic, strong) AMapLocationManager *ALocationManager; +@property (nonatomic, strong) NSArray *origTracePoints; //原始轨迹测绘坐标点 +@property (nonatomic, strong) NSArray *smoothedTracePoints; //平滑处理用的轨迹数组点 +@property (nonatomic, strong) MAPolyline *smoothedTrace; + + + +//大头针 +@property (nonatomic, strong) MAPointAnnotation *beginAnnotataion; +@property (nonatomic, strong) MAPointAnnotation *endAnnotataion; + + +@property __block UIImage *shareImage; +@end + +@implementation MGDDataViewController +- (void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:YES]; + self.tabBarController.hidesBottomBarWhenPushed = YES; + self.navigationController.navigationBar.hidden = NO; +} + +- (void)viewDidAppear:(BOOL)animated{ + [super viewDidAppear:YES]; + self.tabBarController.hidesBottomBarWhenPushed = NO; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self.navigationController setNavigationBarHidden:YES animated:YES];//隐藏导航栏 + + [self fit]; + self.overView.mapView.delegate = self; + self.overView.mapView.showsUserLocation = NO; + self.overView.mapView.userInteractionEnabled = YES; + [self initLocationManager]; +/* +绘制轨迹 + */ + //初始化原始数据数组和处理后的数组 + self.origTracePoints = [NSArray array]; + self.smoothedTracePoints = [NSArray array]; + [self loadTrancePoints]; + [self initSmoothedTrace]; + + //绘制始终位置大头针 + [self initBeginAndEndAnnotations]; + + // 给分享界面添加手势 + UITapGestureRecognizer *backGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(backevent:)]; + backGesture.delegate = self; + [self.shareView.backView addGestureRecognizer:backGesture]; + + //设置地图中心点 + RunLocationModel *model3 = self.locationAry.lastObject; + CLLocationCoordinate2D centerCoordinate = model3.location; + [self.overView.mapView setCenterCoordinate:centerCoordinate ]; + self.overView.mapView.showsUserLocation = NO; + [self.ALocationManager stopUpdatingLocation]; //停止定位 +} + //适配各个View的深色模式以及页面布局 +- (void)fit{ + //适配深色模式 + _backScrollView = [[UIScrollView alloc] init]; + if (@available(iOS 11.0, *)) { + self.view.backgroundColor = bottomColor; + _backScrollView.contentInsetAdjustmentBehavior = UIApplicationBackgroundFetchIntervalNever; + } else { + // Fallback on earlier versions + } + + //根据机型进行控件布局 + if (kIs_iPhoneX) { + _backScrollView.frame = CGRectMake(0, 0, screenWidth, screenHeigth - 100); + + _twoBtnView = [[MGDButtonsView alloc] initWithFrame:CGRectMake(0, screenHeigth - 100, screenWidth, 100)]; + + _dataView = [[MGDDataView alloc] initWithFrame:CGRectMake(0, screenHeigth - 100 + 10, screenWidth, 710 + 35)]; + }else { + _backScrollView.frame = CGRectMake(0, 0, screenWidth, screenHeigth - 66); + + _twoBtnView = [[MGDButtonsView alloc] initWithFrame:CGRectMake(0, screenHeigth - 66, screenWidth, 66)]; + + _dataView = [[MGDDataView alloc] initWithFrame:CGRectMake(0, screenHeigth - 66 + 50, screenWidth, 710 + 35)]; + + } + + //两个butto的View + [_twoBtnView.overBtn addTarget:self action:@selector(backRootCV) forControlEvents:UIControlEventTouchUpInside]; + [_twoBtnView.shareBtn addTarget:self action:@selector(share) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:_twoBtnView]; + if (kIs_iPhoneX) { + _backScrollView.contentSize = CGSizeMake(screenWidth, 1432 + 100); + }else { + _backScrollView.contentSize = CGSizeMake(screenWidth, screenHeigth + 667); + } + [self.view addSubview:_backScrollView]; + + //地图下,统计图上的View,配速、时间、燃烧千卡等label的数据 + if (@available(iOS 12.0, *)) { + _overView = [[MGDOverView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeigth)]; + } else { + // Fallback on earlier versions + } + [self.backScrollView addSubview:_overView]; + self.overView.mapView.delegate = self; + /* + 步频、速度两个图表 + */ + [self addTwoCharts]; + + //绘制统计图的View + [self.backScrollView addSubview:_dataView]; + + + + //赋值 + //温度赋值 + if (self.temperature != nil) { + self.overView.degree.text = [NSString stringWithFormat:@"%@°C",self.temperature]; + } + self.overView.kmLab.text = self.distanceStr; //跑步距离赋值 + self.overView.speedLab.text = self.speedStr; //配速赋值 +// if (self.averageStepFrequency >0 && self.averageStepFrequency < 300) { + if (self.averageStepFrequency < 300) { + self.overView.paceLab.text = [NSString stringWithFormat:@"%d",self.averageStepFrequency]; //平均步频赋值 + } +// } + //天气框图片 + if ([self.weather isEqualToString:@"雷阵雨"]) { + self.overView.weatherImagview.image = [UIImage imageNamed:@"雷阵雨白"]; + }else if ([self.weather isEqualToString:@"晴"]){ + self.overView.weatherImagview.image = [UIImage imageNamed:@"晴白"]; + }else if ([self.weather isEqualToString:@"雪"]){ + self.overView.weatherImagview.image = [UIImage imageNamed:@"雪白"]; + }else if ([self.weather isEqualToString:@"阴"] || [self.weather isEqualToString:@"多云"]){ + self.overView.weatherImagview.image = [UIImage imageNamed:@"阴天白"]; + }else if([self.weather isEqualToString:@"雨"]){ + self.overView.weatherImagview.image = [UIImage imageNamed:@"雨白"]; + } + _overView.timeLab.text = self.timeStr; //跑步时间赋值 + self.overView.calLab.text = self.energyStr; //燃烧千卡赋值 + self.overView.paceLab.text = [NSString stringWithFormat:@"%d",self.averageStepFrequency]; //平均步频 + self.dataView.paceLab.text = [NSString stringWithFormat:@"%d",self.maxStepFrequencyLastest]; //最大步频 + self.dataView.speedLab.text = [NSString stringWithFormat:@"%.02f",self.maxSpeedLastest]; //最大速度 + +} + +//添加两个图表 +- (void)addTwoCharts{ + //画步频的波浪图 + //如果步频数组不为0则正常绘制 + if (self.cacultedStepsAry.count != 0) { + //步频的波浪图 + SZHWaveChart *paceWaveChart = [[SZHWaveChart alloc] init]; + [paceWaveChart initWithViewsWithBooTomCount:self.cacultedStepsAry.count AndLineDataAry:self.cacultedStepsAry AndYMaxNumber:250]; + + //图标添加到视图上并进行位置约束 + [self.dataView.paceBackView addSubview:paceWaveChart]; + [paceWaveChart mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.dataView.paceBackView); + make.height.mas_equalTo(245); + }]; + paceWaveChart.topYlabel.text = @"步/分"; + paceWaveChart.bottomXLabel.text = @"分钟"; + + //创建左边的数字label + for (int i = 0; i < paceWaveChart.leftLblAry.count; i++) { + UILabel *label = paceWaveChart.leftLblAry[i]; + label.text = [NSString stringWithFormat:@"%d",(i+1) * 50]; + } + }else if (self.cacultedStepsAry.count == 0) { + NSArray *paceArray = @[@130,@140,@152,@180,@200,@148,@132,@98]; + SZHWaveChart *paceWaveChart = [[SZHWaveChart alloc] init]; + [paceWaveChart initWithViewsWithBooTomCount:paceArray.count AndLineDataAry:paceArray AndYMaxNumber:250]; + [self.dataView.paceBackView addSubview:paceWaveChart]; + [paceWaveChart mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.dataView.paceBackView); + make.height.mas_equalTo(245); + }]; + paceWaveChart.topYlabel.text = @"步/分"; + paceWaveChart.bottomXLabel.text = @"分钟"; + for (int i = 0; i < paceWaveChart.leftLblAry.count; i++) { + UILabel *label = paceWaveChart.leftLblAry[i]; + label.text = [NSString stringWithFormat:@"%d",(i+1) * 50]; + } + } + + //处理画速度的折线图 + +// NSLog(@"在跑步结束页绘制的速度数组为%@",self.caculatedSpeedAry); + //如果速度数组不为空则正常显示,否则就显示固定的数组 + if (self.caculatedSpeedAry.count != 0) { + //速度的折线图 + SZHChart *speedChart = [[SZHChart alloc] init]; + [speedChart initWithViewsWithBooTomCount:self.caculatedSpeedAry.count AndLineDataAry:self.caculatedSpeedAry AndYMaxNumber:6]; + + //约束并添加到视图上 + [self.dataView.speedBackView addSubview:speedChart]; + [speedChart mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.dataView.speedBackView); + make.height.mas_equalTo(245); + }]; + speedChart.topYlabel.text = @"米/秒"; + speedChart.bottomXLabel.text = @"分钟"; + + //创建左边的数字label + for (int i = 0; i < speedChart.leftLblAry.count; i++) { + UILabel *label = speedChart.leftLblAry[i]; + label.text = [NSString stringWithFormat:@"%d", i + 2]; + } + }else if (self.caculatedSpeedAry.count == 0){ + //速度的折线图 + SZHChart *speedChart = [[SZHChart alloc] init]; + //测试用 + NSArray *array = @[@3,@4.8,@4,@3.8,@4,@4.3,@4.5,@3.7]; + [speedChart initWithViewsWithBooTomCount:array.count AndLineDataAry:array AndYMaxNumber:6]; + [self.dataView.speedBackView addSubview:speedChart]; + [speedChart mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.dataView.speedBackView); + make.height.mas_equalTo(245); + }]; + speedChart.topYlabel.text = @"米/秒"; + speedChart.bottomXLabel.text = @"分钟"; + for (int i = 0; i < speedChart.leftLblAry.count; i++) { + UILabel *label = speedChart.leftLblAry[i]; + label.text = [NSString stringWithFormat:@"%d", i + 2]; + } + } +} + +//跳转到首页界面 +- (void)backRootCV { + MGDTabBarViewController *cv = [[MGDTabBarViewController alloc] init]; + self.tabBarController.tabBar.hidden = NO; + [self.navigationController pushViewController:cv animated:YES]; +} + +- (void)share { + _shareView = [[MGDShareView alloc] initWithShotImage:@"" logoImage:@"" QRcodeImage:@""]; + [self.view addSubview:_shareView]; + [_shareView.cancelBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; + + //分享界面下五个按钮的方法 + [self shareAction]; + + // 分享界面的地图截图 +// CGRect inRect = self.overView.mapView.frame; + +// CGRect inRect = self.shareView.popView.frame; + CGRect inRect = self.overView.mapView.frame; + [self.overView.mapView takeSnapshotInRect:inRect withCompletionBlock:^(UIImage *resultImage, NSInteger state) { + state = 1; + self.shareImage = resultImage; + self.shareView.shotImage.image = self.shareImage; + }]; + //在地图截图上展示跑步距离、配速、步频、时间等数据 + self->_shareDataView = [[MGDShareDataView alloc] init]; + [self.shareDataView.userIcon sd_setImageWithURL:[NSURL URLWithString:self.userIconStr] placeholderImage:[UIImage imageNamed:@"logo头像"]]; + self.shareDataView.userName.text = self.userNmaeStr; + self.shareDataView.kmLab.text = self.distanceStr; //跑步距离赋值 + self.shareDataView.speedLab.text = self.speedStr; //配速赋值 + self.shareDataView.timeLab.text = self.timeStr; //跑步时间赋值 + self.shareDataView.calLab.text = self.energyStr; //燃烧千卡赋值 + self.shareDataView.paceLab.text = self.stepFrequencyStr; //步频 + self.shareDataView.date.text = self.date; //日期 + self.shareDataView.currentTime.text = self.time; //时间 + [self.shareView.dataView addSubview:_shareDataView]; +} + +- (void)backevent:(UIGestureRecognizer *)sender { + NSLog(@"1111"); +} + + +- (void)back { + [UIView animateWithDuration:0.3 animations:^{ + [self.shareView removeFromSuperview]; + }]; +} + +#pragma mark- 位置管理者 +- (void)initLocationManager{ + self.ALocationManager = [[AMapLocationManager alloc] init]; + self.ALocationManager.delegate = self; + self.ALocationManager.allowsBackgroundLocationUpdates = YES; //开启后台定位 + self.ALocationManager.distanceFilter = 5; //设置移动精度 + self.ALocationManager.locationTimeout = 2; //定位超时时间 + [self.ALocationManager setLocatingWithReGeocode:YES]; + [self.ALocationManager startUpdatingLocation]; + // 延迟执行取消定位操作 + __weak typeof(self) weakSelf = self; + dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)); + dispatch_after(delayTime, dispatch_get_main_queue(), ^{ + [weakSelf.ALocationManager stopUpdatingLocation]; + }); +} + +#pragma mark- 轨迹相关 + //因为CLLocationCoordinate2D为只读属性,无法用可变数组直接addobject储存,所以需要以下转化 +- (void)loadTrancePoints{ + NSMutableArray *muteableAry = [NSMutableArray array]; + // CLLocationCoordinate2D linePoints[self.drawLineAry.count]; + for (int i = 0; i < self.drawLineAry.count; i++) { + RunLocationModel *lineLocationModel = self.drawLineAry[i]; + // linePoints[i] = lineLocationModel.location; + MALonLatPoint *point = [[MALonLatPoint alloc] init]; + point.lat = lineLocationModel.location.latitude; + point.lon = lineLocationModel.location.longitude; + [muteableAry addObject:point]; + } + self.origTracePoints = muteableAry; + NSLog(@"原始轨迹数据测绘点个数为%lu",(unsigned long)self.origTracePoints.count); +} + +//处理、绘制轨迹线 +- (void)initSmoothedTrace{ + MASmoothPathTool *tool = [[MASmoothPathTool alloc] init]; + tool.intensity = 3; + tool.threshHold = 0.3; + tool.noiseThreshhold = 10; + self.smoothedTracePoints = [tool pathOptimize:self.origTracePoints]; + NSLog(@"处理后的轨迹绘制数据点%lu",(unsigned long)self.smoothedTracePoints.count); + CLLocationCoordinate2D *pCoords = malloc(sizeof(CLLocationCoordinate2D) * self.smoothedTracePoints.count); + if(!pCoords) { + return; + } + + for(int i = 0; i < self.smoothedTracePoints.count; ++i) { + MALonLatPoint *p = [self.smoothedTracePoints objectAtIndex:i]; + CLLocationCoordinate2D *pCur = pCoords + i; +// CLLocationCoordinate2D *pCur = &pCoords[i]; + pCur->latitude = p.lat; + pCur->longitude = p.lon; + } + + self.smoothedTrace = [MAPolyline polylineWithCoordinates:pCoords count:self.smoothedTracePoints.count]; + [self.overView.mapView addOverlay:self.smoothedTrace]; + if(pCoords) { + free(pCoords); + } + +} + +//自定义轨迹线 +- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id)overlay{ + if ([overlay isKindOfClass:[MAPolyline class]]) { + MAPolylineRenderer *polyLineRender = [[MAPolylineRenderer alloc] initWithPolyline:overlay]; + polyLineRender.lineWidth = 8; + polyLineRender.strokeColor = [UIColor colorWithRed:123/255.0 green:183/255.0 blue:196/255.0 alpha:1.0]; //折线颜色 + return polyLineRender; + } + return nil; +} + +#pragma mark- 大头针相关 +//设置开始,结束位置的大头针 +- (void)initBeginAndEndAnnotations{ + //开始地点 + MAPointAnnotation *beginAnnotation = [[MAPointAnnotation alloc] init]; + // RunLocationModel *beginLocation = self.locationAry.firstObject; + MALonLatPoint *beginLocation = self.smoothedTracePoints.firstObject; + beginAnnotation.coordinate = CLLocationCoordinate2DMake(beginLocation.lat, beginLocation.lon); + self.beginAnnotataion = beginAnnotation; + [self.overView.mapView addAnnotation:self.beginAnnotataion]; + + //结束地点 + MAPointAnnotation *endAnnotation = [[MAPointAnnotation alloc] init]; + // RunLocationModel *endLocation = self.locationAry.lastObject; + MALonLatPoint *endLocation = self.smoothedTracePoints.lastObject; + endAnnotation.coordinate = CLLocationCoordinate2DMake(endLocation.lat, endLocation.lon); + self.endAnnotataion = endAnnotation; + [self.overView.mapView addAnnotation:self.endAnnotataion]; +} + +//自定义大头针样式 +- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation{ + if ([annotation isKindOfClass:[MAPointAnnotation class]]){ + if (annotation == self.beginAnnotataion) { + static NSString *pointReuseIndentifier = @"pointReuseIndentifier"; + MAPinAnnotationView*annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndentifier]; + if (annotationView == nil){ + annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndentifier]; + } + annotationView.image = [UIImage imageNamed:@"startPointImage"]; + annotationView.animatesDrop = NO; //设置标注动画显示,默认为NO + annotationView.canShowCallout= NO; //设置气泡可以弹出,默认为NO + annotationView.draggable = NO; //设置不可被拖动 + return annotationView; + }else if (annotation == self.endAnnotataion){ + static NSString *end = @"end"; + MAPinAnnotationView*annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:end]; + if (annotationView == nil){ + annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:end]; + } + annotationView.image = [UIImage imageNamed:@"endPointImage"]; + annotationView.animatesDrop = NO; //设置标注动画显示,默认为NO + annotationView.canShowCallout= NO; //设置气泡可以弹出,默认为NO + annotationView.draggable = NO; //设置不可被拖动 + return annotationView; + } + } + return nil; +} + +#pragma mark- 定位回调方法 +- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation{ + CGFloat signal = userLocation.location.horizontalAccuracy; + + if(!updatingLocation) + return ; + + if (signal < 0) + { + return ; + } +} + +//持续定位 +- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode{ + CGFloat signal = location.horizontalAccuracy; + if (signal < 0) + { + return ; + } + + NSLog(@"逆地理编码为%@",reGeocode.citycode); + [self.overView.mapView setCenterCoordinate:location.coordinate]; +} + +#pragma mark- 分享的五个按钮的方法 +- (void)shareAction{ + for (int i = 0; i < self.shareView.bootomBtns.count; i++) { + UIButton *btn = [self.shareView.bootomBtns objectAtIndex:i]; + switch (btn.tag) { + case 1: + [btn addTarget:self action:@selector(savePhotoAtLocalAlbum) forControlEvents:UIControlEventTouchUpInside]; + break; + + default: + break; + } + } +} + +//保存截图到本地 +- (void)savePhotoAtLocalAlbum{ + CGRect inRect = self.overView.mapView.frame; + [self.overView.mapView takeSnapshotInRect:inRect withCompletionBlock:^(UIImage *resultImage, NSInteger state) { + state = 1; + }]; + //截取指定区域的屏幕 + UIImage *imageRet = [[UIImage alloc]init]; + UIGraphicsBeginImageContextWithOptions(self.shareView.frame.size, false, 0.0); + [self.shareView.layer renderInContext:UIGraphicsGetCurrentContext()]; + imageRet = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + //保存截图到本地 + UIImageWriteToSavedPhotosAlbum(imageRet, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL); +} +// 保存图片到相册的回调方法 +- (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void*) contextInfo{ + + NSString *msg = nil ; + if(error != NULL){ + msg = @"保存图片失败" ; + }else{ + msg = @"保存图片成功"; + } + + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"保存图片结果提示" message:msg + delegate:self + cancelButtonTitle:@"确定" + otherButtonTitles:nil]; + [alert show]; +} + +#pragma mark-关于两个位置管理者的定位代理方法:实现后台定位 + +- (void)amapLocationManager:(AMapLocationManager *)manager doRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} +- (void)mapViewRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} + +//监听系统的颜色模式来配置地图的白天、深色模式下的自定义样式 +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{ + [super traitCollectionDidChange: previousTraitCollection]; + if (@available(iOS 13.0, *)) { + if([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]){ + if (@available(iOS 13.0, *)) { + UIUserInterfaceStyle mode = UITraitCollection.currentTraitCollection.userInterfaceStyle; + if (mode == UIUserInterfaceStyleDark) { + NSLog(@"深色模式"); + NSString *path = [[NSBundle mainBundle] pathForResource:@"style" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.overView.mapView setCustomMapStyleOptions:options]; + [self.overView.mapView setCustomMapStyleEnabled:YES]; + } else if (mode == UIUserInterfaceStyleLight) { + NSLog(@"浅色模式"); + NSString *path = [[NSBundle mainBundle] pathForResource:@"style2" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.overView.mapView setCustomMapStyleOptions:options]; + [self.overView.mapView setCustomMapStyleEnabled:YES]; + } else { + NSLog(@"未知模式"); + } + } + } + } else { + // Fallback on earlier versions + } + + } +@end diff --git a/MRMobileRun/MRRunning/MGDOverView.h b/MRMobileRun/MRRunning/MGDOverView.h new file mode 100644 index 0000000..015a438 --- /dev/null +++ b/MRMobileRun/MRRunning/MGDOverView.h @@ -0,0 +1,61 @@ +// +// MGDOverView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/26. +// + +#import +#import +#import +#import +#import +NS_ASSUME_NONNULL_BEGIN + + +API_AVAILABLE(ios(12.0)) +API_AVAILABLE(ios(12.0)) +@interface MGDOverView : UIView +//@property (nonatomic, strong) MAMapView *mapView2; + +//天气的图 +@property (nonatomic, strong) UIImageView *weatherImagview; + +//温度 +@property (nonatomic, strong) UILabel *degree; +//地图 +@property (nonatomic, strong) MAMapView *mapView; +//下方背景 +@property (nonatomic, strong) UIView *backView; +//头像 +@property (nonatomic, strong) UIImageView *userIcon; +//用户名 +@property (nonatomic, strong) UILabel *userName; +//公里数 +@property (nonatomic, strong) UILabel *kmLab; +//公里单位 +@property (nonatomic, strong) UILabel *km; +//配速 +@property (nonatomic, strong) UILabel *speedLab; +//配速单位 +@property (nonatomic, strong) UILabel *speed; +//步频 +@property (nonatomic, strong) UILabel *paceLab; +//步频单位 +@property (nonatomic, strong) UILabel *pace; +//时间 +@property (nonatomic, strong) UILabel *timeLab; +//时间单位 +@property (nonatomic, strong) UILabel *time; +//千卡 +@property (nonatomic, strong) UILabel *calLab; +//千卡单位 +@property (nonatomic, strong) UILabel *cal; +//日期 +@property (nonatomic, strong) UILabel *date; +//时间 +@property (nonatomic, strong) UILabel *currentTime; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/MGDOverView.m b/MRMobileRun/MRRunning/MGDOverView.m new file mode 100644 index 0000000..10679b9 --- /dev/null +++ b/MRMobileRun/MRRunning/MGDOverView.m @@ -0,0 +1,480 @@ +// +// MGDOverView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/26. +// + +#import "MGDOverView.h" +#import +#import +#import +#import +#import + +#import "UIImageView+WebCache.h" +#import "HttpClient.h" +#import +#define UNITCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] + +@implementation MGDOverView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + //地图的View + _mapView = [[MAMapView alloc] init]; + [self addSubview:_mapView]; + + //温度的label + _degree = [[UILabel alloc] init]; + _degree.font = [UIFont fontWithName:@"PingFangSC" size: 18]; + _degree.textAlignment = NSTextAlignmentCenter; + [self.mapView addSubview:_degree]; + + //天气的图片 + _weatherImagview = [[UIImageView alloc] init]; + [self.mapView addSubview:_weatherImagview]; + + //下方显示跑步信息的View + _backView = [[UIView alloc] init]; + [self addSubview:_backView]; + + //用户头像 + _userIcon = [[UIImageView alloc] init]; + _userIcon.layer.masksToBounds = YES; + _userIcon.contentMode = UIViewContentModeScaleToFill; + _userIcon.layer.cornerRadius = screenWidth * 0.192 / 2; + [self.backView addSubview:_userIcon]; + + //用户姓名 + _userName = [[UILabel alloc] init]; + _userName.textAlignment = NSTextAlignmentLeft; + _userName.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _userName.numberOfLines = 0; + [self.backView addSubview:_userName]; + + //展示跑步信息的一些Label + _kmLab = [[UILabel alloc] init]; + _kmLab.textAlignment = NSTextAlignmentCenter; + _kmLab.font = [UIFont fontWithName:@"Impact" size: 44]; + _kmLab.numberOfLines = 0; + [self.backView addSubview:_kmLab]; + + _km = [[UILabel alloc] init]; + _km.textAlignment = NSTextAlignmentLeft; + _km.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 18]; + _km.text = @"公里"; + [self.backView addSubview:_km]; + + _speedLab = [[UILabel alloc] init]; + _speedLab.textAlignment = NSTextAlignmentCenter; + _speedLab.font = [UIFont fontWithName:@"Impact" size: 24]; + [self.backView addSubview:_speedLab]; + + _speed = [[UILabel alloc] init]; + _speed.textAlignment = NSTextAlignmentCenter; + _speed.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 12]; + _speed.text = @"配速"; + _speed.tintColor = UNITCOLOR; + [self.backView addSubview:_speed]; + + _paceLab = [[UILabel alloc] init]; + _paceLab.textAlignment = NSTextAlignmentCenter; + _paceLab.font = self.speedLab.font; + [self.backView addSubview:_paceLab]; + + _pace = [[UILabel alloc] init]; + _pace.textAlignment = NSTextAlignmentCenter; + _pace.font = _speed.font; + _pace.text = @"步频"; + _pace.tintColor = UNITCOLOR; + [self.backView addSubview:_pace]; + + _timeLab = [[UILabel alloc] init]; + _timeLab.textAlignment = NSTextAlignmentCenter; + _timeLab.font = self.speedLab.font; + [self.backView addSubview:_timeLab]; + + _time = [[UILabel alloc] init]; + _time.textAlignment = NSTextAlignmentCenter; + _time.font = self.speed.font; + _time.text = @"时间"; + _time.tintColor = UNITCOLOR; + [self.backView addSubview:_time]; + + _calLab = [[UILabel alloc] init]; + _calLab.textAlignment = NSTextAlignmentCenter; + _calLab.font = self.speedLab.font; + [self.backView addSubview:_calLab]; + + _cal = [[UILabel alloc] init]; + _cal.textAlignment = NSTextAlignmentCenter; + _cal.font = self.speed.font; + _cal.text = @"千卡"; + _cal.tintColor = UNITCOLOR; + [self.backView addSubview:_cal]; + + _date = [[UILabel alloc] init]; + _date.textAlignment = NSTextAlignmentRight; + _date.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + [self.backView addSubview:_date]; + + _currentTime = [[UILabel alloc] init]; + _currentTime.textAlignment = NSTextAlignmentRight; + _currentTime.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + [self.backView addSubview:_currentTime]; + + + if (@available(iOS 11.0, *)) { + self.backView.backgroundColor = bottomColor; + self.kmLab.tintColor = bottomTitleColor; + self.speedLab.tintColor = bottomTitleColor; + self.paceLab.tintColor = bottomTitleColor; + self.timeLab.tintColor = bottomTitleColor; + self.calLab.tintColor = bottomTitleColor; + self.km.tintColor = kmColor; + self.currentTime.tintColor = MGDTextColor2; + self.date.tintColor = MGDColor2; + } else { + // Fallback on earlier versions + } + //数据测试 + [self test]; + [self changeMapType]; + } + return self; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + + if (kIs_iPhoneX) { + [_mapView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth * 0.6477); + }]; + + [_degree mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(screenHeigth * 0.0714); + make.right.mas_equalTo(self.mas_right).mas_offset(-screenWidth * 0.1546); + make.left.mas_equalTo(self.mas_left).mas_offset(screenWidth * 0.728); + make.height.mas_equalTo(screenHeigth * 0.0446); + }]; + + [_weatherImagview mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(screenHeigth * 0.0714); +// make.right.mas_equalTo(self.mas_right).mas_offset(-screenWidth * 0.0693); + make.left.mas_equalTo(self.mas_left).mas_offset(screenWidth * 0.8666); + make.size.mas_equalTo(CGSizeMake(24, 26.5)); +// make.height.mas_equalTo(screenHeigth * 0.0503); + }]; + + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mapView.mas_bottom); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth * 0.229); + }]; + + [_date mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.7093); + make.width.mas_equalTo(screenWidth * 0.144); + make.height.mas_equalTo(screenHeigth * 0.0594); + }]; + + [_currentTime mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.date); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.8666); + make.width.mas_equalTo(screenWidth * 0.0933); + make.height.mas_equalTo(screenHeigth * 0.0594); + }]; + + [_userIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.0594 * 0.3522); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.0506); + make.width.height.mas_equalTo(screenWidth * 0.192); + }]; + + [_userName mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.3522 * 0.1468); + make.left.mas_equalTo(self.userIcon.mas_right).mas_offset(screenWidth * 0.0373); + make.width.mas_equalTo(screenWidth * 0.3386); + make.height.mas_equalTo(screenHeigth * 0.0769 * 0.3522); + }]; + + [_kmLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.0381); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-screenWidth * 0.136); + make.width.mas_greaterThanOrEqualTo(screenWidth * 0.2106); + make.height.mas_equalTo(screenHeigth * 0.1853 * 0.3522); + }]; + + [_km mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.1888 * 0.3522); + make.left.mas_equalTo(self.kmLab.mas_right); + make.height.mas_equalTo(screenHeigth * 0.0874 * 0.3522); + make.width.mas_equalTo(screenWidth * 0.096); + }]; + + [_speedLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.kmLab.mas_bottom).mas_offset(screenHeigth * 0.0369); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.04); + make.width.mas_equalTo(screenWidth * 0.208); + make.height.mas_equalTo(screenHeigth * 0.1013 * 0.3522); + }]; + + [_speed mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab.mas_bottom).mas_offset(screenHeigth * 0.0049 * 0.3522); + make.left.mas_equalTo(self.speedLab.mas_left).mas_offset(screenWidth * 0.024); + make.right.mas_equalTo(self.speedLab.mas_right).mas_offset(-screenWidth * 0.0186); + make.height.mas_equalTo(screenHeigth * 0.0839* 0.3522); + }]; + + [_paceLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.2773); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_pace mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.paceLab.mas_left).mas_offset(screenWidth * 0.056); + make.right.mas_equalTo(self.paceLab.mas_right).mas_offset(-screenWidth * 0.056); + make.height.mas_equalTo(self.speed); + }]; + + [_timeLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.5146); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_time mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.timeLab.mas_left).mas_offset(screenWidth * 0.056); + make.right.mas_equalTo(self.timeLab.mas_right).mas_offset(-screenWidth * 0.056); + make.height.mas_equalTo(self.speed); + }]; + + [_calLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.752); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_cal mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.calLab.mas_left).mas_offset(screenWidth * 0.056); + make.right.mas_equalTo(self.calLab.mas_right).mas_offset(-screenWidth * 0.056); + make.height.mas_equalTo(self.speed); + }]; + + }else { + [_mapView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth * 0.6221); + }]; + + [_degree mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(screenHeigth * 0.0728); + make.right.mas_equalTo(self.mas_right).mas_offset(-screenWidth * 0.1546); + make.left.mas_equalTo(self.mas_left).mas_offset(screenWidth * 0.728); + make.height.mas_equalTo(screenHeigth * 0.0493); + }]; + + [_weatherImagview mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(screenHeigth * 0.0714); +// make.right.mas_equalTo(self.mas_right).mas_offset(-screenWidth * 0.0693); + make.left.mas_equalTo(self.mas_left).mas_offset(screenWidth * 0.8666); + make.size.mas_equalTo(CGSizeMake(24, 26.5)); +// make.height.mas_equalTo(screenHeigth * 0.0503); + }]; + + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mapView.mas_bottom); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth * 0.3788); + }]; + + [_date mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.7093); + make.width.mas_equalTo(screenWidth * 0.144); + make.height.mas_equalTo(screenHeigth * 0.0594); + }]; + + [_currentTime mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.date); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.8666); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-screenWidth * 0.02); + make.height.mas_equalTo(screenHeigth * 0.0594); + }]; + + [_userIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.0674 * 0.3788); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.0506); + make.width.height.mas_equalTo(screenWidth * 0.192); + }]; + + [_userName mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.3522 * 0.1468); + make.left.mas_equalTo(self.userIcon.mas_right).mas_offset(screenWidth * 0.0373); + make.width.mas_equalTo(screenWidth * 0.3386); + make.height.mas_equalTo(screenHeigth * 0.0873 * 0.3778); + }]; + + [_kmLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.0381); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-screenWidth * 0.136); + make.width.mas_greaterThanOrEqualTo(screenWidth * 0.2106); + make.height.mas_equalTo(screenHeigth * 0.2103 * 0.3778); + }]; + + [_km mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(screenHeigth * 0.1888 * 0.3778); + make.right.mas_equalTo(self.backView.mas_right); + make.height.mas_equalTo(screenHeigth * 0.0992 * 0.3778); + make.left.mas_equalTo(self.kmLab.mas_right); + }]; + + [_speedLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.kmLab.mas_bottom).mas_offset(screenHeigth * 0.0369); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.04); + make.width.mas_equalTo(screenWidth * 0.208); + make.height.mas_equalTo(screenHeigth * 0.115 * 0.3788); + }]; + + [_speed mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab.mas_bottom).mas_offset(screenHeigth * 0.0049 * 0.3778); + make.left.mas_equalTo(self.speedLab.mas_left).mas_offset(screenWidth * 0.024); + make.right.mas_equalTo(self.speedLab.mas_right).mas_offset(-screenWidth * 0.0186); + make.height.mas_equalTo(screenHeigth * 0.0952* 0.2788); + }]; + + [_paceLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.2773); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_pace mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.paceLab.mas_left).mas_offset(screenWidth * 0.056); + make.right.mas_equalTo(self.paceLab.mas_right).mas_offset(-screenWidth * 0.056); + make.height.mas_equalTo(self.speed); + }]; + + [_timeLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.5146); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_time mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.timeLab.mas_left).mas_offset(screenWidth * 0.056); + make.right.mas_equalTo(self.timeLab.mas_right).mas_offset(-screenWidth * 0.056); + make.height.mas_equalTo(self.speed); + }]; + + [_calLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.752); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_cal mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.calLab.mas_left).mas_offset(screenWidth * 0.056); + make.right.mas_equalTo(self.calLab.mas_right).mas_offset(-screenWidth * 0.056); + make.height.mas_equalTo(self.speed); + }]; + + } + + + +} + +- (void)test { + + //设置地图相关属性 + self.mapView.zoomLevel = 18; + self.mapView.mapType = MAMapTypeStandard; //设置地图的样式 + self.mapView.showsUserLocation = NO; //不显示小蓝点 + self.mapView.userTrackingMode = MAUserTrackingModeFollow; + self.mapView.pausesLocationUpdatesAutomatically = NO; + self.mapView.showsCompass = NO; + self.mapView.showsScale = NO; +// self.mapView.userInteractionEnabled = YES; //是否禁止地图与用户的交互 + [self.mapView setAllowsBackgroundLocationUpdates:YES];//打开后台定位 + self.mapView.distanceFilter = 10; +//自定义用户小蓝点,不让其显示精度圈 + MAUserLocationRepresentation *r = [[MAUserLocationRepresentation alloc] init]; + r.showsAccuracyRing = NO;//不显示精度圈 + r.image = [UIImage imageNamed:@"userAnnotation"]; + [self.mapView updateUserLocationRepresentation:r]; + self.mapView.userInteractionEnabled = NO; + [self getUserInfo]; + + //天气的图片框 + self.weatherImagview = [[UIImageView alloc] init]; + [self addSubview:self.weatherImagview]; + [self.weatherImagview mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.degree.mas_right).offset(8); + make.centerY.height.equalTo(self.degree); + make.width.mas_equalTo(25); + }]; +} +//获取用户的头像、昵称 +- (void)getUserInfo { + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *nickName = [user objectForKey:@"nickname"]; + NSString *imageUrl = [user objectForKey:@"avatar_url"]; + [self.userIcon sd_setImageWithURL:[NSURL URLWithString:imageUrl]]; + self.userName.text = nickName; +} +//判断系统环境在深色或浅色模式,转换自定义地图的地图样式 +- (void)changeMapType{ + if (@available(iOS 13.0, *)) { + UIUserInterfaceStyle mode = UITraitCollection.currentTraitCollection.userInterfaceStyle; + if (mode == UIUserInterfaceStyleDark) { + NSLog(@"深色模式"); + //设置深色模式下的自定义地图样式 + NSString *path = [[NSBundle mainBundle] pathForResource:@"style" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.mapView setCustomMapStyleOptions:options]; + [self.mapView setCustomMapStyleEnabled:YES]; + + } else if (mode == UIUserInterfaceStyleLight) { + NSLog(@"浅色模式"); + //设置浅色模式下的自定义地图样式 + NSString *path = [[NSBundle mainBundle] pathForResource:@"style2" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.mapView setCustomMapStyleOptions:options]; + [self.mapView setCustomMapStyleEnabled:YES]; + + } else { + NSLog(@"未知模式"); + } + } +} + +@end + diff --git a/MRMobileRun/MRRunning/MGDShareDataView.h b/MRMobileRun/MRRunning/MGDShareDataView.h new file mode 100644 index 0000000..bf1b03b --- /dev/null +++ b/MRMobileRun/MRRunning/MGDShareDataView.h @@ -0,0 +1,47 @@ +// +// MGDShareDataView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/9/24. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDShareDataView : UIView + +//下方背景 +@property (nonatomic, strong) UIView *backView; +//头像 +@property (nonatomic, strong) UIImageView *userIcon; +//用户名 +@property (nonatomic, strong) UILabel *userName; +//公里数 +@property (nonatomic, strong) UILabel *kmLab; +//公里单位 +@property (nonatomic, strong) UILabel *km; +//配速 +@property (nonatomic, strong) UILabel *speedLab; +//配速单位 +@property (nonatomic, strong) UILabel *speed; +//步频 +@property (nonatomic, strong) UILabel *paceLab; +//步频单位 +@property (nonatomic, strong) UILabel *pace; +//时间 +@property (nonatomic, strong) UILabel *timeLab; +//时间单位 +@property (nonatomic, strong) UILabel *time; +//千卡 +@property (nonatomic, strong) UILabel *calLab; +//千卡单位 +@property (nonatomic, strong) UILabel *cal; +//日期 +@property (nonatomic, strong) UILabel *date; +//时间 +@property (nonatomic, strong) UILabel *currentTime; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/MGDShareDataView.m b/MRMobileRun/MRRunning/MGDShareDataView.m new file mode 100644 index 0000000..0610408 --- /dev/null +++ b/MRMobileRun/MRRunning/MGDShareDataView.m @@ -0,0 +1,352 @@ +// +// MGDShareDataView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/9/24. +// + +#import "MGDShareDataView.h" +#import +#define UNITCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] + +@implementation MGDShareDataView + +- (instancetype)init { + if (self = [super init]) { + self.frame = [UIScreen mainScreen].bounds; + //下方显示跑步信息的View + _backView = [[UIView alloc] init]; + _backView.backgroundColor = [UIColor clearColor]; + [self addSubview:_backView]; + + //用户头像 + _userIcon = [[UIImageView alloc] init]; + _userIcon.backgroundColor = [UIColor clearColor]; + _userIcon.layer.masksToBounds = YES; + _userIcon.contentMode = UIViewContentModeScaleToFill; + [self.backView addSubview:_userIcon]; + + //用户姓名 + _userName = [[UILabel alloc] init]; + _userName.backgroundColor = [UIColor clearColor]; + _userName.textAlignment = NSTextAlignmentLeft; + _userName.numberOfLines = 0; + [self.backView addSubview:_userName]; + + //展示跑步信息的一些Label + _kmLab = [[UILabel alloc] init]; + _kmLab.backgroundColor = [UIColor clearColor]; + _kmLab.textAlignment = NSTextAlignmentRight; + _kmLab.numberOfLines = 0; + [self.backView addSubview:_kmLab]; + + _km = [[UILabel alloc] init]; + _km.backgroundColor = [UIColor clearColor]; + _km.textAlignment = NSTextAlignmentLeft; + _km.text = @"公里"; + [self.backView addSubview:_km]; + + _speedLab = [[UILabel alloc] init]; + _speedLab.backgroundColor = [UIColor clearColor]; + _speedLab.textAlignment = NSTextAlignmentCenter; + [self.backView addSubview:_speedLab]; + + _speed = [[UILabel alloc] init]; + _speed.backgroundColor = [UIColor clearColor]; + _speed.textAlignment = NSTextAlignmentCenter; + _speed.text = @"配速"; + _speed.tintColor = UNITCOLOR; + [self.backView addSubview:_speed]; + + _paceLab = [[UILabel alloc] init]; + _paceLab.backgroundColor = [UIColor clearColor]; + _paceLab.textAlignment = NSTextAlignmentCenter; + [self.backView addSubview:_paceLab]; + + _pace = [[UILabel alloc] init]; + _pace.backgroundColor = [UIColor clearColor]; + _pace.textAlignment = NSTextAlignmentCenter; + _pace.text = @"步频"; + _pace.tintColor = UNITCOLOR; + [self.backView addSubview:_pace]; + + _timeLab = [[UILabel alloc] init]; + _timeLab.backgroundColor = [UIColor clearColor]; + _timeLab.textAlignment = NSTextAlignmentCenter; + [self.backView addSubview:_timeLab]; + + _time = [[UILabel alloc] init]; + _time.backgroundColor = [UIColor clearColor]; + _time.textAlignment = NSTextAlignmentCenter; + _time.text = @"时间"; + _time.tintColor = UNITCOLOR; + [self.backView addSubview:_time]; + + _calLab = [[UILabel alloc] init]; + _calLab.backgroundColor = [UIColor clearColor]; + _calLab.textAlignment = NSTextAlignmentCenter; + [self.backView addSubview:_calLab]; + + _cal = [[UILabel alloc] init]; + _cal.backgroundColor = [UIColor clearColor]; + _cal.textAlignment = NSTextAlignmentCenter; + _cal.text = @"千卡"; + _cal.tintColor = UNITCOLOR; + [self.backView addSubview:_cal]; + + _date = [[UILabel alloc] init]; + _date.backgroundColor = [UIColor clearColor]; + _date.textAlignment = NSTextAlignmentRight; + _date.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + [self.backView addSubview:_date]; + + _currentTime = [[UILabel alloc] init]; + _currentTime.backgroundColor = [UIColor clearColor]; + _currentTime.textAlignment = NSTextAlignmentRight; + _currentTime.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + [self.backView addSubview:_currentTime]; + + if (kIs_iPhoneX) { + _userName.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _kmLab.font = [UIFont fontWithName:@"Impact" size: 44]; + _km.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 18]; + _speedLab.font = [UIFont fontWithName:@"Impact" size: 24]; + _speed.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 12]; + }else { + //非全面屏手机此处信息的字体调小一点以便于全部显示 + _userName.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 13]; + _kmLab.font = [UIFont fontWithName:@"Impact" size: 38]; + _km.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 16]; + _speedLab.font = [UIFont fontWithName:@"Impact" size: 22]; + _speed.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 10]; + } + _paceLab.font = self.speedLab.font; + _pace.font = _speed.font; + _timeLab.font = self.speedLab.font; + _time.font = self.speed.font; + _calLab.font = self.speedLab.font; + _cal.font = self.speed.font; + } + return self; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + if (kIs_iPhoneX) { + CGFloat W = screenWidth * 0.92; + CGFloat H = screenHeigth * 0.3522; + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.width.mas_equalTo(W); + make.height.mas_equalTo(screenHeigth * 0.2057); + }]; + + [_date mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(H * 0.0489); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.7093); + make.width.mas_equalTo(W * 0.144); + make.height.mas_equalTo(H * 0.0594); + }]; + + [_currentTime mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.date); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.8666); + make.width.mas_equalTo(W * 0.0933); + make.height.mas_equalTo(_date); + }]; + + [_userIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(H * 0.0594); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.0506); + make.width.height.mas_equalTo(W * 0.192); + }]; + _userIcon.layer.cornerRadius = W * 0.192 / 2; + + [_userName mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(H * 0.1468); + make.left.mas_equalTo(self.userIcon.mas_right).mas_offset(W * 0.0373); + make.right.mas_equalTo(self.kmLab.mas_left).mas_offset(W * 0.0346); + make.height.mas_equalTo(H * 0.0769); + }]; + + [_kmLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(H * 0.1083); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-W * 0.136); + make.width.mas_greaterThanOrEqualTo(W * 0.2106); + make.height.mas_equalTo(H * 0.1853); + }]; + + [_km mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.kmLab.mas_top).mas_offset(H * 0.0283); + make.left.mas_equalTo(self.kmLab.mas_right); + make.bottom.mas_equalTo(_kmLab); + make.right.mas_equalTo(self.mas_right).mas_offset(W * 0.01); + }]; + + [_speedLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.kmLab.mas_bottom).mas_offset(H * 0.0369); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.04); + make.width.mas_equalTo(W * 0.208); + make.height.mas_equalTo(H * 0.1013); + }]; + + [_speed mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab.mas_bottom).mas_offset(H * 0.0049); + make.left.mas_equalTo(self.speedLab.mas_left).mas_offset(W * 0.024); + make.right.mas_equalTo(self.speedLab.mas_right).mas_offset(-W * 0.0186); + make.height.mas_equalTo(H * 0.0839); + }]; + + [_paceLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.2773); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_pace mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.paceLab.mas_left).mas_offset(W * 0.056); + make.right.mas_equalTo(self.paceLab.mas_right).mas_offset(-W * 0.056); + make.height.mas_equalTo(self.speed); + }]; + + [_timeLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.5146); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_time mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.timeLab.mas_left).mas_offset(W * 0.056); + make.right.mas_equalTo(self.timeLab.mas_right).mas_offset(-W * 0.056); + make.height.mas_equalTo(self.speed); + }]; + + [_calLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.752); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_cal mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.calLab.mas_left).mas_offset(W * 0.056); + make.right.mas_equalTo(self.calLab.mas_right).mas_offset(-W * 0.056); + make.height.mas_equalTo(self.speed); + }]; + + }else { + CGFloat W = screenWidth * 0.7761; + CGFloat H = screenHeigth * 0.3778; + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.width.mas_equalTo(W); + make.height.mas_equalTo(screenHeigth * 0.213); + }]; + + [_date mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(H * 0.0489); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.6393); + make.width.mas_equalTo(W * 0.204); + make.height.mas_equalTo(H * 0.0594); + }]; + + [_currentTime mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.date); + make.width.mas_equalTo(self.date); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-W * 0.02); + make.height.mas_equalTo(H * 0.0594); + }]; + + [_userIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(H * 0.0674); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.0506); + make.width.height.mas_equalTo(W * 0.1921); + }]; + _userIcon.layer.cornerRadius = W * 0.1921 / 2; + + [_userName mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.userIcon.mas_top).mas_offset(H * 0.0374); + make.left.mas_equalTo(self.userIcon.mas_right).mas_offset(W * 0.0373); + make.right.mas_equalTo(self.kmLab.mas_left).mas_offset(-W * 0.0346); + make.bottom.mas_equalTo(self.userIcon.mas_bottom).mas_offset(-H * 0.0374 ); + }]; + + [_kmLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(H * 0.123); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-W * 0.136); + make.width.mas_greaterThanOrEqualTo(W * 0.2106); + make.height.mas_equalTo(H * 0.2103); + }]; + + [_km mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(H * 0.1888); + make.right.mas_equalTo(self.backView.mas_right); + make.left.mas_equalTo(self.kmLab.mas_right); + make.height.mas_equalTo(H * 0.0992); + }]; + + [_speedLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.kmLab.mas_bottom).mas_offset(H * 0.0374); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.04); + make.width.mas_equalTo(W * 0.208); + make.height.mas_equalTo(H * 0.115); + }]; + + [_speed mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab.mas_bottom).mas_offset(H * 0.0059); + make.left.mas_equalTo(self.speedLab.mas_left).mas_offset(W * 0.024); + make.right.mas_equalTo(self.speedLab.mas_right).mas_offset(-W * 0.0186); + make.height.mas_equalTo(H * 0.0952); + }]; + + [_paceLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.2773); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_pace mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.paceLab.mas_left).mas_offset(W * 0.056); + make.right.mas_equalTo(self.paceLab.mas_right).mas_offset(-W * 0.056); + make.height.mas_equalTo(self.speed); + }]; + + [_timeLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.5146); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_time mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.timeLab.mas_left).mas_offset(W * 0.056); + make.right.mas_equalTo(self.timeLab.mas_right).mas_offset(-W * 0.056); + make.height.mas_equalTo(self.speed); + }]; + + [_calLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(W * 0.752); + make.width.mas_equalTo(self.speedLab); + make.height.mas_equalTo(self.speedLab); + }]; + + [_cal mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speed); + make.left.mas_equalTo(self.calLab.mas_left).mas_offset(W * 0.056); + make.right.mas_equalTo(self.calLab.mas_right).mas_offset(-W * 0.056); + make.height.mas_equalTo(self.speed); + }]; + } +} +@end diff --git a/MRMobileRun/MRRunning/MGDShareModel.h b/MRMobileRun/MRRunning/MGDShareModel.h new file mode 100644 index 0000000..2c3a235 --- /dev/null +++ b/MRMobileRun/MRRunning/MGDShareModel.h @@ -0,0 +1,25 @@ +// +// MGDShareModel.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDShareModel : NSObject + +//分享标题 只分享文本是也用这个字段 +@property (nonatomic,copy) NSString *title; +//描述内容 +@property (nonatomic,copy) NSString *descr; +//缩略图 +@property (nonatomic,strong) id thumbImage; +//链接 +@property (nonatomic,copy) NSString *url; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/MGDShareModel.m b/MRMobileRun/MRRunning/MGDShareModel.m new file mode 100644 index 0000000..471e0d7 --- /dev/null +++ b/MRMobileRun/MRRunning/MGDShareModel.m @@ -0,0 +1,12 @@ +// +// MGDShareModel.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +#import "MGDShareModel.h" + +@implementation MGDShareModel + +@end diff --git a/MRMobileRun/MRRunning/MGDSharePlatform.h b/MRMobileRun/MRRunning/MGDSharePlatform.h new file mode 100644 index 0000000..a5abbe7 --- /dev/null +++ b/MRMobileRun/MRRunning/MGDSharePlatform.h @@ -0,0 +1,19 @@ +// +// MGDSharePlatform.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +#import + + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDSharePlatform : NSObject +@property (nonatomic,copy) NSString *iconStateNormal; +@property (nonatomic,copy) NSString *iconStateHighlighted; +@property (nonatomic,copy) NSString *name; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/MGDSharePlatform.m b/MRMobileRun/MRRunning/MGDSharePlatform.m new file mode 100644 index 0000000..dad793c --- /dev/null +++ b/MRMobileRun/MRRunning/MGDSharePlatform.m @@ -0,0 +1,12 @@ +// +// MGDSharePlatform.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +#import "MGDSharePlatform.h" + +@implementation MGDSharePlatform + +@end diff --git a/MRMobileRun/MRRunning/MGDShareView.h b/MRMobileRun/MRRunning/MGDShareView.h new file mode 100644 index 0000000..c9087a3 --- /dev/null +++ b/MRMobileRun/MRRunning/MGDShareView.h @@ -0,0 +1,51 @@ +// +// MGDShareView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +//这个View是跑完步后点击分享后弹出的View,是一个整体的大的透明的UIView,上面有一个占据部分的View,上方是一个大的UIImageView,用来展示截取的关于跑步信息的图片,下面是两个小的UIImageView和一个Label,两个小的UIImageView自己看逻辑来获取,最下面是取消按钮和一个放置五个按钮的view,按钮的具体逻辑自己实现就行了 +#import + +NS_ASSUME_NONNULL_BEGIN +@class MGDShareView; + +@protocol MGDShareViewDelegate + +- (NSArray *_Nullable)platformImageArray:(NSString *_Nullable)imageArray; + +- (NSArray *_Nullable)platformTitleArray:(NSString *_Nullable)titleArray; + +@end + +@interface MGDShareView : UIView + +- (instancetype)initWithShotImage:(NSString *)shotImage logoImage:(NSString *)logo QRcodeImage:(NSString *)QRcode; + +@property (nonatomic, strong)NSArray *bootomBtns; //保存着分享的五个按钮的数组 + +@property (nonatomic, strong) UIView *backView; + +@property (nonatomic, strong) UIView *popView; + +@property (nonatomic, strong) UIImageView *shotImage; + +@property (nonatomic, strong) UIImageView *logoImage; + +@property (nonatomic, strong) UIImageView *QRImage; + +@property (nonatomic, strong) UILabel *shareLab; + +@property (nonatomic, strong) UIButton *cancelBtn; + +@property (nonatomic, strong) UIView *bottomView; + +@property (nonatomic, strong) UIView *btnbackView; + +@property (nonatomic, strong) UIView *dataView; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/MRMobileRun/MRRunning/MGDShareView.m b/MRMobileRun/MRRunning/MGDShareView.m new file mode 100644 index 0000000..415df90 --- /dev/null +++ b/MRMobileRun/MRRunning/MGDShareView.m @@ -0,0 +1,342 @@ +// +// MGDShareView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +#import "MGDShareView.h" +#import +#import + +#define SHAWDOWCOLOR [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.1] +#define CANCELCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1] +#define UNITCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] +@interface MGDShareView() + + +@end + +@implementation MGDShareView + +- (instancetype)initWithShotImage:(NSString *)shotImage logoImage:(NSString *)logo QRcodeImage:(NSString *)QRcode { + if (self = [super init]) { + self.frame = [UIScreen mainScreen].bounds; + //整体的透明的背景 + _backView = [[UIView alloc] init]; + _backView.backgroundColor = [UIColor clearColor]; + [self addSubview:_backView]; + + //底部的按钮的View + _bottomView = [[UIView alloc] init]; + [self.backView addSubview:_bottomView]; +// + NSMutableArray *btnAry = [NSMutableArray array]; + //创建五个View,包括内部的Btn和Lable,后面约束一下内部的位置 + CGFloat gap = (screenWidth - 52 - 250) / 4; + for (int i = 1;i <= 5; i++) { + //View + _btnbackView = [[UIView alloc] init]; + _btnbackView.backgroundColor = [UIColor clearColor]; + [self.bottomView addSubview:_btnbackView]; + CGFloat x = 26 + (gap + 50) * (i-1); + //View布局 + if (kIs_iPhoneX) { + [_btnbackView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.popView.mas_bottom).mas_offset(50); //(64) + make.left.mas_equalTo(self.mas_left).mas_offset(x); + make.bottom.mas_equalTo(self.cancelBtn.mas_top).mas_offset(-18); + make.width.equalTo(@50); + }]; + }else { + [_btnbackView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.popView.mas_bottom).mas_offset(screenHeigth * 0.1069); //(69) + make.left.mas_equalTo(self.mas_left).mas_offset(x); + make.bottom.mas_equalTo(self.cancelBtn.mas_top).mas_offset(-15); + make.width.equalTo(@50); + }]; + } + + //Button + UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; + [btn setImage:[UIImage imageNamed:[NSString stringWithFormat:@"分享%d",i]] forState:UIControlStateNormal]; + [btn setBackgroundColor:[UIColor clearColor]]; + [_btnbackView addSubview:btn]; + [btn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.btnbackView.mas_top); + make.left.mas_equalTo(self.btnbackView.mas_left).mas_offset(screenWidth * 0.0267); + make.width.mas_equalTo(30); + make.height.mas_equalTo(30); + }]; + //为btn添加标记,等待在controller里为button添加逻辑操作 + btn.tag = i; + [btnAry addObject:btn]; + + //Lable + UILabel *label = [[UILabel alloc] init]; + label.tag = 5 + i; + label.textAlignment = NSTextAlignmentCenter; + label.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + label.textColor = [UIColor colorWithRed:136/255.0 green:141/255.0 blue:151/255.0 alpha:1.0]; + [_btnbackView addSubview:label]; + [label mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(50, 17)); + make.centerX.bottom.equalTo(_btnbackView); + }]; + //设置五个label的内容 + switch (label.tag) { + case 6: + label.text = @"保存图片"; + break; + case 7: + label.text = @"QQ"; + break; + case 8: + label.text = @"QQ空间"; + break; + case 9: + label.text = @"微信"; + break; + case 10: + label.text = @"朋友圈"; + break; + default: + break; + } + } + self.bootomBtns = btnAry; //将循环创建的btn保存下来等待在coontrller里面进行逻辑操作 + + + + //弹出的View + _popView = [[UIView alloc] init]; + + _popView.layer.cornerRadius = 12; + _popView.layer.shadowColor = SHAWDOWCOLOR.CGColor; + _popView.layer.shadowOffset = CGSizeMake(0,2); + _popView.layer.shadowOpacity = 1; + _popView.layer.shadowRadius = 6; + [self showView]; + [self.backView addSubview:_popView]; + + //地图 + _shotImage = [[UIImageView alloc] init]; + _shotImage.backgroundColor = [UIColor clearColor]; + _shotImage.layer.cornerRadius = 12; + _shotImage.layer.shadowColor = SHAWDOWCOLOR.CGColor; + _shotImage.layer.shadowOffset = CGSizeMake(0,2); + _shotImage.layer.shadowOpacity = 1; + _shotImage.layer.shadowRadius = 6; + _shotImage.layer.masksToBounds = YES; + [self.popView addSubview:_shotImage]; + + //信息 + _dataView = [[UIView alloc] init]; + _dataView.backgroundColor = [UIColor clearColor]; + [self.popView addSubview:_dataView]; + + //两个小的UIImageview + _logoImage = [[UIImageView alloc] init]; + _logoImage.backgroundColor = [UIColor clearColor]; + _logoImage.layer.cornerRadius = 6; + _logoImage.contentMode = UIViewContentModeScaleAspectFill; + _logoImage.clipsToBounds = YES; + _logoImage.image = [UIImage imageNamed:@"约跑"]; + [self.popView addSubview:_logoImage]; + + _QRImage = [[UIImageView alloc] init]; + _QRImage.backgroundColor = [UIColor lightGrayColor]; + _QRImage.layer.cornerRadius = 6; + [self.popView addSubview:_QRImage]; + //实现长按识别二维码,无二维码,未实现 + + _shareLab = [[UILabel alloc] init]; + _shareLab.textAlignment = NSTextAlignmentLeft; + _shareLab.numberOfLines = 0; + _shareLab.text = @"长按识别二维码\n加入约跑和我一起跑步"; + [self.popView addSubview:_shareLab]; + + //取消按钮 + _cancelBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + [_cancelBtn setTitle:@"取消" forState:UIControlStateNormal]; + _cancelBtn.titleLabel.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 16]; + _cancelBtn.tintColor = CANCELCOLOR; + [self.backView addSubview:_cancelBtn]; + + if (@available(iOS 11.0, *)) { + self.bottomView.backgroundColor = bottomColor; + self.shareLab.tintColor = MGDTextColor2; + [self.cancelBtn setBackgroundColor:MGDColor1]; + self.popView.backgroundColor = bottomColor; + } else { + // Fallback on earlier versions + } + } + return self; +} + + + +- (void)layoutSubviews { + [super layoutSubviews]; + if (kIs_iPhoneX) { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(screenHeigth * 0.0825); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.bottom.mas_equalTo(self.mas_bottom); + }]; + + [_popView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top); + make.left.mas_equalTo(self.mas_left).mas_offset(screenWidth * 0.04); + make.right.mas_equalTo(self.mas_right).mas_offset(-screenWidth * 0.04); + make.height.mas_equalTo(screenHeigth * 0.697); + }]; + + [_shotImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.popView.mas_top); + make.left.mas_equalTo(self.popView.mas_left); + make.right.mas_equalTo(self.popView.mas_right); +// make.height.mas_equalTo(screenHeigth * 0.3965); + make.bottom.mas_equalTo(self.popView.mas_bottom).mas_offset(-screenHeigth * 0.0948); + }]; + + [_dataView mas_makeConstraints:^(MASConstraintMaker *make) { +// make.top.mas_equalTo(self.shotImage.mas_bottom); + make.top.mas_equalTo(self.popView.mas_top).offset(screenHeigth * 0.3965); + make.left.mas_equalTo(self.popView.mas_left); + make.right.mas_equalTo(self.popView.mas_right); + make.bottom.mas_equalTo(self.popView.mas_bottom).mas_offset(-screenHeigth * 0.0948); + }]; + + [_logoImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.dataView.mas_bottom).mas_offset(screenHeigth * 0.0135); + make.left.mas_equalTo(self.popView.mas_left).mas_offset(screenWidth * 0.0347); + make.height.mas_equalTo(screenHeigth * 0.0666); + make.width.mas_equalTo(screenWidth * 0.1565); + }]; + + [_QRImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.dataView.mas_bottom).mas_offset(screenHeigth * 0.0123); + make.right.mas_equalTo(self.popView.mas_right).mas_offset(-screenWidth * 0.0434); + make.width.mas_equalTo(self.logoImage); + make.height.mas_equalTo(self.logoImage); + }]; + + [_shareLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.dataView.mas_bottom).mas_offset(screenHeigth * 0.0283); + make.left.mas_equalTo(self.logoImage.mas_right).mas_offset(screenWidth * 0.04); + make.width.mas_equalTo(screenWidth * 0.3623); + make.height.mas_equalTo(screenHeigth * 0.0418); + }]; + _shareLab.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + + [_bottomView mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.mas_equalTo(self.cancelBtn.mas_top); + make.left.mas_equalTo(self.backView.mas_left); + make.right.mas_equalTo(self.backView.mas_right); + make.height.mas_equalTo(screenHeigth * 0.1588); + }]; + + [_cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.mas_equalTo(self.mas_bottom); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth * 0.0986); + }]; + + }else { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(screenHeigth * 0.0599); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.bottom.mas_equalTo(self.mas_bottom); + }]; + + [_popView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(screenWidth * 0.1093); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-screenWidth * 0.1146); + make.height.mas_equalTo(screenHeigth * 0.7196); + }]; + + [_shotImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.popView.mas_top); + make.left.mas_equalTo(self.popView.mas_left); + make.right.mas_equalTo(self.popView.mas_right); + make.height.mas_equalTo(screenHeigth * 0.4092); + }]; + + [_dataView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.shotImage.mas_bottom); + make.left.mas_equalTo(self.popView.mas_left); + make.right.mas_equalTo(self.popView.mas_right); + make.bottom.mas_equalTo(self.popView.mas_bottom).mas_offset(-screenHeigth * 0.0974); + }]; + + [_logoImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.dataView.mas_bottom).mas_offset(screenHeigth * 0.0134); + make.left.mas_equalTo(self.popView.mas_left).mas_offset(screenWidth * 0.0266); + make.bottom.mas_equalTo(_QRImage); + make.right.mas_equalTo(self.popView.mas_right).mas_offset(-screenWidth * 0.6266); + }]; + + [_QRImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.dataView.mas_bottom).mas_offset(screenHeigth * 0.0119); + make.right.mas_equalTo(self.popView.mas_right).mas_offset(-screenWidth * 0.0293); + make.bottom.mas_equalTo(self.popView.mas_bottom).mas_offset(-screenHeigth * 0.0164); + make.left.mas_equalTo(self.popView.mas_left).mas_offset(screenWidth * 0.6239); + }]; + + [_shareLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.dataView.mas_bottom).mas_offset(screenHeigth * 0.0299); + make.left.mas_equalTo(self.logoImage.mas_right).mas_offset(screenWidth * 0.0319); + make.width.mas_equalTo(screenWidth * 0.4639); + make.height.mas_equalTo(screenHeigth * 0.0583); + }]; + _shareLab.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 10]; + + [_bottomView mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.mas_equalTo(self.cancelBtn.mas_top); + make.left.mas_equalTo(self.backView.mas_left); + make.right.mas_equalTo(self.backView.mas_right); + make.height.mas_equalTo(screenHeigth * 0.2428); + }]; + + [_cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.mas_equalTo(self.mas_bottom); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth * 0.069); + }]; + } +} + +//添加底部分享的按钮和label +- (void)addBootomBtnAndLbl{ + // +} + +-(void)showView{ + + [[UIApplication sharedApplication].keyWindow addSubview:self]; + + CGAffineTransform transform = CGAffineTransformScale(CGAffineTransformIdentity,1.0,1.0); + + self.popView.transform = CGAffineTransformScale(CGAffineTransformIdentity,0.2,0.2); + self.popView.alpha = 0; + [UIView animateWithDuration:0.2 delay:0.2 usingSpringWithDamping:0.5 initialSpringVelocity:10 options:UIViewAnimationOptionCurveLinear animations:^{ + self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:.4f]; + self.popView.transform = transform; + self.popView.alpha = 1; + } completion:^(BOOL finished) { + + }]; + +} + + +@end + + diff --git a/MRMobileRun/MRRunning/MRAlertView.h b/MRMobileRun/MRRunning/MRAlertView.h deleted file mode 100755 index d369712..0000000 --- a/MRMobileRun/MRRunning/MRAlertView.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// MRAlertView.h -// MRAlertView -// -// Created by RainyTunes on 2017/2/19. -// Copyright © 2017年 We.Can. All rights reserved. -// - -#import - -@interface MRAlertView : UIView -+ (instancetype)alertViewWithTitle:(NSString *)title action:(void(^)())handler; -@property UIButton *okButton; -@property UIButton *cancelButton; -@property UIView *effectView; -@property (nonatomic,strong)NSString *hideIdentifier; - -@end diff --git a/MRMobileRun/MRRunning/MRAlertView.m b/MRMobileRun/MRRunning/MRAlertView.m deleted file mode 100755 index d626f75..0000000 --- a/MRMobileRun/MRRunning/MRAlertView.m +++ /dev/null @@ -1,264 +0,0 @@ -// -// MRAlertView.m -// MRAlertView -// -// Created by RainyTunes on 2017/2/19. -// Copyright © 2017年 We.Can. All rights reserved. -// - -#import "MRAlertView.h" -#import "Masonry.h" -#import "WeKit.h" - -typedef void(^MRAlertBlock)(); - -static const NSInteger alertColor = 0xef6253; -static const NSInteger normalColor = 0x7A5595; -static const NSInteger textColor = 0xB4ABC5; - -@interface MRAlertView() -@property UIImageView *alertWindowImageView; -@property UIImageView *remindImageView; -@property UIImageView *horizonalLine; -@property UIImageView *verticalLine; -@property UILabel *alertTextLabel; -@property UILabel *alertTitleLabel; - -@property NSString *remindText; -@property NSInteger remindTextLines; -@property CGFloat rateX; -@property CGFloat rateY; - - -//用于判断点击弹窗外区域是否隐藏 - -@property MRAlertBlock block; - -@end -@implementation MRAlertView - -- (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - self.rateX = ScreenWidth / 375; - self.rateY = ScreenHeight / 667; - [self initEffectView]; - [self initAlertView]; - } - return self; -} - -- (instancetype)init { - self = [self initWithFrame:ScreenFrame]; - return self; -} - - -/** - 弹框的初始化 - - @param title 字符串,弹框提示语 - @param block 代码块,点击确认后的回调 - @return 弹框View自身 - */ -+ (instancetype)alertViewWithTitle:(NSString *)title action:(void(^)())block { - MRAlertView *alertView = [[MRAlertView alloc] init]; - alertView.remindText = title; - alertView.block = block; - return alertView; -} - -- (void)updateConstraints { - - /** - alertWindows - */ - - UIEdgeInsets insets1 = UIEdgeInsetsMake(self.rateY * 209.5, self.rateX * 36, self.rateY * 253.5, self.rateX * 33); - [self.alertWindowImageView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.mas_top).with.offset(insets1.top); //with is an optional semantic filler - make.left.equalTo(self.mas_left).with.offset(insets1.left); - make.bottom.equalTo(self.mas_bottom).with.offset(-insets1.bottom); - make.right.equalTo(self.mas_right).with.offset(-insets1.right); - }]; - - /** - remindIcon - */ - - UIEdgeInsets insets2 = UIEdgeInsetsMake(self.rateY * 34.5, self.rateX * 121, self.rateY * 143.5, self.rateX * 159); - [self.remindImageView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.alertWindowImageView.mas_top).with.offset(insets2.top); //with is an optional semantic filler - make.left.equalTo(self.alertWindowImageView.mas_left).with.offset(insets2.left); - make.bottom.equalTo(self.alertWindowImageView.mas_bottom).with.offset(-insets2.bottom); - make.right.equalTo(self.alertWindowImageView.mas_right).with.offset(-insets2.right); - }]; - - /** - alertTitleLabel - */ - - UIEdgeInsets insets3 = UIEdgeInsetsMake(self.rateY * 35, self.rateX * 154.5, self.rateY * 144, self.rateX * 115); -// self.alertTitleLabel.backgroundColor = [UIColor redColor]; - [self.alertTitleLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.alertWindowImageView.mas_top).with.offset(insets3.top); //with is an optional semantic filler - make.left.equalTo(self.alertWindowImageView.mas_left).with.offset(insets3.left); - make.width.equalTo(@(60*self.rateX)); - make.height.equalTo(@(25*self.rateY)); - }]; - - /** - alertTextLabel - */ - - UIEdgeInsets insets4 = UIEdgeInsetsMake(self.rateY * 81, self.rateX * 30.5, self.rateY * 83, self.rateX * 32); - self.alertTextLabel.text = self.remindText; - [self.alertTextLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.alertWindowImageView.mas_top).with.offset(insets4.top); //with is an optional semantic filler - make.left.equalTo(self.alertWindowImageView.mas_left).with.offset(insets4.left); - make.bottom.equalTo(self.alertWindowImageView.mas_bottom).with.offset(-insets4.bottom); - make.right.equalTo(self.alertWindowImageView.mas_right).with.offset(-insets4.right); - }]; - - /** - horizonalLine - */ - - UIEdgeInsets insets5 = UIEdgeInsetsMake(self.rateY * 148.5, self.rateX * 0, self.rateY * 54.5, self.rateX * 0); - [self.horizonalLine mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.alertWindowImageView.mas_top).with.offset(insets5.top); //with is an optional semantic filler - make.left.equalTo(self.alertWindowImageView.mas_left).with.offset(insets5.left); - make.bottom.equalTo(self.alertWindowImageView.mas_bottom).with.offset(-insets5.bottom); - make.right.equalTo(self.alertWindowImageView.mas_right).with.offset(-insets5.right); - }]; - - /** - verticalLine - */ - - UIEdgeInsets insets6 = UIEdgeInsetsMake(self.rateY * 149.5, self.rateX * 152, self.rateY * 0, self.rateX * 153); - [self.verticalLine mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.alertWindowImageView.mas_top).with.offset(insets6.top); - make.left.equalTo(self.alertWindowImageView.mas_left).with.offset(insets6.left); - make.width.equalTo(@(1*self.rateX)); - make.height.equalTo(@(54.5*self.rateY)); - }]; - - /** - cancelButton - */ - - UIEdgeInsets insets7 = UIEdgeInsetsMake(self.rateY * 148.5, self.rateX * 0, self.rateY * 16, self.rateX * 60.5); -// self.cancelButton.backgroundColor = [UIColor blueColor]; - [self.cancelButton addTarget:self action:@selector(clickCancelButton) forControlEvents:UIControlEventTouchUpInside]; - [self.cancelButton mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.alertWindowImageView.mas_top).with.offset(insets7.top); //with is an optional semantic filler - make.left.equalTo(self.alertWindowImageView.mas_left).with.offset(insets7.left); - make.width.equalTo(@(153*self.rateX)); - make.height.equalTo(@(54.5*self.rateY)); - }]; - - /** - okButton - */ - - UIEdgeInsets insets8 = UIEdgeInsetsMake(self.rateY * 148.5, self.rateX * 153, self.rateY * 16.5, self.rateX * 208.5); -// self.okButton.backgroundColor = [UIColor blackColor]; - [self.okButton addTarget:self action:@selector(clickOkButton) forControlEvents:UIControlEventTouchUpInside]; - [self.okButton mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.alertWindowImageView.mas_top).with.offset(insets8.top); //with is an optional semantic filler - make.left.equalTo(self.alertWindowImageView.mas_left).with.offset(insets8.left); - make.width.equalTo(@(153*self.rateX)); - make.height.equalTo(@(54.5*self.rateY)); - }]; - [super updateConstraints]; -} - -- (void)initEffectView { - self.effectView = [[UIView alloc] initWithFrame:ScreenFrame]; - self.effectView.backgroundColor = [UIColor colorWithRed:114.0/255 green:109.0/255 blue:131.0/255 alpha:0.62]; - self.effectView.userInteractionEnabled = YES; - if ([self.hideIdentifier isEqualToString:@"Yes"]) { - [self.effectView addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(clickEffectView)]]; - } - - - [self addSubview:self.effectView]; -} - -- (void)initAlertView { - UIImage *alertWindowImage = [UIImage imageNamed:@"过短弹窗"]; - self.alertWindowImageView = [[UIImageView alloc] initWithImage:alertWindowImage]; - self.alertWindowImageView.userInteractionEnabled = YES; - [self addSubview:self.alertWindowImageView]; - - UIImage *remindIcon = [UIImage imageNamed:@"提示icon"]; - self.remindImageView = [[UIImageView alloc] initWithImage:remindIcon]; - [self.alertWindowImageView addSubview:self.remindImageView]; - - UIImage *lineImage1 = [UIImage imageNamed:@"横分割线2"]; - self.horizonalLine = [[UIImageView alloc] initWithImage:lineImage1]; - [self.alertWindowImageView addSubview:self.horizonalLine]; - - UIImage *lineImage2 = [UIImage imageNamed:@"束分割线2"]; - self.verticalLine = [[UIImageView alloc] initWithImage:lineImage2]; - [self.alertWindowImageView addSubview:self.verticalLine]; - - self.cancelButton = [[UIButton alloc] init]; - [self.cancelButton setTitle:@"取消" forState:UIControlStateNormal]; - [self.cancelButton setTitleColor:UIColorFromRGB(alertColor) forState:UIControlStateNormal]; - [self.alertWindowImageView addSubview:self.cancelButton]; - - self.okButton = [[UIButton alloc] init]; - [self.okButton setTitle:@"确定" forState:UIControlStateNormal]; - [self.okButton setTitleColor:UIColorFromRGB(normalColor) forState:UIControlStateNormal]; - [self.alertWindowImageView addSubview:self.okButton]; - - - self.alertTextLabel = [[UILabel alloc] init]; - self.alertTextLabel.numberOfLines = -1; - self.alertTextLabel.textAlignment = NSTextAlignmentCenter; - [self.alertTextLabel setText:self.remindText]; - self.alertTextLabel.font = [UIFont fontWithName:@"Helvetica" size:14]; - [self.alertTextLabel setTextColor:UIColorFromRGB(textColor)]; - self.remindTextLines = self.remindText.length / 2 / (243.5 * self.rateX / 14); - [self.alertWindowImageView addSubview:self.alertTextLabel]; - - self.alertTitleLabel = [[UILabel alloc] init]; - [self.alertTitleLabel setText:@"提示"]; - self.alertTitleLabel.font = [UIFont fontWithName:@"Helvetica" size:18.0 * screenHeigth/667.0]; - [self.alertTitleLabel setTextColor:UIColorFromRGB(textColor)]; - [self.alertWindowImageView addSubview:self.alertTitleLabel]; - - self.hideIdentifier = @"Yes"; - -} - -- (void)clickOkButton { - self.hidden = YES; - self.block(); -} - -- (void)clickCancelButton { - self.hidden = YES; -} - -- (void)clickEffectView { - self.hidden = YES; -} - - -+ (BOOL)requiresConstraintBasedLayout { - return YES; -} - - -/* -// Only override drawRect: if you perform custom drawing. -// An empty implementation adversely affects performance during animation. -- (void)drawRect:(CGRect)rect { - // Drawing code -} -*/ - -@end diff --git a/MRMobileRun/MRRunning/MRPauseAndResumeBtu.h b/MRMobileRun/MRRunning/MRPauseAndResumeBtu.h deleted file mode 100755 index da4556f..0000000 --- a/MRMobileRun/MRRunning/MRPauseAndResumeBtu.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// MRPauseAndResumeBtu.h -// MobileRun -// -// Created by 郑沛越 on 2017/2/9. -// Copyright © 2017年 郑沛越. All rights reserved. -// - -#import - -@interface MRPauseAndResumeBtu : UIButton -- (instancetype)init; - -@end diff --git a/MRMobileRun/MRRunning/MRPauseAndResumeBtu.m b/MRMobileRun/MRRunning/MRPauseAndResumeBtu.m deleted file mode 100755 index 7fa8d3b..0000000 --- a/MRMobileRun/MRRunning/MRPauseAndResumeBtu.m +++ /dev/null @@ -1,62 +0,0 @@ -// -// MRPauseAndResumeBtu.m -// MobileRun -// -// Created by 郑沛越 on 2017/2/9. -// Copyright © 2017年 郑沛越. All rights reserved. -// - -#import "MRPauseAndResumeBtu.h" -#import -@interface MRPauseAndResumeBtu () - -@property (nonatomic,strong) UIImageView *pauseAndResumeImageView; - -@end - -@implementation MRPauseAndResumeBtu - -//这个是暂停和继续按钮 -- (instancetype)init{ - if (self =[super init]) { - [self initpauseAndResumeBtu]; - return self; - } - return self; - -} - -- (void)initpauseAndResumeBtu{ - self.frame = CGRectMake(0, 0, 183, 183); - [self setTitle:@"暂停" forState:UIControlStateNormal]; - - [self setBackgroundImage:[UIImage imageNamed:@"暂停按钮"] forState:UIControlStateNormal]; - [self addTarget:self action:@selector(pause) forControlEvents:UIControlEventTouchUpInside]; - self.titleLabel.font = [UIFont boldSystemFontOfSize:20.0*screenWidth/414.0]; - -// self.contentEdgeInsets = UIEdgeInsetsMake(screenHeigth *59.0 /1334,screenWidth *59.0/750, screenHeigth *95.0 /1334, screenWidth *47.0/750); -// [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { -// make.centerX.equalTo(self.mas_centerX); -// make.centerY.equalTo(self.mas_centerY); -// }]; -} - -- (void)pause{ - if ([self.titleLabel.text isEqualToString:@"暂停"]) { - - [self setBackgroundImage:[UIImage imageNamed:@"继续按钮"] forState:UIControlStateNormal]; - [self addTarget:self action:@selector(resume) forControlEvents:UIControlEventTouchUpInside]; - [self setTitle:@"继续" forState:UIControlStateNormal]; - } -} - -- (void)resume{ - - if ([self.titleLabel.text isEqualToString:@"继续"]) { - - [self setBackgroundImage:[UIImage imageNamed:@"暂停按钮"] forState:UIControlStateNormal]; - [self addTarget:self action:@selector(pause) forControlEvents:UIControlEventTouchUpInside]; - [self setTitle:@"暂停" forState:UIControlStateNormal]; - } -} -@end diff --git a/MRMobileRun/MRRunning/MRRunningLabel.h b/MRMobileRun/MRRunning/MRRunningLabel.h deleted file mode 100755 index 28ac388..0000000 --- a/MRMobileRun/MRRunning/MRRunningLabel.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// MRRunningLabel.h -// MobileRun -// -// Created by 郑沛越 on 2017/2/27. -// Copyright © 2017年 郑沛越. All rights reserved. -// - -#import - -@interface MRRunningLabel : UILabel -- (instancetype)init; -@end diff --git a/MRMobileRun/MRRunning/MRRunningLabel.m b/MRMobileRun/MRRunning/MRRunningLabel.m deleted file mode 100755 index 770f2fd..0000000 --- a/MRMobileRun/MRRunning/MRRunningLabel.m +++ /dev/null @@ -1,28 +0,0 @@ - -// -// MRRunningLabel.m -// MobileRun -// -// Created by 郑沛越 on 2017/2/27. -// Copyright © 2017年 郑沛越. All rights reserved. -// - -#import "MRRunningLabel.h" - -@implementation MRRunningLabel - -- (instancetype)init{ - if (self = [super init]) { - [self initRunningTimeLabel]; - return self; - } - return self; -} - - -- (void)initRunningTimeLabel{ - self.text = @"00:00:00"; - self.font = [UIFont fontWithName:@"DINAlternate-Bold" size:32 *screenWidth/414.0]; - -} -@end diff --git a/MRMobileRun/MRRunning/MRStopBtu.h b/MRMobileRun/MRRunning/MRStopBtu.h deleted file mode 100755 index 30da46d..0000000 --- a/MRMobileRun/MRRunning/MRStopBtu.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// MRStopBtu.h -// MobileRun -// -// Created by 郑沛越 on 2017/2/9. -// Copyright © 2017年 郑沛越. All rights reserved. -// - -#import - -@interface MRStopBtu : UIButton -- (instancetype)init; - -@end diff --git a/MRMobileRun/MRRunning/MRStopBtu.m b/MRMobileRun/MRRunning/MRStopBtu.m deleted file mode 100755 index 8eff853..0000000 --- a/MRMobileRun/MRRunning/MRStopBtu.m +++ /dev/null @@ -1,37 +0,0 @@ - - - -// -// MRStopBtu.m -// MobileRun -// -// Created by 郑沛越 on 2017/2/9. -// Copyright © 2017年 郑沛越. All rights reserved. -// - -#import "MRStopBtu.h" -#import - -@implementation MRStopBtu - -- (instancetype)init{ - if (self =[super init]) { - [self initStopBtu]; - return self; - } - return self; - -} - -- (void)initStopBtu{ - self.frame = CGRectMake(0, 0, 183, 183); - [self setBackgroundImage:[UIImage imageNamed:@"结束按钮"] forState:UIControlStateNormal]; -// [self addTarget:self action:@selector(pause) forControlEvents:UIControlEventTouchUpInside]; - [self setTitle:@"结束" forState:UIControlStateNormal]; - self.titleLabel.font = [UIFont boldSystemFontOfSize:18*screenWidth/414.0]; - [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerX.equalTo(self.mas_centerX); - make.centerY.equalTo(self.mas_centerY); - }]; -} -@end diff --git a/MRMobileRun/MRRunning/RecordtimeString.h b/MRMobileRun/MRRunning/RecordtimeString.h new file mode 100644 index 0000000..ebb89f0 --- /dev/null +++ b/MRMobileRun/MRRunning/RecordtimeString.h @@ -0,0 +1,17 @@ +// +// RecordtimeString.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/29. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RecordtimeString : NSObject ++ (NSString *)getTimeStringWithSeconds:(int )second; ++ (NSString *)getMinutesTimeStringWithSeconds:(int )second; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/RecordtimeString.m b/MRMobileRun/MRRunning/RecordtimeString.m new file mode 100644 index 0000000..5cde43f --- /dev/null +++ b/MRMobileRun/MRRunning/RecordtimeString.m @@ -0,0 +1,61 @@ +// +// RecordtimeString.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/29. +// + +#import "RecordtimeString.h" + +@implementation RecordtimeString +//将秒数转化为HH:MM:SS格式数据的一个方法 ++ (NSString *)getTimeStringWithSeconds:(int)second{ + NSString *timeString = [[NSString alloc] init]; + + NSString *secondString = [[NSString alloc] init]; + NSString *minuteString = [[NSString alloc] init]; + NSString *hourString = [[NSString alloc] init]; + + NSString *secondStr = [NSString stringWithFormat:@"%d",second%3600%60]; + + if (second%3600%60 <10 ) { + secondString = [NSString stringWithFormat:@"%@%@",@"0",secondStr]; + } + else{ + secondString = [NSString stringWithFormat:@"%@",secondStr]; + } + + NSString * minuteStr = [NSString stringWithFormat:@"%d",second%3600/60]; + + if (second%3600/60<10) { + minuteString = [NSString stringWithFormat:@"%@%@",@"0",minuteStr]; + } + else{ + minuteString = [NSString stringWithFormat:@"%@",minuteStr]; + + } + NSString * hourStr = [NSString stringWithFormat:@"%d",second/3600]; + if (second/3600 <10) { + hourString = [NSString stringWithFormat:@"%@%@",@"0",hourStr]; + } + else{ + hourString = [NSString stringWithFormat:@"%@",hourStr]; + + } + timeString = [NSString stringWithFormat:@"%@%@%@%@%@",hourString,@":",minuteString,@":",secondString]; + NSLog(@"%@",timeString); + + return timeString; +} ++ (NSString *)getMinutesTimeStringWithSeconds:(int)second{ + NSString *str_minute = [[NSString alloc] init]; + NSString *str_second = [NSString stringWithFormat:@"%02ld",(long)second%60]; +// if (second >= 6000) { +// str_minute = [NSString stringWithFormat:@"%03ld",(long)(second%3600)/60]; +// }else { + str_minute = [NSString stringWithFormat:@"%02ld",(long)(second%3600)/60]; +// } + NSString *format_time = [NSString stringWithFormat:@"%@:%@",str_minute,str_second]; + return format_time; +} +@end diff --git a/MRMobileRun/MRRunning/RunLocationModel.h b/MRMobileRun/MRRunning/RunLocationModel.h new file mode 100644 index 0000000..855cb39 --- /dev/null +++ b/MRMobileRun/MRRunning/RunLocationModel.h @@ -0,0 +1,21 @@ +// +// RunLocationModel.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/22. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RunLocationModel : NSObject +@property (nonatomic, strong) CLLocation *LOCATION; +@property (nonatomic, assign) CLLocationCoordinate2D location; +@property (nonatomic, assign) CLLocationSpeed speed; +@property (nonatomic, strong) NSDate *time; //记录每个定位点的时间 + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/RunLocationModel.m b/MRMobileRun/MRRunning/RunLocationModel.m new file mode 100644 index 0000000..d7b6580 --- /dev/null +++ b/MRMobileRun/MRRunning/RunLocationModel.m @@ -0,0 +1,12 @@ +// +// RunLocationModel.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/22. +// + +#import "RunLocationModel.h" + +@implementation RunLocationModel + +@end diff --git a/MRMobileRun/MRRunning/RunMainBtn.h b/MRMobileRun/MRRunning/RunMainBtn.h new file mode 100644 index 0000000..82baade --- /dev/null +++ b/MRMobileRun/MRRunning/RunMainBtn.h @@ -0,0 +1,19 @@ +// +// RunMainBtn.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/24. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RunMainBtn : UIButton +@property (nonatomic, strong) UIImageView *logoImg; +@property (nonatomic, strong) UILabel *descLbl; + +- (void)initRunBtn;; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/RunMainBtn.m b/MRMobileRun/MRRunning/RunMainBtn.m new file mode 100644 index 0000000..c69adf5 --- /dev/null +++ b/MRMobileRun/MRRunning/RunMainBtn.m @@ -0,0 +1,34 @@ +// +// RunMainBtn.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/24. +// + +#import "RunMainBtn.h" +#import +@implementation RunMainBtn +- (void)initRunBtn{ + + self.logoImg = [[UIImageView alloc] init]; + [self addSubview:self.logoImg]; + [self.logoImg mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self); + make.centerY.equalTo(self).offset(-5); + make.size.mas_equalTo(CGSizeMake(30, 30)); + }]; + + self.descLbl = [[UILabel alloc] init]; + [self addSubview:self.descLbl]; + [self.descLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.logoImg); + make.top.equalTo(self.logoImg.mas_bottom); + make.size.mas_equalTo(CGSizeMake(48, 17)); + }]; + self.descLbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + self.descLbl.textAlignment = NSTextAlignmentCenter; + +} + + +@end diff --git a/MRMobileRun/MRRunning/RunMainPageCV.h b/MRMobileRun/MRRunning/RunMainPageCV.h new file mode 100644 index 0000000..726b22f --- /dev/null +++ b/MRMobileRun/MRRunning/RunMainPageCV.h @@ -0,0 +1,19 @@ +// +// RunMainPageCV.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/10. +// +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RunMainPageCV : UIViewController + + // 当前跑步距离 +@property(nonatomic,assign)double distance; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/RunMainPageCV.m b/MRMobileRun/MRRunning/RunMainPageCV.m new file mode 100644 index 0000000..3c149be --- /dev/null +++ b/MRMobileRun/MRRunning/RunMainPageCV.m @@ -0,0 +1,883 @@ +// +// RunMainPageCV.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/10. +// + + + +#import +#import +#import +#import +#import +#import +#import +#import +#import //搜索库,为获取天气 +#import //读取健康数据(此页面暂时只读取健康数据) + +#import "StepManager.h" //陀螺仪计步 +#import "SVGKit.h" +#import "SVGKImage.h" +#import "SVGKParser.h" +#import "UIImage+SVGTool.h" +#import "ZYLMainViewController.h" +#import "MGDTabBarViewController.h" +#import "ZYLTimeStamp.h" //获取开始、结束的时间 +#import "GYYHealthManager.h" //读取健康数据,获取跑步时间段的步数来计算步频 +#import "MRTabBarController.h" +#import "MRMainTabBarController.h" +#import "RunMainPageCV.h" +#import "RunningMainPageView.h" +#import "RunLocationModel.h" +#import "MGDDataViewController.h" +#import "SZHAlertView.h" //跑步距离过短时结束的提示弹窗 +#import "RecordtimeString.h" +@interface RunMainPageCV () +{ + CGFloat _yyy; +} +@property (nonatomic, strong) RunningMainPageView *Mainview; + +//关于时间 +@property (nonatomic, strong) NSTimer *runTimer; +@property (nonatomic, strong) NSDate *beginTime; //开始的时间(系统时间) +@property (nonatomic, strong) NSDate *endTime; //结束时间(系统时间) +@property (nonatomic, strong) NSString *timeStr; //最后获取到秒数转化为时间 + +@property (nonatomic) int second; + +//数组 + //关于步频 +@property (nonatomic, strong) NSMutableArray *stepsAry; //每分钟的步数 +@property (nonatomic, strong) NSArray *updateStepsAry; //上传的步频数组 +@property int averageStepFrequency; //平均步频 +@property int maxStepFrequency; //最大步频 +@property NSInteger everyMinuteSteps; //每分钟的步数 +//此跑步页经过处理后,要给跑步完成界面绘图的步频数组 +@property (nonatomic, strong) NSArray *cacultedStepsAry; + + //关于速度 +@property (nonatomic, strong) NSMutableArray *speedAry; //速度的数组 +@property (nonatomic, strong) NSArray *updateSpeedAry; //上传的速度数组 +@property double averageSpeed; //平均速度 +@property double maxSpeed; //最大速度 +//此跑步页经过处理后,要给跑步完成界面绘图的速度数组 +@property (nonatomic, strong) NSArray *caculatedSpeedAry; + + +@property double mileage; //总路程 +@property double duration; //总时间 +@property (nonatomic, strong) NSString *finishDate;//完成的日期 + +@property double kcal; //燃烧千卡; + +//关于模型 +@property (nonatomic, strong) RunLocationModel *locationModel; + +/* + 关于定位以及绘制轨迹 + */ +@property (nonatomic, strong) AMapLocationManager *locationManager; +@property (nonatomic, strong) CLLocationManager *CLlocationManager; +@property (nonatomic, strong)MAAnnotationView *myAnnotationView;//我的当前位置的大头针 +@property (nonatomic, strong)MAPolyline *polyline;//当前绘制的轨迹曲线 + +@property (nonatomic, strong)NSMutableArray *drawLineArray;//待绘制定位轨迹线数据 +@property (nonatomic, strong)NSMutableArray *locationArray; + + +@property (nonatomic, assign) CGFloat signal; //信号强度 + +//跑步结束时的AlertView +@property (nonatomic, strong) SZHAlertView *shortAlert; //跑步距离过短时 +@property (nonatomic, strong) SZHAlertView *normalAlert; + +//关于实时天气 +@property (nonatomic, strong) AMapSearchAPI *search; +@property (nonatomic, strong) NSString *temperature; //温度 +@property (nonatomic, strong) NSString *weather; //天气 + +//关于上传跑步数据 +@property (nonatomic, strong) NSMutableArray *pathMuteAry; +@property double maxSpeedLast; //最大速度 +@property double maxStepLast; //最大步频 + +@end + + +@implementation RunMainPageCV + +- (void)viewDidLoad { + [super viewDidLoad]; + ///关于一些初始化设置 + self.locationArray = [NSMutableArray array]; + self.drawLineArray = [NSMutableArray array]; + self.distance = 0; + self.kcal = 0; + //原始的步频、速度数组 + self.stepsAry = [NSMutableArray array]; + self.speedAry = [NSMutableArray array]; + //上传的步频、速度数组 + self.updateSpeedAry = [NSArray array]; + self.updateStepsAry = [NSArray array]; + self.pathMuteAry = [NSMutableArray array]; //位置数组 + self.caculatedSpeedAry = [NSArray array]; //处理后的速度数组 + self.cacultedStepsAry = [NSArray array]; //处理后的步频数组 + + + //跑步首页UI + self.Mainview = [[RunningMainPageView alloc] initWithFrame:self.view.frame]; + [self.view addSubview:self.Mainview]; + [self.Mainview mainRunView]; + + self.Mainview.mapView.delegate = self; //设置地图代理 + + [self initAMapLocation]; //初始化位置管理者 + [self btnFunction]; //跑步首页关于继续暂停等按钮的方法 + + //关于天气 + self.search = [[AMapSearchAPI alloc] init]; + self.search.delegate = self; + + [[StepManager sharedManager] startWithStep]; //开始计步 + self.second = 0; //初始化秒数为0 + //计时器每隔一秒钟执行一次方法 + self.runTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(startTimer) userInfo:nil repeats:YES]; +} + + +#pragma mark- 加载位置管理者 +- (void)initAMapLocation{ + _locationManager = [[AMapLocationManager alloc] init]; + _locationManager.delegate = self; + _locationManager.distanceFilter = 10;//设置移动精度(单位:米) + [_locationManager setDesiredAccuracy:kCLLocationAccuracyBest]; //设置期望定位精度 + _locationManager.locationTimeout = 2;//定位时间 + _locationManager.allowsBackgroundLocationUpdates = YES;//开启后台定位 + [_locationManager setLocatingWithReGeocode:YES]; //连续定位是否返回逆地理信息 + [_locationManager startUpdatingLocation]; //开始持续定位 +} + +#pragma mark- ---------------------------------地图的代理方法------------------------------------ + //设置地图的自动转向以及用户小蓝点的自动转向 +- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation{ + //设置用户小蓝点的自动转向 + if (!updatingLocation) { + MAAnnotationView *userLocationView = [mapView viewForAnnotation:mapView.userLocation]; + [UIView animateWithDuration:0.1 animations:^{ + double degree = userLocation.heading.trueHeading - self.Mainview.mapView.rotationDegree; + userLocationView.imageView.transform = CGAffineTransformMakeRotation(degree * M_PI / 180.f ); + }]; + } +} + +//定位数据 +- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode{ + self.signal = location.horizontalAccuracy; + //根据信号强度设置信号强度的照片 + if (self.signal < 20 && location.verticalAccuracy < 20 ) { + //信号强 + self.Mainview.GPSSignal.image = [UIImage imageNamed:@"信号三格"]; + }else if(self.signal < 70 && location.verticalAccuracy < 70){ + //信号中等 + self.Mainview.GPSSignal.image = [UIImage imageNamed:@"信号二格"]; + }else{ + //信号差 + self.Mainview.GPSSignal.image = [UIImage imageNamed:@"信号一格"]; + } + //GPS信号大于0。小于80的时候进来 + if (self.signal < 80 && self.signal >0 && location.verticalAccuracy < 80 && location.verticalAccuracy > 0){ + //设置地图中心为当前的经纬度 + [self.Mainview.mapView setCenterCoordinate:location.coordinate]; + if (self.locationArray.count == 0) { + //最开始的一个定位点 + RunLocationModel *StartPointModel = [[RunLocationModel alloc] init]; + StartPointModel.location = location.coordinate; + StartPointModel.speed = location.speed; + StartPointModel.time = [NSDate date]; + [self.locationArray addObject:StartPointModel];//向位置数组里面添加第一个定位点 + [self.drawLineArray addObject:StartPointModel];//向绘制轨迹点的数组里添加第一个定位点 + } + //位置数组不为空,开始后续的定位点 + if (self.locationArray.count >= 1) { + RunLocationModel *LastlocationModel = self.locationArray.lastObject; + //当前定位的位置信息model + RunLocationModel *currentModel = [[RunLocationModel alloc] init]; + currentModel.location = location.coordinate; + currentModel.time = [NSDate date]; + currentModel.speed = location.speed; + + //计算出两点的距离 +// double distance = [self distanceWithLocation:LastlocationModel andLastButOneModel:currentModel]; + MAMapPoint point1 = MAMapPointForCoordinate(LastlocationModel.location); + MAMapPoint point2 = MAMapPointForCoordinate(currentModel.location); + CLLocationDistance distance = MAMetersBetweenMapPoints(point1, point2); + double Kmters = distance/1000; + self.distance = self.distance + Kmters; + + //将距离赋值到中间以及右上角的label上 + self.Mainview.mileNumberLabel.text = [NSString stringWithFormat:@"%0.2f",self.distance]; //首页正中间的 + //首页右上角的 + self.Mainview.mileNumberLabelRight.text = [NSString stringWithFormat:@"%0.2f",self.distance]; + + //如果返回的距离超过10米,就加入到绘制轨迹数组内 + if (distance > 10) { + [self.drawLineArray addObject:currentModel]; + } + + //将该点加入到位置数组 + [self.locationArray addObject:currentModel]; + + //绘制轨迹 + [self drawRunLineAction]; + + //计算两个定位点的时差 + NSTimeInterval secondesBetweenPoints = [currentModel.time timeIntervalSinceDate:LastlocationModel.time]; + //计算两点的速度 + double speed = distance/secondesBetweenPoints; + //如果两点间速度大于0小于百米9.97秒说明此速度为正常速度,进行后续速度操作以及配速的逻辑 + if (speed < 100/9.97 && speed >= 0) { + //1.每隔30秒采集一次速度,添加进速度数组 + if (self.second%30 == 0) { + NSString *speedStr = [NSString stringWithFormat:@"%0.2f", speed]; + [self.speedAry addObject:speedStr]; + } + //2.计算配速 + int speedMinutes = (int)(1000/speed)/60; + int speedSeconds = (int)(1000/speed)%60; + if (speedMinutes > /* DISABLES CODE */ (99) && speedMinutes < 0) { + self.Mainview.speedNumberLbl.text = @"--'--''"; + }else if(speedMinutes > 0){ + self.Mainview.speedNumberLbl.text = [NSString stringWithFormat:@"%d'%d''",speedMinutes,speedSeconds]; + + //3.计算燃烧千卡 + self.kcal = 60 * self.distance * 1.036; + self.Mainview.energyNumberLbl.text = [NSString stringWithFormat:@"%0.1f",self.kcal]; + } + } + } + } + AMapWeatherSearchRequest *request = [[AMapWeatherSearchRequest alloc] init]; + request.city = @"重庆"; + request.type = AMapWeatherTypeLive; //天气类型为实时天气 + [self.search AMapWeatherSearch:request]; + +} + +//计算距离 +-(double)distanceWithLocation:(RunLocationModel *)lastModel andLastButOneModel:(RunLocationModel *)lastButOneModel{ + CLLocationDistance Meters = 0; + MAMapPoint point1 = MAMapPointForCoordinate(lastModel.location); + MAMapPoint point2 = MAMapPointForCoordinate(lastButOneModel.location); + //2.计算距离 +// CLLocationDistance newdistance = MAMetersBetweenMapPoints(point1,point2); + Meters = MAMetersBetweenMapPoints(point1,point2); +// 计算两个定位点的时间差 +// NSTimeInterval secondesBetweenPoints = [lastModel.time timeIntervalSinceDate:lastButOneModel.time]; + double KMeters = Meters/1000; + return KMeters; +} + + +#pragma mark- 获取天气的代理回调方法 +- (void)onWeatherSearchDone:(AMapWeatherSearchRequest *)request response:(AMapWeatherSearchResponse *)response{ + if (response.lives.count == 0) { + return; + } + AMapLocalWeatherLive *liveWeather = response.lives.firstObject; + if (liveWeather != nil) { + self.temperature = liveWeather.temperature; + self.weather = liveWeather.weather; +// NSLog(@"获得的天气为:温度:%@,天气:%@",self.temperature,self.weather); + } +} + +#pragma mark- 绘制定位大头针 + //自定义大头针 +- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation{ + + // 自定义userlocation的大头针 + if ([annotation isKindOfClass:[MAUserLocation class]]) { + static NSString *userLocationReuseIndetifier = @"userLocation"; + self.myAnnotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:userLocationReuseIndetifier]; + if (self.myAnnotationView == nil) { + self.myAnnotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:userLocationReuseIndetifier]; + } + self.myAnnotationView.image = [UIImage imageNamed:@"userAnnotation"]; + return self.myAnnotationView; + } + return nil; +} + +#pragma mark- 轨迹线的设置 +//绘制轨迹线:为保证性能全图只绘制一条轨迹线 +- (void)drawRunLineAction{ + CLLocationCoordinate2D commonPolylineCoords[self.drawLineArray.count]; + for (int i = 0; i < self.drawLineArray.count; i++) { + RunLocationModel *model = self.drawLineArray[i]; + commonPolylineCoords[i] = model.location; + } + [self.Mainview.mapView removeOverlay:self.polyline]; //移除之前的轨迹线 + //设置出新的从开始到当前点的轨迹线 + self.polyline = [MAPolyline polylineWithCoordinates:commonPolylineCoords count:self.drawLineArray.count]; + [self.Mainview.mapView addOverlay:self.polyline]; +} + +//自定义轨迹线 +- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id )overlay{ + if ([overlay isKindOfClass:[MAPolyline class]]) { + MAPolylineRenderer *polyLineRender = [[MAPolylineRenderer alloc] initWithPolyline:overlay]; + polyLineRender.lineWidth = 8; + polyLineRender.strokeColor = [UIColor colorWithRed:129/255.0 green:233/255.0 blue:255/255.0 alpha:1.0]; //折线颜色 + return polyLineRender; + } + return nil; +} + +#pragma mark- 关于后台定位需要调用的代理方法 +- (void)amapLocationManager:(AMapLocationManager *)manager doRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} + +- (void)mapViewRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} + +#pragma mark- 关于时间 +//跑步时间开始 +- (void)startTimer{ + self.second++; + if (self.second == 86400) { + self.second = 0; + } +// NSLog(@"%d",self.second); + //如果秒数大于等于一个小时,将格式转换为HH:MM:SS格式,否则转换为MM:SS格式 + NSString *timeStr = @"00:00"; + if (self.second >= 3600) { + //将秒数转化为HH:MM:SS格式 + timeStr = [RecordtimeString getTimeStringWithSeconds:self.second]; + }else if (self.second >= 0 && self.second < 3600){ + //将秒数转化为MM:SS格式 + timeStr = [RecordtimeString getMinutesTimeStringWithSeconds:self.second]; + } + //获取跑步时间 + self.Mainview.timeNumberLbl.text = timeStr; + self.timeStr = timeStr; + //如果有一分钟了执行一下操作来获取步频 + if (self.second%60 == 0) { + NSString *stepString = [NSString stringWithFormat:@"%ld",(long)[StepManager sharedManager].step]; + [self.stepsAry addObject:stepString]; + [StepManager sharedManager].step = 0; //清零 + } +} + + +#pragma mark- 读取健康数据(步数) + + +#pragma mark- 按钮的方法 +//按钮方法 +- (void)btnFunction{ + //暂停按钮 + [self.Mainview.pauseBtn addTarget:self action:@selector(pauseMethod) forControlEvents:UIControlEventTouchUpInside]; + + //锁屏按钮 + [self.Mainview.lockBtn addTarget:self action:@selector(lockMethod) forControlEvents:UIControlEventTouchUpInside]; + + //解锁按钮 + [self.Mainview.unlockLongPressView addTarget:self select:@selector(unlockMethod)]; + + + //继续按钮 + [self.Mainview.continueBtn addTarget:self action:@selector(continueMethod) forControlEvents:UIControlEventTouchUpInside]; + + //结束按钮 + [self.Mainview.endLongPressView addTarget:self select:@selector(endMethod)]; +} + +//点击暂停按钮的方法 +- (void)pauseMethod{ + //计时器暂停 + [self.runTimer setFireDate:[NSDate distantFuture]]; + + //计步暂停 + [[StepManager sharedManager] end]; + + //定位暂停 + [self.locationManager stopUpdatingLocation]; + + //按钮的变化 + self.Mainview.pauseBtn.hidden = YES; + self.Mainview.lockBtn.hidden = YES; + self.Mainview.unlockLongPressView.hidden = YES; + + self.Mainview.endLongPressView.hidden = NO; + self.Mainview.continueBtn.hidden = NO; +} + +//点击继续按钮方法 +- (void)continueMethod{ + //计时器继续 + [self.runTimer setFireDate:[NSDate distantPast]]; + + //计步继续 + [[StepManager sharedManager] continueSteps]; + + //定位继续 + [self.locationManager startUpdatingLocation]; + + //按钮的变换 + self.Mainview.unlockLongPressView.hidden = YES; + self.Mainview.endLongPressView.hidden = YES; + self.Mainview.continueBtn.hidden = YES; + + self.Mainview.pauseBtn.hidden = NO; + self.Mainview.lockBtn.hidden = NO; + +} + +//点击锁屏按钮方法 +- (void)lockMethod{ + self.Mainview.topView.userInteractionEnabled = NO; +#pragma mark- 按钮的变换 + self.Mainview.pauseBtn.hidden = YES; + self.Mainview.lockBtn.hidden = YES; + self.Mainview.endLongPressView.hidden = YES; + self.Mainview.continueBtn.hidden = YES; + self.Mainview.unlockLongPressView.hidden = NO; + + self.Mainview.dragLabel.userInteractionEnabled = NO; +} + +//长按解锁按钮方法 +- (void)unlockMethod{ + self.Mainview.topView.userInteractionEnabled = YES; +#pragma mark- 按钮的变换 + self.Mainview.unlockLongPressView.hidden = YES; + self.Mainview.endLongPressView.hidden = YES; + self.Mainview.continueBtn.hidden = YES; + self.Mainview.lockBtn.hidden = NO; + self.Mainview.pauseBtn.hidden = NO; + + self.Mainview.dragLabel.userInteractionEnabled = YES; +} + +//长按结束按钮方法 +- (void)endMethod{ + self.mileage = self.distance; //总路程 + self.duration = self.second; //总时间 + + //设置上传的步频和速度数组 + { + //设置上传的速度数组 + NSMutableArray *mueArySpeed2 = [NSMutableArray array]; + for (int i = 0; i < self.speedAry.count; i++) { + NSString *speed = self.speedAry[i]; + NSString *index = [NSString stringWithFormat:@"%d",i+1]; + NSNumber *n1 = @([speed doubleValue]); + NSNumber *n2 = @([index intValue]); + NSMutableArray *muteArySpeed = [NSMutableArray array]; + [muteArySpeed addObject:n1]; + [muteArySpeed addObject:n2]; + NSArray *array = muteArySpeed; + [mueArySpeed2 addObject:array]; + } + self.updateSpeedAry = mueArySpeed2; +// NSLog(@"上传的的速度数组为%@",self.updateSpeedAry); + + //设置上传的步频数组 + if (self.stepsAry != nil) { + NSMutableArray *muteStepsArray = [NSMutableArray array]; + for (int i = 0; i < self.stepsAry.count; i++) { + NSString *step = self.stepsAry[i]; + NSString *stepIndex = [NSString stringWithFormat:@"%d",i + 1]; + NSNumber *n1 = @([step intValue]); + NSNumber *n2 = @([stepIndex intValue]); + NSMutableArray *array = [NSMutableArray new]; + [array addObject:n1]; + [array addObject:n2]; + [muteStepsArray addObjectsFromArray:array]; + } + self.updateStepsAry = muteStepsArray; + } + + //为跑步结束页的图表处理步频和速度数组并且找出处理后的最大数组和最大步频 + [self caculateSpeedAndStpesArray]; + [self averageSpeedAndSteps]; //找出平均速度和平均步频 + } + + //获取当前日期 + { + NSDate *date = [NSDate date]; + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + [formatter setDateFormat:@"yyyy-MM-dd"]; +// self.finishDate = [formatter stringFromDate:date]; + NSString *formaterTime = [formatter stringFromDate:date]; + //将当前日期转化为时间戳 + NSDate *date1 = [formatter dateFromString:formaterTime]; + NSInteger timeSp = [[NSNumber numberWithDouble:[date1 timeIntervalSince1970]] integerValue]; + self.finishDate = [NSString stringWithFormat:@"%ld",(long)timeSp]; + NSLog(@"获取到的时间戳为%@",self.finishDate); + } + //弹出提示框 + if (self.second < 60 || self.distance < 0.1) { + SZHAlertView *shortAlert = [[SZHAlertView alloc] initWithTitle:@"本次跑步距离过短,无法保存记录,确定结束吗?"]; + [self.view addSubview:shortAlert]; + shortAlert.frame = self.view.frame; + [shortAlert.endBtn addTarget:self action:@selector(shortEndRun) forControlEvents:UIControlEventTouchUpInside]; + [shortAlert.ContinueRunBtn addTarget:self action:@selector(continueRun1) forControlEvents:UIControlEventTouchUpInside]; + self.shortAlert = shortAlert; + }else{ + SZHAlertView *endAlert = [[SZHAlertView alloc] initWithTitle:@"您确定要结束跑步吗?"]; + [self.view addSubview:endAlert]; + endAlert.frame = self.view.frame; + [endAlert.endBtn addTarget:self action:@selector(endRun) forControlEvents:UIControlEventTouchUpInside]; + [endAlert.ContinueRunBtn addTarget:self action:@selector(continueRun2) forControlEvents:UIControlEventTouchUpInside]; + self.normalAlert = endAlert; + } +} + +/** + 此处应当是直接跳转到首页,不会跳转到跑步结束页,也不会上传跑步数据,最后进行处理 + */ +- (void)shortEndRun{ + + [self.navigationController popToRootViewControllerAnimated:YES]; +// MGDDataViewController *overVC = [[MGDDataViewController alloc] init]; +// [self.navigationController pushViewController:overVC animated:YES]; + //停止定时器 + [self.runTimer invalidate]; +} + +- (void)continueRun1{ + [self.shortAlert removeFromSuperview]; +} + +//正常结束 + //结束 +- (void)endRun{ + //异步执行网络请求,上传跑步数据 + dispatch_async(dispatch_get_global_queue(0, 0), ^{ + [self handUpData]; + }); + //回到主线程去执行界面跳转以及属性传值 + dispatch_async(dispatch_get_main_queue(), ^{ + //跳转到下一个页面 + if (@available(iOS 12.0, *)) { + MGDDataViewController *overVC = [[MGDDataViewController alloc] init]; + //属性传值 +// overVC.distanceStr = self.Mainview.mileNumberLabel.text; //跑步距离 + overVC.distanceStr = [NSString stringWithFormat:@"%0.2f",self.distance]; + overVC.speedStr = self.Mainview.speedNumberLbl.text; //配速 + + overVC.caculatedSpeedAry = self.caculatedSpeedAry;//为绘制速度图处理的数组 + overVC.cacultedStepsAry = self.cacultedStepsAry; //为绘制步频图处理的数组 + + overVC.averageSpeed = self.averageSpeed; //平均速度 + overVC.maxSpeedLastest = self.maxSpeedLast; //最大速度 + overVC.averageStepFrequency = self.averageStepFrequency; //平均步频 + overVC.maxStepFrequencyLastest = self.maxStepLast; //最大步频 + + overVC.timeStr = self.timeStr; //时间 + overVC.energyStr = self.Mainview.energyNumberLbl.text; //千卡 + overVC.drawLineAry = self.drawLineArray; + overVC.locationAry = self.locationArray; + overVC.temperature = self.temperature; //温度 + overVC.weather = self.weather; //天气 + + self.hidesBottomBarWhenPushed = YES; + [self.navigationController pushViewController:overVC animated:YES]; + } else { + // Fallback on earlier versions + } + self.tabBarController.tabBar.hidden = YES; + }); + + //停止定时器 + [self.runTimer invalidate]; +} + //继续跑步 +- (void)continueRun2{ + [self.normalAlert removeFromSuperview]; +} + +#pragma mark-步频和配速 + +//找出平均步频和平均速度 +- (void)averageSpeedAndSteps{ + //平均速度 + self.averageSpeed = 0; //对平均速度进行初始赋值 + self.averageSpeed = (self.distance * 1000)/self.second; + // NSLog(@"此次跑步的平均速度为%f",self.averageSpeed); + + //平均步频 + self.averageStepFrequency = 0; //对平均步频进行初始赋值 + if (self.stepsAry.count != 0) { + int totleSteps = 0; + for (int i = 0; i < self.stepsAry.count; i++) { + NSString *stepsStr = self.stepsAry[i]; + int steps = [stepsStr intValue]; + totleSteps = totleSteps + steps; + } + self.averageStepFrequency = totleSteps/self.stepsAry.count; + } +} + +//为跑步完成界面的步频、速度图绘制对原始的采集数组进行处理 +- (void)caculateSpeedAndStpesArray{ + //处理步频的数组并找出处理后的最大步频 + self.maxStepLast = 0; + NSMutableArray *stepsMuteAry = [NSMutableArray array]; + if (self.stepsAry != nil) { +// //五分钟一个点 +// for (int i = 0; i < self.stepsAry.count; i += 5) { +// // 0 0 0 0 0 0/ 0 0 0 0 0 +// NSString *stepStr = self.stepsAry[i]; +// [stepsMuteAry addObject:stepStr]; +// //找出最处理后的数组中最大的步频 +// double step = [stepStr doubleValue]; +// if (self.maxStepLast < step) { +// self.maxStepLast = step; +// } +// } + + //一分钟一个点 + for (int i = 0; i < self.stepsAry.count; i++) { + NSString *stepStr = self.stepsAry[i]; + [stepsMuteAry addObject:stepStr]; + //找出最处理后的数组中最大的步频 + double step = [stepStr doubleValue]; + if (self.maxStepLast < step) { + self.maxStepLast = step; + } + } + + self.cacultedStepsAry = stepsMuteAry; +// if (self.cacultedStepsAry.count != 0) { +// NSLog(@"处理后的步频数组为%@,处理后最大的步频为%f",self.cacultedStepsAry,self.maxStepLast); +// } + } + + + //处理速度的数组并找出处理后的最大速度 + self.maxSpeedLast = 0; + if (self.speedAry != nil) { + NSMutableArray *speedMuteAry = [NSMutableArray array]; + //两分半记录一个点 + for (int i = 0; i < self.speedAry.count; i += 5) { + NSString *speedStr = self.speedAry[i]; + [speedMuteAry addObject:speedStr]; + //找出处理后的数组里最大的速度 + double speed = [speedStr doubleValue]; + + if (self.maxSpeedLast < speed) { + self.maxSpeedLast = speed; + } + } + self.caculatedSpeedAry = speedMuteAry; +// NSLog(@"处理后的速度数组为%@,处理后最大的速度为%f",self.caculatedSpeedAry,self.maxSpeedLast); + } + +} + +#pragma mark- 网络请求上传跑步数据 +- (void)handUpData{ + + //创建要传上去的数据字典 + NSMutableDictionary *paramDic = [NSMutableDictionary new]; + + //获取跑步路径数据 + for (int i = 0; i < self.locationArray.count; i++ ) { + RunLocationModel *model = self.locationArray[i]; + CLLocationCoordinate2D coordinate = model.location; + double latitude = coordinate.latitude; + double lontitude = coordinate.longitude; +// NSString *latitudeStr = [NSString stringWithFormat:@"%f",coordinate.latitude]; +// NSString *lontitudeStr = [NSString stringWithFormat:@"%f",coordinate.longitude]; + NSMutableArray *sectionPath = [NSMutableArray array]; + NSNumber *lati = [NSNumber numberWithDouble:latitude]; + NSNumber *lonti = [NSNumber numberWithDouble:lontitude]; + [sectionPath addObject:lati]; + [sectionPath addObject:lonti]; + [self.pathMuteAry addObject:sectionPath]; + } + [paramDic setValue:self.pathMuteAry forKey:@"path"]; //跑步沿途路径 + + //跑步时间必须小于23时59分 + if (self.duration < 1440) { + NSString *duration = [[NSNumber numberWithDouble:self.duration] stringValue]; + NSNumber *numberDuration = @([duration intValue]); + [paramDic setValue:numberDuration forKey:@"duration"]; //跑步总时间 + } + + NSString *mileage = [NSString stringWithFormat:@"%0.2f",self.distance]; + NSNumber *numberMileage = @([mileage doubleValue]); + [paramDic setValue:numberMileage forKey:@"mileage"]; //跑步总距离 + + NSString *kcal = [NSString stringWithFormat:@"%0.2f",self.kcal]; + NSNumber *numberKcal = @([kcal doubleValue]); + [paramDic setValue:numberKcal forKey:@"kcal"];//跑步消耗能量 + + NSString *averageSpeedStr = [[NSNumber numberWithDouble:self.averageSpeed] stringValue]; + NSNumber *numberAverageSpeedStr = @([averageSpeedStr doubleValue]); + [paramDic setValue:numberAverageSpeedStr forKey:@"averageSpeed"]; //平均速度 + + //平均步频 + NSString *averageStepFrequencyStr = [[NSNumber numberWithInt:self.averageStepFrequency] stringValue]; + NSNumber *numberAverageStepFrequencyStr = @([averageStepFrequencyStr intValue]); + [paramDic setValue:numberAverageStepFrequencyStr forKey:@"averageStepFrequency"]; +// + NSString *maxSpeedStr = [[NSNumber numberWithDouble:self.maxSpeed] stringValue]; + NSNumber *numberMaxSpeed = @([maxSpeedStr doubleValue]); + [paramDic setValue:numberMaxSpeed forKey:@"maxSpeed"]; //最大速度 +// + NSString *maxStepFrequencyStr = [[NSNumber numberWithInt:self.maxStepFrequency] stringValue]; + NSNumber *maxStep = @([maxStepFrequencyStr intValue]); + [paramDic setValue:maxStep forKey:@"maxStepFrequency"]; //最大步频 +// + NSNumber *finishDate = @([self.finishDate intValue]); + [paramDic setValue:finishDate forKey:@"finishDate"]; //完成日期 +// NSLog(@"上传的日期为%@",self.finishDate); + + + if (self.updateStepsAry.count == 0) { + NSMutableArray *muteAry2 = [NSMutableArray array]; + NSString *string = [NSString stringWithFormat:@"%d",0]; + NSNumber *number1 = @([string intValue]); + NSString *string2 = [NSString stringWithFormat:@"%d",1]; + NSNumber *number2 = @([string2 intValue]); + NSMutableArray *muteary = [NSMutableArray array]; +// [muteary addObject:string2]; +// [muteary addObject:string]; + [muteary addObject:number1]; + [muteary addObject:number2]; + NSArray *array = muteary; + + [muteAry2 addObject:array]; + self.updateStepsAry = muteAry2; + [paramDic setValue:self.updateStepsAry forKey:@"stepFrequency"]; //上传的步频数组 + }else{ + [paramDic setValue:self.updateStepsAry forKey:@"stepFrequency"]; //上传的步频数组 + } + + if (self.updateSpeedAry.count == 0) { + NSMutableArray *muteAry2 = [NSMutableArray array]; + NSString *string = [NSString stringWithFormat:@"%f",0.5]; + NSNumber *number1 = @([string doubleValue]); + NSString *string2 = [NSString stringWithFormat:@"%d",1]; + NSNumber *number2 = @([string2 doubleValue]); + NSMutableArray *muteary = [NSMutableArray array]; + // [muteary addObject:string2]; + // [muteary addObject:string]; + [muteary addObject:number1]; + [muteary addObject:number2]; + NSArray *array = muteary; + [muteAry2 addObject:array]; + [paramDic setValue:muteAry2 forKey:@"speed"]; + }else{ + [paramDic setValue:self.updateSpeedAry forKey:@"speed"];//速度分布数组 + } + + //天气 + if ([self.weather isEqualToString:@"雷阵雨"]) { + [paramDic setValue:@0 forKey:@"weather"]; + }else if ([self.weather isEqualToString:@"晴"]){ + [paramDic setValue:@1 forKey:@"weather"]; + }else if ([self.weather isEqualToString:@"雪"]){ + [paramDic setValue:@2 forKey:@"weather"]; + }else if ([self.weather isEqualToString:@"阴"] || [self.weather isEqualToString:@"多云"]){ + [paramDic setValue:@3 forKey:@"weather"]; + }else if([self.weather isEqualToString:@"雨"]){ + [paramDic setValue:@4 forKey:@"weather"]; + } + + NSNumber *numberTemperature = @([self.temperature doubleValue]); + [paramDic setValue:numberTemperature forKey:@"temperature"]; //温度 + + NSLog(@"未上传数据时的数据字典为%@",paramDic); + + + AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; + //需要上传json类型的数据 + manager.requestSerializer = [AFJSONRequestSerializer serializer]; + manager.requestSerializer.cachePolicy = NSURLRequestUseProtocolCachePolicy; + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *token = [user objectForKey:@"token"]; + // 响应 + AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer]; + [responseSerializer setRemovesKeysWithNullValues:YES]; //去除空值 + responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObjectsFromSet:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", @"text/plain",@"application/atom+xml",@"application/xml",nil]]; //设置接收内容的格式 + [manager setResponseSerializer:responseSerializer]; + //将token添加进请求头 + [manager.requestSerializer setValue:[NSString stringWithFormat:@"%@",token] forHTTPHeaderField:@"token"]; + [manager.requestSerializer setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"]; + + [manager POST:HandUpRunData parameters:paramDic success:^(NSURLSessionDataTask *task, id responseObject) { + NSLog(@"-----------上传数据成功,得到的结果为%@",responseObject); + NSLog(@"-------%@",paramDic); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSLog(@"上传数据失败,上传的参数为"); + NSLog(@"%@",error); + NSData *data = error.userInfo[@"com.alamofire.serialization.response.error.data"] ; + NSString *errorStr = [[ NSString alloc ] initWithData:data encoding:NSUTF8StringEncoding]; + NSLog(@"错误信息为%@",errorStr); + }]; +} + +//监听系统的颜色模式来配置地图的白天、深色模式下的自定义样式 +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection{ + [super traitCollectionDidChange: previousTraitCollection]; + if (@available(iOS 13.0, *)) { + if([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]){ + if (@available(iOS 13.0, *)) { + UIUserInterfaceStyle mode = UITraitCollection.currentTraitCollection.userInterfaceStyle; + if (mode == UIUserInterfaceStyleDark) { + NSLog(@"深色模式"); + //设置深色模式下的自定义地图样式 + NSString *path = [[NSBundle mainBundle] pathForResource:@"style" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.Mainview.mapView setCustomMapStyleOptions:options]; + [self.Mainview.mapView setCustomMapStyleEnabled:YES]; + //设置深色模式下的svg格式的图片 + //暂停按钮 + self.Mainview.pauseBtn.logoImg.image = [UIImage svgImgNamed:@"暂停黑.svg" size:CGSizeMake(30, 30)]; + //解锁按钮 + self.Mainview.unlockLongPressView.imgView.image = [UIImage svgImgNamed:@"锁定黑.svg" size:CGSizeMake(30, 30)]; + //锁屏按钮 + self.Mainview.lockImageView.image = [UIImage svgImgNamed:@"锁定灰.svg" size:CGSizeMake(25, 25)]; + + } else if (mode == UIUserInterfaceStyleLight) { + NSLog(@"浅色模式"); + //设置浅色模式下的自定义地图样式 + NSString *path = [[NSBundle mainBundle] pathForResource:@"style2" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.Mainview.mapView setCustomMapStyleOptions:options]; + [self.Mainview.mapView setCustomMapStyleEnabled:YES]; + + //设置浅色模式下的svg格式的图片 + //暂停按钮 + self.Mainview.pauseBtn.logoImg.image = [UIImage svgImgNamed:@"暂停白.svg" size:CGSizeMake(30, 30)]; + //解锁按钮 + self.Mainview.unlockLongPressView.imgView.image = [UIImage svgImgNamed:@"锁定白.svg" size:CGSizeMake(30, 30)]; + //锁屏按钮 + self.Mainview.lockImageView.image = [UIImage svgImgNamed:@"锁定黑.svg" size:CGSizeMake(25, 25)]; + } else { + NSLog(@"未知模式"); + } + } + } + } else { + // Fallback on earlier versions + } +} +- (void)dealloc{ + NSLog(@"跑步首页控制器已经被销毁了!"); +} +@end diff --git a/MRMobileRun/MRRunning/RunningMainPageView.h b/MRMobileRun/MRRunning/RunningMainPageView.h new file mode 100644 index 0000000..5ab83c0 --- /dev/null +++ b/MRMobileRun/MRRunning/RunningMainPageView.h @@ -0,0 +1,69 @@ +// +// RunningMainPageView.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/10. +// +#import +#import +#import +#import +#import "LongPressView.h" +#import "RunMainBtn.h" +#import +NS_ASSUME_NONNULL_BEGIN + +@interface RunningMainPageView : UIView +@property (nonatomic, strong) MAMapView *mapView; +@property (nonatomic, strong) UIImageView *GPSImgView; +@property (nonatomic, strong) UIImageView *GPSSignal; +//中间的公里数和公里Label +@property (nonatomic, strong) UILabel *mileNumberLabel; +@property (nonatomic, strong) UILabel *mileTexteLable; +//右上角的公里数和公里Label +@property (nonatomic, strong) UILabel *mileNumberLabelRight; +@property (nonatomic, strong) UILabel *mileTextLabelRight; +@property (nonatomic, strong) UIView *bottomView; +@property (nonatomic, strong) UIView *topView; + +@property (nonatomic, strong) UILabel *dragLabel; //拖拽的label +@property (nonatomic, strong) UIImageView *dragimageView; //(PNG) + +@property (nonatomic, strong) UIImageView *speedImgView; +@property (nonatomic, strong) UIImageView *timeImgView; +@property (nonatomic, strong) UIImageView *energyImgView; +@property (nonatomic, strong) UILabel *speedNumberLbl; +@property (nonatomic, strong) UILabel *timeNumberLbl; +@property (nonatomic, strong) UILabel *energyNumberLbl; +@property (nonatomic, strong) UILabel *timeLbl; +@property (nonatomic, strong) UILabel *speedLbl; +@property (nonatomic, strong) UILabel *energyLbl; + +//关于button +@property (nonatomic, strong) UIButton *lockBtn; +@property (nonatomic, strong) RunMainBtn *pauseBtn; +@property (nonatomic, strong) RunMainBtn *continueBtn; +@property (nonatomic, strong) LongPressView *endLongPressView; +@property (nonatomic, strong) LongPressView *unlockLongPressView; + +@property (nonatomic, strong) UIImageView *pauseImgView; +@property (nonatomic, strong) UIImageView *continueImgView; +@property (nonatomic, strong) UIImageView *endImgView; +//锁屏按钮的imageView +@property (nonatomic, strong) UIImageView *lockImageView; +@property (nonatomic, strong) UILabel *pauseLabel; +@property (nonatomic, strong) UILabel *continueLabel; +@property (nonatomic, strong) UILabel *endLabel; +@property (nonatomic, strong) UIImageView *unlockImgView; +@property (nonatomic, strong) UILabel *unlockLabel; + +@property (nonatomic, strong) UILabel *dragLable; + +- (void)mainRunView; +- (void)addMapView; +- (void)addViewOnMap; +- (void)addViewOnBottomView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/RunningMainPageView.m b/MRMobileRun/MRRunning/RunningMainPageView.m new file mode 100644 index 0000000..0c60b1c --- /dev/null +++ b/MRMobileRun/MRRunning/RunningMainPageView.m @@ -0,0 +1,594 @@ +// +// RunningMainPageView.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/10. +// + +#import "RunningMainPageView.h" + +#import +#import +#import +#import +#import +#import "SVGKit.h" +#import "SVGKImage.h" +#import "SVGKParser.h" +#import "UIImage+SVGTool.h" +//屏幕的宽和高 +#define kScreenWidth [UIScreen mainScreen].bounds.size.width +#define kScreenHight [UIScreen mainScreen].bounds.size.height +@interface RunningMainPageView() +@property CGPoint containerOrigin; +@end + +@implementation RunningMainPageView + +//初始化View +- (void)mainRunView{ + [self addMapView]; + [self addViewOnMap]; + [self addViewOnBottomView]; + + //给底部视图添加手势 + UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(dragAction:)]; + [self.bottomView addGestureRecognizer:pan]; + self.bottomView.userInteractionEnabled = YES; +} + +//添加地图视图 +- (void)addMapView{ + //添加地图 + self.mapView = [[MAMapView alloc] init]; + self.mapView.mapType = MAMapTypeStandard; //设置地图类型 + //定位以后改变地图的图层显示 + [self.mapView setUserTrackingMode:MAUserTrackingModeFollow animated:YES]; + [self addSubview:self.mapView]; + + //设置地图位置: + [self.mapView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self); + make.left.right.equalTo(self); + make.bottom.equalTo(self); + }]; + //设置地图相关属性 + self.mapView.zoomLevel = 17; + self.mapView.showsUserLocation = YES; //显示用户小蓝点 + self.mapView.rotateEnabled = NO; //不旋转 + self.mapView.pausesLocationUpdatesAutomatically = NO; + self.mapView.showsCompass = NO; + self.mapView.showsScale = NO; + self.mapView.userInteractionEnabled = YES; + [self.mapView setAllowsBackgroundLocationUpdates:YES];//打开后台定位 + self.mapView.customizeUserLocationAccuracyCircleRepresentation = YES; + + //自定义用户位置小蓝点 + MAUserLocationRepresentation *r = [[MAUserLocationRepresentation alloc] init]; + r.showsAccuracyRing = NO;//不显示精度圈 +// r.image = [UIImage imageNamed:@"userAnnotation"]; + [self.mapView updateUserLocationRepresentation:r]; + + //监听是否是深色模式,并根据模式设置自定义地图样式 + [self changeMapType]; +} + +//在地图上添加控件 +- (void)addViewOnMap{ + //设置一个未显示地图时白色的蒙板 + self.topView = [[UIView alloc] init]; + [self.mapView addSubview:self.topView]; + [self.topView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.top.right.bottom.equalTo(self.mapView); +// make.bottom.equalTo(self.bottomView.mas_top); + }]; + //适配深色模式 + if (@available(iOS 11.0, *)) { + self.topView.backgroundColor = WhiteColor; + } else { + // Fallback on earlier versions + } + self.topView.alpha = 0.6; + + + //下面的白色View + self.bottomView = [[UIView alloc] init]; + [self.mapView addSubview:self.bottomView]; + [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.mas_top).offset(kScreenHight * 0.5369); + make.bottom.equalTo(self.mapView.mas_bottom); +// make.height.mas_equalTo(kScreenHight * 0.4631); + make.width.mas_equalTo(kScreenWidth); + }]; + //适配深色模式 + if (@available(iOS 11.0, *)) { + self.bottomView.backgroundColor = WhiteColor; + } else { + // Fallback on earlier versions + } + self.bottomView.layer.cornerRadius = 22; + self.bottomView.layer.shadowColor = [UIColor colorWithRed:73/255.0 green:80/255.0 blue:90/255.0 alpha:0.1].CGColor; + self.bottomView.layer.shadowOpacity = 1; + self.bottomView.layer.shadowRadius = 6; + + //左上角的GPS图标 + self.GPSImgView = [[UIImageView alloc] init]; + [self.mapView addSubview:self.GPSImgView]; + [self.GPSImgView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.mapView.mas_left).offset(kScreenWidth * 0.04); + make.top.equalTo(self.mapView.mas_top).offset(kScreenHight * 0.0739); + make.size.mas_equalTo(CGSizeMake(28, 28)); + }]; + self.GPSImgView.backgroundColor = [UIColor clearColor]; +// self.GPSImgView.backgroundColor = [UIColor redColor]; +// self.GPSImgView.alpha = 0.05; + self.GPSImgView.image = [UIImage imageNamed:@"GPS"]; + + //左上角的GPS信号 + self.GPSSignal = [[UIImageView alloc] init]; + [self.mapView addSubview:self.GPSSignal]; + [self.GPSSignal mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.GPSImgView.mas_right).offset(screenWidth * 0.0213); + make.centerY.equalTo(_GPSImgView); + make.size.mas_equalTo(CGSizeMake(34, 15)); + }]; + self.GPSSignal.backgroundColor = [UIColor clearColor]; + + //公里的相关lable + [self aboutMinleLbl]; +} + +//在底部视图上添加控件 +- (void)addViewOnBottomView{ +#pragma mark- 配速相关 + //图片框 + self.speedImgView = [[UIImageView alloc] init]; + [self.bottomView addSubview:self.speedImgView]; + [self.speedImgView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.mas_left).offset(kScreenWidth * 0.1707); + make.top.equalTo(self.bottomView.mas_top).offset(kScreenHight * 0.0435); + make.size.mas_equalTo(CGSizeMake(30, 30)); + }]; + self.speedImgView.image = [UIImage imageNamed:@"配速灰"]; + + //显示数字的lable + self.speedNumberLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.speedNumberLbl]; + [self.speedNumberLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.speedImgView); + make.top.equalTo(self.speedImgView.mas_bottom).offset(kScreenHight * 0.0224); + make.size.mas_equalTo(CGSizeMake(90, 34)); + }]; + self.speedNumberLbl.font = [UIFont fontWithName:@"Impact" size:28]; + +// [UIFont fontWithName:@"Impact" size: 82]; + if (@available(iOS 11.0, *)) { + self.speedNumberLbl.textColor = SpeedTextColor; + } else { + // Fallback on earlier versions + } + self.speedNumberLbl.textAlignment = NSTextAlignmentCenter; + self.speedNumberLbl.text = @"--'--''"; + + //显示“配速”的label + self.speedLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.speedLbl]; + [self.speedLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.speedImgView.mas_centerX); + make.top.equalTo(self.speedNumberLbl.mas_bottom).offset(kScreenHight * 0.0074); + make.size.mas_equalTo(CGSizeMake(54, 24)); + }]; + self.speedLbl.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 14]; + self.speedLbl.textColor = [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0]; + self.speedLbl.textAlignment = NSTextAlignmentCenter; + self.speedLbl.text = @"配速"; + + +#pragma mark- 时间相关 + //时间的图片 + self.timeImgView = [[UIImageView alloc] init]; + [self.bottomView addSubview:self.timeImgView]; + [self.timeImgView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.speedImgView.mas_centerY); +// make.left.equalTo(self.speedImgView.mas_right).offset(kScreenWidth * 0.256); + make.centerX.equalTo(self.mas_centerX); + make.size.mas_equalTo(CGSizeMake(30, 30)); + }]; + self.timeImgView.image = [UIImage imageNamed:@"时间灰"]; + + //显示时间的数字的lable + self.timeNumberLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.timeNumberLbl]; + [self.timeNumberLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.timeImgView); + make.centerY.equalTo(self.speedNumberLbl); + make.size.mas_equalTo(CGSizeMake(108, 34)); + }]; + self.timeNumberLbl.font = self.speedNumberLbl.font; + self.timeNumberLbl.textColor = self.speedNumberLbl.textColor; + self.timeNumberLbl.textAlignment = self.speedNumberLbl.textAlignment; + self.timeNumberLbl.text = @"00:00"; + + //显示“时间”的label + self.timeLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.timeLbl]; + [self.timeLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.timeImgView.mas_centerX); + make.centerY.equalTo(self.speedLbl.mas_centerY); + make.size.mas_equalTo(CGSizeMake(54, 24)); + }]; + self.timeLbl.font = self.speedLbl.font; + self.timeLbl.textColor = self.speedLbl.textColor; + self.timeLbl.textAlignment = NSTextAlignmentCenter; + self.timeLbl.text = @"时间"; + + +#pragma mark- 燃烧卡路里 + //燃烧卡路里的图标 + self.energyImgView = [[UIImageView alloc] init]; + [self.bottomView addSubview:self.energyImgView]; + [self.energyImgView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.speedImgView); + make.right.equalTo(self.mas_right).offset(-kScreenWidth * 0.1707); + make.size.mas_equalTo(CGSizeMake(30, 30)); + }]; + self.energyImgView.image = [UIImage imageNamed:@"千卡灰色"]; + + //燃烧多少卡路里的数字 + self.energyNumberLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.energyNumberLbl]; + [self.energyNumberLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.energyImgView); + make.centerY.equalTo(self.speedNumberLbl); + make.size.mas_equalTo(CGSizeMake(90, 34)); + }]; + self.energyNumberLbl.font = self.speedNumberLbl.font; + self.energyNumberLbl.textColor = self.speedNumberLbl.textColor; + self.energyNumberLbl.textAlignment = NSTextAlignmentCenter; + self.energyNumberLbl.text = @"0"; + + //显示“卡路里”的lable + self.energyLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.energyLbl]; + [_energyLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.energyImgView); + make.centerY.equalTo(self.speedLbl); + make.size.mas_equalTo(CGSizeMake(46, 24)); + }]; + self.energyLbl.font = self.speedLbl.font; + self.energyLbl.textColor = self.speedLbl.textColor; + self.energyLbl.text = @"千卡"; + self.energyLbl.textAlignment = NSTextAlignmentCenter; + + + #pragma mark- 可拖拽使得View高度变化的label + self.dragLabel = [[UILabel alloc] init]; +// _dragLabel.backgroundColor = [UIColor redColor]; + [self.bottomView addSubview:self.dragLabel]; + [self.dragLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.speedLbl.mas_left); + make.right.equalTo(self.energyLbl.mas_right); + make.top.equalTo(self.bottomView.mas_top); + make.bottom.equalTo(self.timeImgView.mas_top); + }]; + + #pragma mark- 关于按钮 + +#pragma mark- 锁屏按钮 + self.lockBtn = [[UIButton alloc] init]; + [self.bottomView addSubview:self.lockBtn]; + [self.lockBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.speedImgView); + make.top.equalTo(self.speedLbl.mas_bottom).offset(kScreenHight * 0.0843); + make.size.mas_equalTo(CGSizeMake(25, 25)); + }]; + //图片 +// UIImageView *lockImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"smallLockImage"]]; + self.lockImageView = [[UIImageView alloc] init]; + [self.lockBtn addSubview:self.lockImageView]; + [self.lockImageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.top.bottom.equalTo(self.lockBtn); + }]; + //锁屏按钮 + self.lockImageView.image = [UIImage svgImgNamed:@"锁定黑.svg" size:CGSizeMake(25, 25)]; + + #pragma mark- 暂停按钮 + self.pauseBtn = [[RunMainBtn alloc] init]; + [self.pauseBtn initRunBtn]; + [self.bottomView addSubview:self.pauseBtn]; + [self.pauseBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.timeImgView); + make.centerY.equalTo(self.lockBtn); + make.size.mas_equalTo(CGSizeMake(90, 90)); + }]; + self.pauseBtn.layer.cornerRadius = 45; +// self.pauseBtn.clipsToBounds = YES; + self.pauseBtn.layer.masksToBounds = 45 ? YES : NO; + if (@available(iOS 11.0, *)) { + self.pauseBtn.backgroundColor = GrayColor; + } else { + // Fallback on earlier versions + } + //图片 +// self.pauseBtn.logoImg.image = [UIImage imageNamed:@"pauseBtnImage"]; + self.pauseBtn.logoImg.image = [UIImage svgImgNamed:@"暂停白.svg" size:CGSizeMake(30, 30)]; + + self.pauseBtn.descLbl.text = @"暂停"; + if (@available(iOS 11.0, *)) { + self.pauseBtn.descLbl.textColor = ContinueBtnTextColor; + } else { + // Fallback on earlier versions + } + self.pauseBtn.hidden = NO; + + + #pragma mark- 结束的View (相当于button) + self.endLongPressView = [[LongPressView alloc] init]; + [self.endLongPressView initLongPressView]; + [self.bottomView addSubview:self.endLongPressView]; + [self.endLongPressView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.mas_left).offset(kScreenWidth * 0.2213); + make.top.equalTo(self.bottomView.mas_top).offset(kScreenHight * 0.2153); + make.size.mas_equalTo(CGSizeMake(102, 102)); + }]; + self.endLongPressView.bgView.backgroundColor = [UIColor colorWithRed:255/255.0 green:92/255.0 blue:119/255.0 alpha:1.0]; + + //设置titlelabel + self.endLongPressView.titleLbl.textColor = [UIColor whiteColor]; + self.endLongPressView.titleLbl.text = @"长按结束"; + //图片框的图片 +// self.endLongPressView.imgView.image = [UIImage imageNamed:@"endBtnImage"]; + self.endLongPressView.imgView.image = [UIImage svgImgNamed:@"结束白.svg" size:CGSizeMake(30, 30)]; +// SVGKImage *endWhite = [SVGKImage imageNamed:@"结束白"]; +// self.endLongPressView.imgview.image = endWhite; +// self.endLongPressView.imgview.backgroundColor = [UIColor darkGrayColor]; + + self.endLongPressView.layer.cornerRadius = 51; + self.endLongPressView.layer.masksToBounds = YES; + + self.endLongPressView.hidden = YES; + + + #pragma mark- 继续按钮 + self.continueBtn = [[RunMainBtn alloc] init]; + [self.continueBtn initRunBtn]; + [self.bottomView addSubview:self.continueBtn]; + [self.continueBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.endLongPressView); + make.left.equalTo(self.endLongPressView.mas_right).offset(kScreenWidth * 0.08); + make.size.mas_equalTo(CGSizeMake(90, 90)); + }]; + //图片 +// self.continueBtn.logoImg.image = [UIImage imageNamed:@"continueBtnImage"]; + self.continueBtn.logoImg.image = [UIImage svgImgNamed:@"继续白" size:CGSizeMake(30, 30)]; + self.continueBtn.descLbl.text = @"继续"; + self.continueBtn.descLbl.textColor = [UIColor whiteColor]; + + self.continueBtn.backgroundColor = [UIColor colorWithRed:85/255.0 green:213/255.0 blue:226/255.0 alpha:1.0]; + self.continueBtn.layer.cornerRadius = 45; + self.continueBtn.layer.masksToBounds = YES; + self.continueBtn.hidden = YES; + + #pragma mark- 解锁的View(相当于按钮) + self.unlockLongPressView = [[LongPressView alloc] init]; + [self.unlockLongPressView initLongPressView]; + [self.bottomView addSubview:self.unlockLongPressView]; + [self.unlockLongPressView mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self.pauseBtn); + make.size.mas_equalTo(CGSizeMake(102, 102)); + }]; + + self.unlockLongPressView.titleLbl.text = @"长按解锁"; + if (@available(iOS 11.0, *)) { + self.unlockLongPressView.titleLbl.textColor = ContinueBtnTextColor; + } else { + // Fallback on earlier versions + } + + self.unlockLongPressView.bgView.backgroundColor = self.pauseBtn.backgroundColor; + + //图片 +// self.unlockLongPressView.imgView.image = [UIImage imageNamed:@"BigLockBtnImage"]; + self.unlockLongPressView.imgView.image = [UIImage svgImgNamed:@"锁定白.svg" size:CGSizeMake(30, 30)]; + self.unlockLongPressView.layer.cornerRadius = 51; + self.unlockLongPressView.layer.masksToBounds = YES; + + + self.unlockLongPressView.hidden = YES; +#pragma mark- 拖动的labl和图片框 + self.dragLabel = [[UILabel alloc] init]; + [self.bottomView addSubview:self.dragLabel]; + [self.dragLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.timeImgView); + make.top.equalTo(self.bottomView.mas_top); + make.bottom.equalTo(self.timeImgView.mas_top); +// make.height.mas_equalTo(@25); + make.width.mas_equalTo(screenWidth * 0.6666); + }]; + + self.dragimageView = [[UIImageView alloc] init]; + self.dragimageView.backgroundColor = [UIColor colorWithRed:219/255.0 green:219/255.0 blue:219/255.0 alpha:1.0]; + self.dragimageView.layer.cornerRadius = 3; + [self.dragLabel addSubview:self.dragimageView]; +// self.dragimageView.image = [UIImage imageNamed:@"初始位置"]; + [self.dragimageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self.dragLabel); + make.height.mas_equalTo(7); + make.width.mas_equalTo(screenWidth * 0.072); + }]; +} + +//添加显示公里数的label和显示公里的label +- (void)aboutMinleLbl{ +/* + 中间的公里数和公里的label + */ + //显示公里数的label + self.mileNumberLabel = [[UILabel alloc] init]; + self.mileNumberLabel.frame = CGRectMake(0, screenHeigth * 0.2696, screenWidth, 100); + [self addSubview:self.mileNumberLabel]; + self.mileNumberLabel.textAlignment = NSTextAlignmentCenter; + self.mileNumberLabel.text = @"0.00"; //文本 + self.mileNumberLabel.font = [UIFont fontWithName:@"Impact" size: 82]; + if (@available(iOS 11.0, *)) { + self.mileNumberLabel.textColor = MilesColor; + } else { + // Fallback on earlier versions + } + + //显示“公里”的label + self.mileTexteLable = [[UILabel alloc] init]; + self.mileTexteLable.frame = CGRectMake(screenWidth * 0.4427, screenHeigth * 0.2696 + 100, 44, 30); + [self addSubview:self.mileTexteLable]; + self.mileTexteLable.textAlignment = NSTextAlignmentCenter; + self.mileTexteLable.text = @"公里"; + self.mileTexteLable.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 22]; + if (@available(iOS 11.0, *)) { + self.mileTexteLable.textColor = MilesTxetColor; + } else { + // Fallback on earlier versions + } +/* + 右上角的公里数和公里的label + */ + //公里数 + self.mileNumberLabelRight = [[UILabel alloc] init]; + self.mileNumberLabelRight.text = self.mileNumberLabel.text; + self.mileNumberLabelRight.textAlignment = NSTextAlignmentCenter; + self.mileNumberLabelRight.font = [UIFont fontWithName:@"Impact" size: 44]; + self.mileNumberLabelRight.frame = CGRectMake(screenWidth * 0.64,screenHeigth * 0.0497, 84, 53); + self.mileNumberLabelRight.alpha = 0; + self.mileNumberLabelRight.textColor = self.mileNumberLabel.textColor; + [self addSubview:self.mileNumberLabelRight]; +// self.mileNumberLabelRight.backgroundColor = [UIColor whiteColor]; + + //公里 + self.mileTextLabelRight = [[UILabel alloc] init]; + self.mileTextLabelRight.text = self.mileTexteLable.text; + self.mileTextLabelRight.textAlignment = NSTextAlignmentCenter; + self.mileTextLabelRight.textColor = self.mileTextLabelRight.textColor; + self.mileTextLabelRight.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 18]; + self.mileTextLabelRight.alpha = 0; + self.mileTextLabelRight.frame = CGRectMake(screenWidth * 0.64 + 84, screenHeigth * 0.0497 + 5, 36, 25); + [self addSubview:self.mileTextLabelRight]; +} + +//监听是否是深色模式,并根据模式设置自定义地图样式 +- (void)changeMapType{ + if (@available(iOS 13.0, *)) { + UIUserInterfaceStyle mode = UITraitCollection.currentTraitCollection.userInterfaceStyle; + if (mode == UIUserInterfaceStyleDark) { + NSLog(@"深色模式"); + + NSString *path = [[NSBundle mainBundle] pathForResource:@"style" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.mapView setCustomMapStyleOptions:options]; + [self.mapView setCustomMapStyleEnabled:YES]; + //设置深色模式下的svg格式的图片 + //暂停按钮 + self.pauseBtn.logoImg.image = [UIImage svgImgNamed:@"暂停黑.svg" size:CGSizeMake(30, 30)]; + //解锁按钮 + self.unlockLongPressView.imgView.image = [UIImage svgImgNamed:@"锁定黑.svg" size:CGSizeMake(30, 30)]; + //锁屏按钮 + self.lockImageView.image = [UIImage svgImgNamed:@"锁定灰.svg" size:CGSizeMake(25, 25)]; + + } else if (mode == UIUserInterfaceStyleLight) { + NSLog(@"浅色模式"); + + NSString *path = [[NSBundle mainBundle] pathForResource:@"style2" ofType:@"data"]; + NSData *data = [NSData dataWithContentsOfFile:path]; + MAMapCustomStyleOptions *options = [[MAMapCustomStyleOptions alloc] init]; + options.styleData = data; + [self.mapView setCustomMapStyleOptions:options]; + [self.mapView setCustomMapStyleEnabled:YES]; + + //设置浅色模式下的svg格式的图片 + //暂停按钮 + self.pauseBtn.logoImg.image = [UIImage svgImgNamed:@"暂停白.svg" size:CGSizeMake(30, 30)]; + //解锁按钮 + self.unlockLongPressView.imgView.image = [UIImage svgImgNamed:@"锁定白.svg" size:CGSizeMake(30, 30)]; + //锁屏按钮 + self.lockImageView.image = [UIImage svgImgNamed:@"锁定黑.svg" size:CGSizeMake(25, 25)]; + + } else { + NSLog(@"未知模式"); + } + } +} + +- (void)dragAction:(UIPanGestureRecognizer *)recognizer{ + CGPoint point = [recognizer translationInView:self.bottomView]; + if (recognizer.state == UIGestureRecognizerStateBegan) { + self.containerOrigin = recognizer.view.frame.origin; + } + // 手势移动过程中: 在边界处做判断,其他位置 + if (recognizer.state == UIGestureRecognizerStateChanged) { + + CGRect frame = recognizer.view.frame; + frame.origin.y = self.containerOrigin.y + point.y; + if (frame.origin.y < screenHeigth * 0.6) { // 上边界 + frame.origin.y = screenHeigth * 0.6; + } + + if (frame.origin.y > screenHeigth * 0.8) { // 下边界 + frame.origin.y = screenHeigth * 0.8; + } + + recognizer.view.frame = frame; + } + // 手势结束后:有向上趋势,视图直接滑动至上边界, 向下趋势,视图直接滑动至到下边界 + if (recognizer.state == UIGestureRecognizerStateEnded){ + if ([recognizer velocityInView:self.bottomView].y < 0) { + NSLog(@"向上"); + [UIView animateWithDuration:0.50 animations:^{ + CGRect frame = recognizer.view.frame; + frame.origin.y = screenHeigth * 0.6; + recognizer.view.frame = frame; + self.mileNumberLabelRight.alpha = 0; + self.mileTextLabelRight.alpha = 0; + self.topView.alpha = 0.6; //恢复原来的透明度 + }]; + //延迟0.5秒,等右上角的全部消失后中间的label再显示出来 + [UIView animateWithDuration:0.5 delay:0.5 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:nil animations:^{ + self.mileNumberLabel.alpha = 1; + self.mileTexteLable.alpha = 1; + + + } completion:nil]; + + + //设置draglabel里面的图片 + self.dragimageView.backgroundColor = [UIColor colorWithRed:219/255.0 green:219/255.0 blue:219/255.0 alpha:1.0]; + self.dragimageView.image = nil; + + + }else { + NSLog(@"向下"); + [UIView animateWithDuration:0.50 animations:^{ + CGRect frame = recognizer.view.frame; + frame.origin.y = screenHeigth * 0.8; + recognizer.view.frame = frame; + self.mileNumberLabel.alpha = 0; + self.mileTexteLable.alpha = 0; + self.topView.alpha = 0; + + }]; + //延迟0.5秒,等右上角的全部消失后中间的label再显示出来 + [UIView animateWithDuration:0.5 delay:0.5 usingSpringWithDamping:0.5 initialSpringVelocity:0 options:nil animations:^{ + self.mileNumberLabelRight.alpha = 1; + self.mileTextLabelRight.alpha = 1; + } completion:nil]; + + + self.dragimageView.backgroundColor = [UIColor clearColor]; + self.dragimageView.image = [UIImage imageNamed:@"底部位置"]; + + } + } + } + + + +@end diff --git a/MRMobileRun/MRRunning/SZHAlertView.h b/MRMobileRun/MRRunning/SZHAlertView.h new file mode 100644 index 0000000..d6cff3f --- /dev/null +++ b/MRMobileRun/MRRunning/SZHAlertView.h @@ -0,0 +1,21 @@ +// +// SZHAlertView.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/29. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SZHAlertView : UIView +@property (nonatomic, strong) UIView *AlertView; +@property (nonatomic, strong) UILabel *messageLbl; //信息框 +@property (nonatomic, strong) UIButton *endBtn; //结束按钮 +@property (nonatomic, strong) UIButton *ContinueRunBtn; //继续跑步按钮 + +- (instancetype)initWithTitle:(NSString *)title; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/SZHAlertView.m b/MRMobileRun/MRRunning/SZHAlertView.m new file mode 100644 index 0000000..ad1ac0a --- /dev/null +++ b/MRMobileRun/MRRunning/SZHAlertView.m @@ -0,0 +1,187 @@ +// +// SZHAlertView.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/29. +// +#import +#import "SZHAlertView.h" + +#define Width self.bounds.size.width +#define Height self.bounds.size.height +@implementation SZHAlertView + +- (instancetype)initWithTitle:(NSString *)title{ + if (self = [super init]) { + /** + 分享的那个小界面 + */ + UIView *AlertView = [[UIView alloc] init]; + if (@available(iOS 11.0, *)) { + AlertView.backgroundColor = SZHAlertColor; + } else { + // Fallback on earlier versions + } + [self addSubview:AlertView]; + [AlertView mas_makeConstraints:^(MASConstraintMaker *make) { +// make.left.equalTo(self.mas_left).offset(screenWidth * 0.0906); +// make.top.equalTo(self.mas_top).offset(screenHeigth * 0.335); + make.center.equalTo(self); + make.size.mas_equalTo(CGSizeMake(screenWidth * 0.816,screenHeigth * 0.2463)); + }]; +// AlertView.layer.cornerRadius = 16; +// AlertView.layer.shadowRadius = 6; +// AlertView.layer.shadowOpacity = 1; + self.AlertView = AlertView; + self.AlertView.layer.cornerRadius = 16; + self.AlertView.layer.shadowRadius = 6; + + /* + 中间的label文本 + */ + self.messageLbl = [[UILabel alloc] init]; + [AlertView addSubview:self.messageLbl]; + [self.messageLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self); + make.width.mas_equalTo(216); + make.top.equalTo(AlertView.mas_top).offset(47); +// make.bottom.equalTo(self.endBtn.mas_top); + }]; + self.messageLbl.numberOfLines = 0; + self.messageLbl.textAlignment = NSTextAlignmentCenter; + if (@available(iOS 11.0, *)) { + self.messageLbl.textColor = bottomTitleColor; + } else { + // Fallback on earlier versions + } + self.messageLbl.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + self.messageLbl.text = title; + + + /* + 结束按钮 + */ + self.endBtn = [[UIButton alloc] init]; + [AlertView addSubview:_endBtn]; + [self.endBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(AlertView.mas_left).offset(18); + make.top.equalTo(self.messageLbl.mas_bottom).offset(20); + make.size.mas_equalTo(CGSizeMake(130, 44)); + }]; + if (@available(iOS 11.0, *)) { + self.endBtn.backgroundColor = GrayColor; + } else { + // Fallback on earlier versions + } + self.endBtn.layer.cornerRadius = 12; + + //给endBtn添加label + UILabel *endBtnTitleLel = [[UILabel alloc] init]; + if (@available(iOS 11.0, *)) { + endBtnTitleLel.textColor = SZHAlertTextColor; + } else { + // Fallback on earlier versions + } + + endBtnTitleLel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + endBtnTitleLel.text = @"结束"; + endBtnTitleLel.textAlignment = NSTextAlignmentCenter; + if (@available(iOS 11.0, *)) { + endBtnTitleLel.textColor = SZHAlertEndBtnTexteColor; + } else { + // Fallback on earlier versions + } + [self.endBtn addSubview:endBtnTitleLel]; + [endBtnTitleLel mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.mas_equalTo(self.endBtn.center); + make.height.mas_equalTo(22); + make.width.mas_equalTo(self.endBtn.mas_width); + }]; + + + + /* + 继续跑步按钮 + */ + self.ContinueRunBtn = [[UIButton alloc] init]; + [AlertView addSubview:self.ContinueRunBtn]; + [self.ContinueRunBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.endBtn.mas_right).offset(11); + make.size.centerY.equalTo(self.endBtn); + }]; + self.ContinueRunBtn.titleLabel.backgroundColor = [UIColor redColor]; + + //给继续跑步按钮添加lable + UILabel *continueBtnTitleLbl = [[UILabel alloc] init]; + continueBtnTitleLbl.textColor = [UIColor whiteColor]; + continueBtnTitleLbl.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + continueBtnTitleLbl.textAlignment = NSTextAlignmentCenter; + continueBtnTitleLbl.text = @"继续跑步"; + [self.ContinueRunBtn addSubview:continueBtnTitleLbl]; + [continueBtnTitleLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.mas_equalTo(self.ContinueRunBtn.center); + make.height.mas_equalTo(22); + make.width.equalTo(self.ContinueRunBtn.mas_width); + }]; + + self.ContinueRunBtn.backgroundColor = [UIColor colorWithRed:0/255.0 green:197/255.0 blue:217/255.0 alpha:1.0]; + self.ContinueRunBtn.layer.cornerRadius = 12; + + + + [self addUnabledViews]; + } + return self; +} + +//添加四周的蒙板 +- (void)addUnabledViews{ + //顶部蒙板 + UIView *topView = [[UIView alloc] init]; + [self addSubview:topView]; + [topView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.top.right.equalTo(self); + make.bottom.equalTo(self.AlertView.mas_top); + }]; + topView.alpha = 0.05; + topView.userInteractionEnabled = NO; + + //左边蒙板 + UIView *leftView = [[UIView alloc] init]; + [self addSubview:leftView]; + [leftView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self); + make.right.equalTo(self.AlertView.mas_left); + make.top.bottom.equalTo(self.AlertView); + }]; + leftView.alpha = 0.05; + leftView.userInteractionEnabled = NO; + + //右边的蒙板 + UIView *rightView = [[UIView alloc] init]; + [self addSubview:rightView]; + [rightView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.bottom.equalTo(self.AlertView); + make.right.equalTo(self); + make.left.equalTo(self.AlertView.mas_right); + }]; + rightView.alpha = 0.05; + rightView.userInteractionEnabled = NO; + + + //下面的蒙板 + UIView *bottomView = [[UIView alloc] init]; + [self addSubview:bottomView]; + [bottomView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self); + make.top.equalTo(self.AlertView.mas_bottom); + }]; + + topView.backgroundColor = [UIColor blackColor]; + leftView.backgroundColor = [UIColor blackColor]; + rightView.backgroundColor = [UIColor blackColor]; + bottomView.backgroundColor = [UIColor blackColor]; + bottomView.alpha = 0.05; + bottomView.userInteractionEnabled = NO; +} +@end diff --git a/MRMobileRun/MRRunning/SZHChart.h b/MRMobileRun/MRRunning/SZHChart.h new file mode 100644 index 0000000..554bab5 --- /dev/null +++ b/MRMobileRun/MRRunning/SZHChart.h @@ -0,0 +1,44 @@ +// +// SZHChart.h +// SZHChart +// +// Created by 石子涵 on 2020/8/6. +// Copyright © 2020 石子涵. All rights reserved. +// + +#import +/****** + 显示速度的折线图 +*/ +NS_ASSUME_NONNULL_BEGIN + +@interface SZHChart : UIView +@property double YmaxNumber; //Y轴上的最大数值,默认为6 + +@property (nonatomic, strong) UILabel *topYlabel; //纵轴顶部显示单位的label +@property (nonatomic, strong) UILabel *bottomXLabel; //X轴底部显示单位的label + +@property (nonatomic, strong) NSArray*leftLblAry; //左边的文本label数组 +@property (nonatomic, strong) NSArray *lineDataAry; //在折线图上显示的数据的数组 + +@property unsigned long bottomXCount; //底部X轴的刻度点,默认为6 + +#pragma mark- 分割线 +/** 折线颜色(默认为设计图的颜色) */ +@property (nonatomic, strong) UIColor *lineColor; +/** 折线宽(默认1) */ +@property (nonatomic, assign) CGFloat lineWidth; + +/** 渐变颜色集合 */ +@property (nonatomic, strong) NSArray *colorArr; +/** 是否填充颜色渐变(默认YES) */ +@property (nonatomic, assign) BOOL showColorGradient; + + +- (void)initWithViewsWithBooTomCount:(unsigned long )bottomCout AndLineDataAry:(NSArray *)lineDataAry AndYMaxNumber:(double )YmaxNumber; +@end + + + + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/SZHChart.m b/MRMobileRun/MRRunning/SZHChart.m new file mode 100644 index 0000000..ef8a932 --- /dev/null +++ b/MRMobileRun/MRRunning/SZHChart.m @@ -0,0 +1,240 @@ +// +// SZHChart.m +// SZHChart +// +// Created by 石子涵 on 2020/8/6. +// Copyright © 2020 石子涵. All rights reserved. +// + + +#import "SZHChart.h" +#import +#import + +#define screenWidth [UIScreen mainScreen].bounds.size.width +#define screenHeight [UIScreen mainScreen].bounds.size.height +@interface SZHChart() +@property int maxY; //最高的Y轴分割线的位置 +@property double spaceY; //Y轴各刻度间的间距; +@property double spaceX; //X轴各刻度间的间距 +@property (nonatomic, strong) UIScrollView *chartScroll; + +@property (nonatomic, assign) NSArray *pointAry; + +@property (nonatomic, strong) UIColor *textColor; +@end + + + +@implementation SZHChart +//初始化视图以及一些属性的封装 +- (void)initWithViewsWithBooTomCount:(unsigned long )bottomCout AndLineDataAry:(NSArray *)lineDataAry AndYMaxNumber:(double )YmaxNumber{ + //对一些数据的初始化 + self.spaceY = screenHeight *0.0449; + self.spaceX = screenWidth * 0.0933; + self.lineColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0]; + self.lineWidth = 6; + self.lineColor = [UIColor redColor]; + self.bottomXCount = 0; //初始的X轴lable的个数为0 + NSLog(@"传进来的速度数组为%@",lineDataAry); +// self.bottomXCount = bottomCout - 1; +// if ((bottomCout - 1 == 0 && bottomCout - 1 > 0) || (bottomCout - 1) < 6) { +// self.bottomXCount = 6; +// }else{ +// self.bottomXCount = (bottomCout - 1)/2; +// } + if (bottomCout - 1 < 6) { + self.bottomXCount = 6; + }else{ + self.bottomXCount = bottomCout - 1; + } + self.lineDataAry = lineDataAry; + self.YmaxNumber = YmaxNumber; + + //x轴单位、y轴文本、x轴文本的字体颜色 + self.textColor = [UIColor colorWithRed:136/255.0 green:136/255.0 blue:136/255.0 alpha:1.0]; + + + //显示图形的ScroolView + self.chartScroll = [[UIScrollView alloc] init]; + self.chartScroll.bounces = NO; //不回弹 + self.chartScroll.showsHorizontalScrollIndicator = NO; //不显示X轴的小滑条 + self.chartScroll.backgroundColor = [UIColor clearColor]; + self.chartScroll.contentSize = CGSizeMake( self.bottomXCount * (screenWidth * 0.1333 + 1) , self.chartScroll.bounds.size.height); // + [self addSubview:self.chartScroll]; + [self.chartScroll mas_makeConstraints:^(MASConstraintMaker *make) { +// make.left.equalTo(self.topYlabel.mas_right).offset(-10); + make.left.equalTo(self).offset(screenWidth * 0.04 + 28 - 10); + make.bottom.equalTo(self.mas_bottom); + // make.top.equalTo(self.topYlabel.mas_bottom); + make.height.mas_equalTo(_spaceY * 6 + 20); + make.width.mas_equalTo(screenWidth * 0.824); + }]; + + //Y轴单位label + self.topYlabel = [[UILabel alloc] init]; + [self addSubview:self.topYlabel]; + [self.topYlabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self); +// make.bottom.equalTo(self.chartScroll.mas_top); + make.left.equalTo(self.mas_left).offset(screenWidth * 0.04); + make.size.mas_equalTo(CGSizeMake(28, 16)); + }]; + self.topYlabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size:11]; + self.topYlabel.textColor = [UIColor colorWithRed:65/255.0 green:68/255.0 blue:72/255.0 alpha:1.0]; + + //X轴单位Label + self.bottomXLabel = [[UILabel alloc] init]; + [self addSubview:self.bottomXLabel]; + [self.bottomXLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.chartScroll.mas_right); + make.bottom.equalTo(self.chartScroll.mas_bottom); + make.size.mas_equalTo(CGSizeMake(16, 11)); + }]; + self.bottomXLabel.textColor = self.textColor; + self.bottomXLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 8]; + + //最左边的0 + UILabel *left0 = [[UILabel alloc] init]; + [self addSubview:left0]; + [left0 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.topYlabel); + make.bottom.equalTo(self); + make.size.mas_equalTo(CGSizeMake(15, 11)); + }]; + left0.text = @"0"; + left0.textAlignment = NSTextAlignmentRight; + left0.textColor = self.textColor; + left0.font = [UIFont fontWithName:@"PingFangSC-Regular" size:8]; + + [self drawLineChart]; + +} +/** + 渲染折线图 + */ +- (void)drawLineChart{ + + NSMutableArray *muteableAry = [NSMutableArray array]; //用来存储左边label的数组 + + //绘制纵轴文本和纵轴分割线 + for (int i = 1; i < 6; i++) { + //绘制纵轴文本的label + UILabel *leftLbl = [[UILabel alloc] init]; + leftLbl.textColor = self.textColor; + leftLbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 8]; + leftLbl.textAlignment = NSTextAlignmentRight; + [self addSubview:leftLbl]; + [leftLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.topYlabel); + make.bottom.equalTo(self.mas_bottom).offset(- _spaceY*i - 20 + 7.5); + make.size.mas_equalTo(CGSizeMake(15, 11)); + }]; + + //纵轴的分割线 + CALayer *line = [[CALayer alloc] init]; + line.frame = CGRectMake(0,0 + i * _spaceY,self.chartScroll.contentSize.width, 1); + line.backgroundColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0].CGColor; + if (i == 5) { + CGFloat maxY = CGRectGetMaxY(line.frame); + self.maxY = maxY; +// NSLog(@"--------------%d",self.maxY); + } + [self.chartScroll.layer addSublayer:line]; + [muteableAry addObject:leftLbl]; + } + self.leftLblAry = muteableAry; + + //绘制X轴 + CALayer *bottomline = [[CALayer alloc] init]; + bottomline.backgroundColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0].CGColor; + bottomline.frame = CGRectMake(0,6 * _spaceY,self.chartScroll.contentSize.width, 1); + [self.chartScroll.layer addSublayer:bottomline]; + + //X轴文字 + for (int i = 1; i < self.bottomXCount + 1; i++) { + UILabel *bottomlbl = [[UILabel alloc] init]; + bottomlbl.frame = CGRectMake(0 + i*_spaceX + (i-1)*15, 6 * _spaceY + 10, 15, 11); + [self.chartScroll addSubview:bottomlbl]; + bottomlbl.text = [NSString stringWithFormat:@"%d", i * 5]; + bottomlbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size:8]; + bottomlbl.textColor = self.textColor; + bottomlbl.textAlignment = NSTextAlignmentCenter; + } + //绘制折线 + [self drawLine]; + +} + +/** + * 绘制折线 + */ +- (void)drawLine{ + NSMutableArray *pointAry = [NSMutableArray array]; //用来存储关键点的数组 + for (int i = 0; i < self.lineDataAry.count; i++) { + //绘制关键点 + NSNumber * tempNum = self.lineDataAry[i]; + CGFloat ratio = tempNum.floatValue/self.YmaxNumber; + // NSLog(@"%f",ratio); + CGFloat Y = 0; +// if (tempNum.floatValue < 2) { +// Y = ((6 * _spaceY ) * ratio)/2; //关键点的竖直位置 +// }else{ + Y = (6 * _spaceY ) * ratio; //关键点的竖直位置 +// } + + // NSLog(@"%f",Y) + //关键点的横向位置; + CGFloat X = 0; + if (i == 0) { + X = 0; + }else{ + X = (8 + i*_spaceX + (i-1)*15)/2; + } + + //绘制折线 + if (pointAry.count == 0) { + NSValue *firstvalue = [NSValue valueWithCGPoint:CGPointMake(X, _spaceY * 6 - Y + _spaceY)]; + [pointAry addObject:firstvalue]; + NSLog(@"添加了一个元素%lu",(unsigned long)pointAry.count); + }else if(pointAry.count >= 0){ + //上一个坐标点 + NSValue *lastValue = pointAry.lastObject; + CGPoint lastPoint = [lastValue CGPointValue]; + //现在的坐标点 + NSValue *currentValue = [NSValue valueWithCGPoint:CGPointMake(X, _spaceY * 6 - Y + _spaceY )]; + CGPoint currentpoint = [currentValue CGPointValue]; + //设置两个控制点 + CGFloat controlX = (lastPoint.x + currentpoint.x)/2; + NSLog(@"%f",controlX); + CGPoint controlPoint1 = CGPointMake(controlX, lastPoint.y); + NSLog(@"控制点1的横纵坐标为---%f,------%f",controlPoint1.x,controlPoint1.y); + CGPoint controlPoint2 = CGPointMake(controlX, currentpoint.y); + NSLog(@"控制点2的横纵坐标为---%f,------%f",controlPoint2.x,controlPoint2.y); + UIBezierPath *linePath = [UIBezierPath bezierPath]; + linePath.lineCapStyle = kCGLineCapRound; + linePath.lineJoinStyle = kCGLineJoinMiter; + linePath.lineWidth = 6; + [linePath moveToPoint:lastPoint]; + [linePath addCurveToPoint:currentpoint controlPoint1:controlPoint1 controlPoint2:controlPoint2]; +// [linePath addLineToPoint:currentpoint]; + + CAShapeLayer *lineLayer = [CAShapeLayer layer]; + lineLayer.path = linePath.CGPath; + lineLayer.strokeColor = self.lineColor.CGColor; + lineLayer.fillColor = [UIColor clearColor].CGColor; + lineLayer.lineWidth = self.lineWidth; + lineLayer.lineCap = kCALineCapRound; + lineLayer.lineJoin = kCALineJoinRound; + lineLayer.contentsScale = [UIScreen mainScreen].scale; + [self.chartScroll.layer addSublayer:lineLayer]; + + [pointAry addObject:currentValue]; + NSLog(@"元素个数为%lu",(unsigned long)pointAry.count); + } + } +} + + +@end + diff --git a/MRMobileRun/MRRunning/SZHWaveChart.h b/MRMobileRun/MRRunning/SZHWaveChart.h new file mode 100644 index 0000000..2353bcb --- /dev/null +++ b/MRMobileRun/MRRunning/SZHWaveChart.h @@ -0,0 +1,42 @@ +// +// SZHWaveChart.h +// SZHChart +// +// Created by 石子涵 on 2020/8/8. +// Copyright © 2020 石子涵. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN +/*** + 显示步频的波浪图 + */ +@interface SZHWaveChart : UIView +@property double YmaxNumber; //Y轴上的最大数值,默认为6 + +@property (nonatomic, strong) UILabel *topYlabel; //纵轴顶部显示单位的label +@property (nonatomic, strong) UILabel *bottomXLabel; //X轴底部显示单位的label + +@property (nonatomic, strong) NSArray*leftLblAry; //左边的文本label数组 +@property (nonatomic, strong) NSArray *lineDataAry; //在折线图上显示的数据的数组 + +@property unsigned long bottomXCount; //底部X轴的刻度点,默认为6 + +#pragma mark- 分割线 +/** 折线颜色(默认为设计图的颜色) */ +@property (nonatomic, strong) UIColor *lineColor; +/** 折线宽(默认1) */ +@property (nonatomic, assign) CGFloat lineWidth; + +/** 渐变颜色集合 */ +@property (nonatomic, strong) NSArray *colorArr; +/** 是否填充颜色渐变(默认YES) */ +@property (nonatomic, assign) BOOL showColorGradient; + + +- (void)initWithViewsWithBooTomCount:(unsigned long)bottomCout AndLineDataAry:(NSArray *)lineDataAry AndYMaxNumber:(double )YmaxNumber; +@end + + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/SZHWaveChart.m b/MRMobileRun/MRRunning/SZHWaveChart.m new file mode 100644 index 0000000..bc22327 --- /dev/null +++ b/MRMobileRun/MRRunning/SZHWaveChart.m @@ -0,0 +1,355 @@ +// +// SZHWaveChart.m +// SZHChart +// +// Created by 石子涵 on 2020/8/8. +// Copyright © 2020 石子涵. All rights reserved. +// + +#import "SZHWaveChart.h" +#import +#import + +#define screenWidth [UIScreen mainScreen].bounds.size.width +#define screenHeight [UIScreen mainScreen].bounds.size.height +@interface SZHWaveChart() +@property CGPoint lastestPoint; //最后一个坐标点 +@property CGPoint startPoint; //最开始的一个坐标点 +@property int maxY; //最高的Y轴分割线的位置 +@property double spaceY; //Y轴各刻度间的间距; +@property double spaceX; //X轴各刻度间的间距 +@property (nonatomic, strong) UIScrollView *chartScroll; + +@property (nonatomic, assign) NSArray *pointAry; + +@property (nonatomic, strong) UIColor *textColor; + +@property (strong,nonatomic) UIBezierPath *circlePath; +@end + +@implementation SZHWaveChart + +//初始化视图以及一些属性的封装 +- (void)initWithViewsWithBooTomCount:(unsigned long)bottomCout AndLineDataAry:(NSArray *)lineDataAry AndYMaxNumber:(double )YmaxNumber{ + self.spaceY = screenHeight *0.0449; + self.spaceX = screenWidth * 0.0933; + self.lineColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0]; + self.lineWidth = 6; + self.lineColor = [UIColor redColor]; + //对底部X轴的lable的数目赋值 + self.bottomXCount = 0; + if (bottomCout < 6) { + self.bottomXCount = 6; + }else{ + self.bottomXCount = bottomCout - 1; + } + self.lineDataAry = lineDataAry; + self.YmaxNumber = YmaxNumber; + self.colorArr = [NSArray arrayWithObjects:(id)[[[UIColor redColor] colorWithAlphaComponent:0.4] CGColor],(id)[[[UIColor whiteColor] colorWithAlphaComponent:0.1] CGColor], nil]; + + + //x轴单位、y轴文本、x轴文本的字体颜色 + self.textColor = [UIColor colorWithRed:136/255.0 green:136/255.0 blue:136/255.0 alpha:1.0]; + + + + //显示图形的ScroolView + self.chartScroll = [[UIScrollView alloc] init]; + self.chartScroll.bounces = NO; //不回弹 + self.chartScroll.showsHorizontalScrollIndicator = YES; //不显示X轴的小滑条 + self.chartScroll.backgroundColor = [UIColor clearColor]; + self.chartScroll.contentSize = CGSizeMake( self.bottomXCount * (screenWidth * 0.1333 + 1) , self.chartScroll.bounds.size.height); //self.bottomXCount * (screenWidth * 0.1333) + [self addSubview:self.chartScroll]; + [self.chartScroll mas_makeConstraints:^(MASConstraintMaker *make) { +// make.left.equalTo(self.topYlabel.mas_right).offset(-10); + make.left.equalTo(self).offset(screenWidth * 0.04 + 28 - 10); + make.bottom.equalTo(self.mas_bottom); +// make.top.equalTo(self.topYlabel.mas_bottom); + make.height.mas_equalTo(_spaceY * 6 + 20); + make.width.mas_equalTo(screenWidth * 0.824); + }]; + + //Y轴单位label + self.topYlabel = [[UILabel alloc] init]; + [self addSubview:self.topYlabel]; + [self.topYlabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self); +// make.bottom.equalTo(self.chartScroll.mas_top); + make.left.equalTo(self.mas_left).offset(screenWidth * 0.04); + make.size.mas_equalTo(CGSizeMake(28, 16)); + }]; + self.topYlabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 11]; + self.topYlabel.textColor = [UIColor colorWithRed:65/255.0 green:68/255.0 blue:72/255.0 alpha:1.0]; + + //X轴单位Label + self.bottomXLabel = [[UILabel alloc] init]; + [self addSubview:self.bottomXLabel]; + [self.bottomXLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.chartScroll.mas_right); + make.bottom.equalTo(self.chartScroll.mas_bottom); + make.size.mas_equalTo(CGSizeMake(16, 11)); + }]; + self.bottomXLabel.textColor = self.textColor; + self.bottomXLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 8]; + + //最左边的0 + UILabel *left0 = [[UILabel alloc] init]; + [self addSubview:left0]; + [left0 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.topYlabel); + make.bottom.equalTo(self); + make.size.mas_equalTo(CGSizeMake(15, 11)); + }]; + left0.text = @"0"; + left0.textAlignment = NSTextAlignmentRight; + left0.textColor = self.textColor; + left0.font = [UIFont fontWithName:@"PingFangSC-Regular" size:8]; + + [self drawLineChart]; + +} + +//渲染折线图 +- (void)drawLineChart{ + + NSMutableArray *muteableAry = [NSMutableArray array]; //用来存储左边label的数组 + + //绘制纵轴文本和纵轴分割线 + for (int i = 1; i < 6; i++) { + //绘制纵轴文本的label + UILabel *leftLbl = [[UILabel alloc] init]; + leftLbl.textColor = self.textColor; + leftLbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 8]; + leftLbl.textAlignment = NSTextAlignmentRight; + [self addSubview:leftLbl]; + [leftLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.topYlabel); + make.bottom.equalTo(self.mas_bottom).offset(- _spaceY*i - 20 + 7.5); + make.size.mas_equalTo(CGSizeMake(15, 11)); + }]; + + //纵轴的分割线 + CALayer *line = [[CALayer alloc] init]; + line.frame = CGRectMake(0,0 + i * _spaceY,self.chartScroll.contentSize.width, 1); + line.backgroundColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0].CGColor; + if (i == 5) { + CGFloat maxY = CGRectGetMaxY(line.frame); + self.maxY = maxY; + } + [self.chartScroll.layer addSublayer:line]; + [muteableAry addObject:leftLbl]; + } + self.leftLblAry = muteableAry; + + //绘制X轴 + CALayer *bottomline = [[CALayer alloc] init]; + bottomline.backgroundColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0].CGColor; + bottomline.frame = CGRectMake(0,6 * _spaceY,self.chartScroll.contentSize.width, 1); + [self.chartScroll.layer addSublayer:bottomline]; + + //X轴文字 + for (int i = 1; i < self.bottomXCount + 1; i++) { + UILabel *bottomlbl = [[UILabel alloc] init]; + bottomlbl.frame = CGRectMake(0 + i*_spaceX + (i-1)*15, 6 * _spaceY + 10, 15, 11); + [self.chartScroll addSubview:bottomlbl]; + bottomlbl.text = [NSString stringWithFormat:@"%d", i * 5]; + bottomlbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size:8]; + bottomlbl.textColor = self.textColor; + bottomlbl.textAlignment = NSTextAlignmentCenter; + } + //绘制折线 + [self drawLine]; + +} + +/** + * 绘制折线 + */ +- (void)drawLine{ + NSMutableArray *pointAry = [NSMutableArray array]; //用来存储关键点的数组 + //遮罩图层轨迹 + UIBezierPath *shelterBezier = [UIBezierPath bezierPath]; + shelterBezier.lineCapStyle = kCGLineCapRound; + shelterBezier.lineJoinStyle = kCGLineJoinMiter; + //折线轨迹 + UIBezierPath *linePath = [UIBezierPath bezierPath]; + linePath.lineCapStyle = kCGLineCapRound; + linePath.lineJoinStyle = kCGLineJoinMiter; + linePath.lineWidth = 1; + + CGFloat X = 0; + for (int i = 0; i < self.lineDataAry.count; i++) { + //绘制关键点 + NSNumber * tempNum = self.lineDataAry[i]; + CGFloat ratio = tempNum.floatValue/self.YmaxNumber; + // NSLog(@"%f",ratio); + CGFloat Y = (5 * _spaceY ) * ratio; //关键点的竖直位置 + // NSLog(@"%f",Y); + if (i == 0) { + X = 0; + }else{ +// X = 8 + i*_spaceX + (i-1)*15; //关键点的横向位置(此处为五分钟绘制一个点) + X = 8 + (i * _spaceX + (i - 1)*5)/5; //此处为每一分钟绘制一个点 + } + + //绘制折线 和 遮罩层 + + if (pointAry.count == 0) { + NSValue *firstvalue = [NSValue valueWithCGPoint:CGPointMake(X, _spaceY * 6 - Y )]; + self.startPoint = [firstvalue CGPointValue]; + + NSLog(@"开始点的坐标%f,%f",self.startPoint.x,self.startPoint.y); + [pointAry addObject:firstvalue]; + NSLog(@"添加了一个元素%lu",(unsigned long)pointAry.count); + [linePath moveToPoint:self.startPoint]; + [shelterBezier moveToPoint:self.startPoint]; + }else if(pointAry.count >= 0){ + //上一个坐标点 + NSValue *lastValue = pointAry.lastObject; + CGPoint lastPoint = [lastValue CGPointValue]; + NSLog(@"上一个坐标点的坐标%f,%f",lastPoint.x,lastPoint.y); + //现在的坐标点 + NSValue *currentValue = [NSValue valueWithCGPoint:CGPointMake(X, _spaceY * 6 - Y )]; + CGPoint currentpoint = [currentValue CGPointValue]; + NSLog(@"现在的坐标点的坐标%f,%f",currentpoint.x,currentpoint.y); + + //设置两个控制点 + CGFloat controlX = (lastPoint.x + currentpoint.x)/2; +// NSLog(@"%f",controlX); + CGPoint controlPoint1 = CGPointMake(controlX, lastPoint.y); +// NSLog(@"控制点1的横纵坐标为---%f,------%f",controlPoint1.x,controlPoint1.y); + CGPoint controlPoint2 = CGPointMake(controlX, currentpoint.y); +// NSLog(@"控制点2的横纵坐标为---%f,------%f",controlPoint2.x,controlPoint2.y); + + //绘制折线 + [linePath addCurveToPoint:currentpoint controlPoint1:controlPoint1 controlPoint2:controlPoint2]; + //将折线添加到scroll上 + CAShapeLayer *lineLayer = [CAShapeLayer layer]; + lineLayer.path = linePath.CGPath; + lineLayer.strokeColor = [UIColor clearColor].CGColor; + lineLayer.fillColor = [UIColor clearColor].CGColor; + lineLayer.lineWidth = 1; + lineLayer.lineCap = kCALineCapRound; + lineLayer.lineJoin = kCALineJoinRound; + lineLayer.contentsScale = [UIScreen mainScreen].scale; + [self.chartScroll.layer addSublayer:lineLayer]; + + //绘制遮罩层 + [shelterBezier addCurveToPoint:currentpoint controlPoint1:controlPoint1 controlPoint2:controlPoint2]; + [pointAry addObject:currentValue]; + if (i == self.lineDataAry.count - 1) { + self.lastestPoint = currentpoint; + NSLog(@"最后一个坐标点的坐标为%f,%f",self.lastestPoint.x,self.lastestPoint.y); + + [self dralineWithShelterVezier:shelterBezier AndSTartP:self.startPoint]; + } +// NSLog(@"元素个数为%lu",(unsigned long)pointAry.count); + } + } + + self.pointAry = pointAry; + //图表颜色填充 +} + +/** + * 设置颜色渐变 + */ +//绘制遮罩层轨迹 + + +- (void)dralineWithShelterVezier:(UIBezierPath *)shelterBezier AndSTartP:(CGPoint )startP{ + CGFloat bgHeight = 6 * _spaceY; //得到在X轴上 + //获取最后一个点的X值 + CGFloat lastPointX = self.lastestPoint.x; + //最后一个点对应的x轴的位置 + CGPoint lastPointX1 = CGPointMake(lastPointX, bgHeight); + [shelterBezier addLineToPoint:lastPointX1]; //遮罩层轨迹绘制 + //回到原点 + [shelterBezier addLineToPoint:CGPointMake(startP.x, bgHeight)]; + + [shelterBezier addLineToPoint:startP]; //密闭 +// CAShapeLayer *shelterlineLayer = [CAShapeLayer layer]; +// shelterlineLayer.path = shelterBezier.CGPath; +// shelterlineLayer.strokeColor = [UIColor greenColor].CGColor; +// shelterlineLayer.fillColor = [UIColor clearColor].CGColor; +// shelterlineLayer.lineWidth = 8; +// shelterlineLayer.lineCap = kCALineCapRound; +// shelterlineLayer.lineJoin = kCALineJoinRound; +// shelterlineLayer.contentsScale = [UIScreen mainScreen].scale; +// [self.chartScroll.layer addSublayer:shelterlineLayer]; + [self addGradientWithBezierPath:shelterBezier]; +} + +//渐变图层 +-(void)addGradientWithBezierPath:(UIBezierPath *)beizer{ + //遮罩层 + CAShapeLayer *shadeLayer = [CAShapeLayer layer]; + shadeLayer.path = beizer.CGPath; + shadeLayer.fillColor = [UIColor greenColor].CGColor; + CAGradientLayer *gradientLayer = [CAGradientLayer layer]; + gradientLayer.frame = CGRectMake(CGRectGetMinX(self.chartScroll.frame), CGRectGetMinY(self.chartScroll.frame), self.chartScroll.contentSize.width, 6 * _spaceY); + gradientLayer.startPoint = CGPointMake(0, 0); + gradientLayer.endPoint = CGPointMake(0, 1); + gradientLayer.cornerRadius = 5; + gradientLayer.masksToBounds = YES; + gradientLayer.colors = @[(__bridge id)[UIColor colorWithRed:56/255.0 green:190/255.0 blue:216/255.0 alpha:0.8].CGColor,(__bridge id)[UIColor colorWithRed:106/255.0 green:207/255.0 blue:191/255.0 alpha:0.1].CGColor]; +// + gradientLayer.locations = @[@(0.5)]; + CALayer *baseLayer = [CALayer layer]; + [baseLayer addSublayer:gradientLayer]; + [baseLayer setMask:shadeLayer]; + [self.chartScroll.layer addSublayer:baseLayer]; +} + + + + + + + + + + + + + + + + + + + + + +//-(void)addBezierPoint:(NSArray *)pointArray andColor:(UIColor *)color andColors:(NSArray *)colors{ +// CGPoint startP = CGPointMake(0, 0); +// startP = [[pointArray objectAtIndex:0] CGPointValue]; +// //直线的连线 +// UIBezierPath *lineBeizer = [UIBezierPath bezierPath]; +// [lineBeizer moveToPoint:startP]; +// _circlePath = lineBeizer; +// //遮罩层的形状 +// UIBezierPath *shelterBezier = [UIBezierPath bezierPath]; +// shelterBezier.lineCapStyle = kCGLineCapRound; +// shelterBezier.lineJoinStyle = kCGLineJoinMiter; +// +// [shelterBezier moveToPoint:startP]; +// +// for (int i = 0;i 0) { +// CGPoint prePoint = [[pointArray objectAtIndex:i-1] CGPointValue]; +// CGPoint nowPoint = [[pointArray objectAtIndex:i] CGPointValue]; +// [lineBeizer addCurveToPoint:nowPoint controlPoint1:CGPointMake((nowPoint.x+prePoint.x)/2, prePoint.y) controlPoint2:CGPointMake((nowPoint.x+prePoint.x)/2, nowPoint.y)]; +// [lineBeizer addLineToPoint:nowPoint]; +// [shelterBezier addCurveToPoint:nowPoint controlPoint1:CGPointMake((nowPoint.x+prePoint.x)/2, prePoint.y) controlPoint2:CGPointMake((nowPoint.x+prePoint.x)/2, nowPoint.y)]; +// if (i == pointArray.count-1) { +// [lineBeizer moveToPoint:nowPoint];//添加连线 +// lastPoint = nowPoint; +// } +// } +// +// } +//} +@end + + diff --git a/MRMobileRun/MRRunning/StepManager.h b/MRMobileRun/MRRunning/StepManager.h new file mode 100644 index 0000000..d6c77ea --- /dev/null +++ b/MRMobileRun/MRRunning/StepManager.h @@ -0,0 +1,34 @@ +// +// StepManager.h +// MRMobileRun +// +// Created by 石子涵 on 2020/11/16. +// + +#import +#import + +@interface StepManager : NSObject + + +@property (nonatomic) NSInteger step; // 运动步数(总计) + ++ (StepManager *)sharedManager; + +//开始计步 +- (void)startWithStep; + +- (void)end; + +- (void)continueSteps; +////得到计步所消耗的卡路里 +//+ (NSInteger)getStepCalorie; +// +////得到所走的路程(单位:米) +//+ (CGFloat)getStepDistance; +// +////得到运动所用的时间 +//+ (NSInteger)getStepTime; + +@end + diff --git a/MRMobileRun/MRRunning/StepManager.m b/MRMobileRun/MRRunning/StepManager.m new file mode 100644 index 0000000..952d677 --- /dev/null +++ b/MRMobileRun/MRRunning/StepManager.m @@ -0,0 +1,285 @@ +// +// StepManager.m +// MRMobileRun +// +// Created by 石子涵 on 2020/11/16. +// + +#import "StepManager.h" +#import "StepModel.h" +#import + +// 计步器开始计步时间(秒) +#define ACCELERO_START_TIME 2 + +// 计步器开始计步步数(步) +#define ACCELERO_START_STEP 1 + +// 数据库存储步数采集间隔(步) +#define DB_STEP_INTERVAL 1 + + +@interface StepManager () + +{ + NSMutableArray *arrAll; // 加速度传感器采集的原始数组 + int record_no_save; + int record_no; + NSDate *lastDate; + +} +@property (nonatomic) NSInteger startStep; // 计步器开始步数 + +@property (nonatomic, retain) NSMutableArray *arrSteps; // 步数数组 +@property (nonatomic, retain) NSMutableArray *arrStepsSave; // 数据库纪录步数数组 + +@property (nonatomic) CGFloat gpsDistance; // GPS轨迹的移动距离(总计) +@property (nonatomic) CGFloat agoGpsDistance; // GPS轨迹的移动距离(之前) +@property (nonatomic) CGFloat agoActionDistance; // 实际运动的移动距离(之前) +//@property (nonatomic , strong) CMPedometer *pedometer; +@property (nonatomic, retain) NSString *actionId; // 运动识别ID +@property (nonatomic) CGFloat distance; // 运动里程(总计) +@property (nonatomic) NSInteger calorie; // 消耗卡路里(总计) +@property (nonatomic) NSInteger second; // 运动用时(总计) + +@end + +@implementation StepManager + +static StepManager *sharedManager; +static CMMotionManager *motionManager; + ++ (StepManager *)sharedManager +{ + @synchronized (self) { + if (!sharedManager) { + sharedManager = [[StepManager alloc]init]; + motionManager = [[CMMotionManager alloc]init]; + } + } + return sharedManager; +} + +//开始计步 +- (void)startWithStep +{ + if (!motionManager.isAccelerometerAvailable) { + NSLog(@"加速度传感器不可用"); + return; + }else { + + motionManager.accelerometerUpdateInterval = 1.0/40; + } + [self startAccelerometer]; + +} + +- (void)startAccelerometer +{ + @try + { + //如果不支持陀螺仪,需要用加速传感器来采集数据 + if (!motionManager.isAccelerometerActive) {// isAccelerometerAvailable方法用来查看加速度器的状态:是否Active(启动)。 + + // 加速度传感器采集的原始数组 + if (arrAll == nil) { + arrAll = [[NSMutableArray alloc] init]; + } + else { + [arrAll removeAllObjects]; + } + + /* + 1.push方式 + 这种方式,是实时获取到Accelerometer的数据,并且用相应的队列来显示。即主动获取加速计的数据。 + */ + NSOperationQueue *queue = [[NSOperationQueue alloc] init]; + + [motionManager startAccelerometerUpdatesToQueue:queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error){ + + if (!motionManager.isAccelerometerActive) { + return; + } + + //三个方向加速度值 + double x = accelerometerData.acceleration.x; + double y = accelerometerData.acceleration.y; + double z = accelerometerData.acceleration.z; + //g是一个double值 ,根据它的大小来判断是否计为1步. + double g = sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2)) - 1; + + //将信息保存在步数模型中 + StepModel *stepsAll = [[StepModel alloc] init]; + + stepsAll.date = [NSDate date]; + + //日期 + NSDateFormatter *df = [[NSDateFormatter alloc] init] ; + df.dateFormat = @"yyyy-MM-dd HH:mm:ss"; + NSString *strYmd = [df stringFromDate:stepsAll.date]; + df = nil; + stepsAll.record_time =strYmd; + + stepsAll.g = g; + // 加速度传感器采集的原始数组 + [self->arrAll addObject:stepsAll]; + + // 每采集10条,大约1.2秒的数据时,进行分析 + if (self->arrAll.count == 10) { + + // 步数缓存数组 + NSMutableArray *arrBuffer = [[NSMutableArray alloc] init]; + + arrBuffer = [self->arrAll copy]; + [self->arrAll removeAllObjects]; + + // 踩点数组 + NSMutableArray *arrCaiDian = [[NSMutableArray alloc] init]; + + //遍历步数缓存数组 + for (int i = 1; i < arrBuffer.count - 2; i++) { + //如果数组个数大于3,继续,否则跳出循环,用连续的三个点,要判断其振幅是否一样,如果一样,然并卵 + if (![arrBuffer objectAtIndex:i-1] || ![arrBuffer objectAtIndex:i] || ![arrBuffer objectAtIndex:i+1]) + { + continue; + } + StepModel *bufferPrevious = (StepModel *)[arrBuffer objectAtIndex:i-1]; + StepModel *bufferCurrent = (StepModel *)[arrBuffer objectAtIndex:i]; + StepModel *bufferNext = (StepModel *)[arrBuffer objectAtIndex:i+1]; + //控制震动幅度,,,,,,根据震动幅度让其加入踩点数组, + if (bufferCurrent.g < -0.12 && bufferCurrent.g < bufferPrevious.g && bufferCurrent.g < bufferNext.g) { + [arrCaiDian addObject:bufferCurrent]; + } + } + + //如果没有步数数组,初始化 + if (nil == self.arrSteps) { + self.arrSteps = [[NSMutableArray alloc] init]; + self.arrStepsSave = [[NSMutableArray alloc] init]; + } + + // 踩点过滤 + for (int j = 0; j < arrCaiDian.count; j++) { + StepModel *caidianCurrent = (StepModel *)[arrCaiDian objectAtIndex:j]; + + //如果之前的步数为0,则重新开始记录 + if (self.arrSteps.count == 0) { + //上次记录的时间 + self->lastDate = caidianCurrent.date; + + // 重新开始时,纪录No初始化 + self->record_no = 1; + self->record_no_save = 1; + + // 运动识别号 + NSTimeInterval interval = [caidianCurrent.date timeIntervalSince1970]; + NSNumber *numInter = [[NSNumber alloc] initWithDouble:interval*1000]; + long long llInter = numInter.longLongValue; + //运动识别id + self.actionId = [NSString stringWithFormat:@"%lld",llInter]; + + self.distance = 0.00f; + self.second = 0; + self.calorie = 0; + self.step = 0; + + self.gpsDistance = 0.00f; + self.agoGpsDistance = 0.00f; + self.agoActionDistance = 0.00f; + + caidianCurrent.record_no = self->record_no; + caidianCurrent.step = (int)self.step; + + [self.arrSteps addObject:caidianCurrent]; + [self.arrStepsSave addObject:caidianCurrent]; + + } + else { + + int intervalCaidian = [caidianCurrent.date timeIntervalSinceDate:self->lastDate] * 1000; + + // 步行最大每秒2.5步,跑步最大每秒3.5步,超过此范围,数据有可能丢失 + int min = 259; + if (intervalCaidian >= min) { + + if (motionManager.isAccelerometerActive) { + + //存一下时间 + self->lastDate = caidianCurrent.date; + + if (intervalCaidian >= ACCELERO_START_TIME * 1000) {// 计步器开始计步时间(秒) + self.startStep = 0; + } + + if (self.startStep < ACCELERO_START_STEP) {//计步器开始计步步数 (步) + + self.startStep ++; + break; + } + else if (self.startStep == ACCELERO_START_STEP) { + self.startStep ++; + // 计步器开始步数 + // 运动步数(总计) + self.step = self.step + self.startStep; + } + else { + self.step ++; + } + + + + //步数在这里 + NSLog(@"步数%ld",(long)self.step); + + int intervalMillSecond = [caidianCurrent.date timeIntervalSinceDate:[[self.arrSteps lastObject] date]] * 1000; + if (intervalMillSecond >= 1000) { + + self->record_no++; + + caidianCurrent.record_no = self->record_no; + + caidianCurrent.step = (int)self.step; + [self.arrSteps addObject:caidianCurrent]; + } + + // 每隔100步保存一条数据(将来插入DB用) + StepModel *arrStepsSaveVHSSteps = (StepModel *)[self.arrStepsSave lastObject]; + int intervalStep = caidianCurrent.step - arrStepsSaveVHSSteps.step; + + // DB_STEP_INTERVAL 数据库存储步数采集间隔(步) 100步 + if (self.arrStepsSave.count == 1 || intervalStep >= DB_STEP_INTERVAL) { + //保存次数 + self->record_no_save++; + caidianCurrent.record_no = self->record_no_save; + [self.arrStepsSave addObject:caidianCurrent]; + + NSLog(@"---***%ld",(long)self.step); + // 备份当前运动数据至文件中,以备APP异常退出时数据也不会丢失 + // [self bkRunningData]; + + } + } + } + + // 运动提醒检查 + // [self checkActionAlarm]; + } + } + } + }]; + + } + }@catch (NSException * e) { + NSLog(@"Exception: %@", e); + return; + } +} + +- (void)end{ + [motionManager stopAccelerometerUpdates]; +} +- (void)continueSteps{ + [motionManager startAccelerometerUpdates]; +} +@end + diff --git a/MRMobileRun/MRRunning/StepModel.h b/MRMobileRun/MRRunning/StepModel.h new file mode 100644 index 0000000..6d8848d --- /dev/null +++ b/MRMobileRun/MRRunning/StepModel.h @@ -0,0 +1,27 @@ +// +// StepModel.h +// MRMobileRun +// +// Created by 石子涵 on 2020/11/16. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface StepModel : NSObject + +@property(nonatomic,strong) NSDate *date; + +@property(nonatomic,assign) int record_no; + +@property(nonatomic, strong) NSString *record_time; + +@property(nonatomic,assign) int step; + +//g是一个震动幅度的系数,通过一定的判断条件来判断是否计做一步 +@property(nonatomic,assign) double g; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/StepModel.m b/MRMobileRun/MRRunning/StepModel.m new file mode 100644 index 0000000..c509fa6 --- /dev/null +++ b/MRMobileRun/MRRunning/StepModel.m @@ -0,0 +1,12 @@ +// +// StepModel.m +// MRMobileRun +// +// Created by 石子涵 on 2020/11/16. +// + +#import "StepModel.h" + +@implementation StepModel + +@end diff --git a/MRMobileRun/MRRunning/UIImage+SVGTool.h b/MRMobileRun/MRRunning/UIImage+SVGTool.h new file mode 100644 index 0000000..094d6ff --- /dev/null +++ b/MRMobileRun/MRRunning/UIImage+SVGTool.h @@ -0,0 +1,29 @@ +// +// UIImage+SVGTool.h +// SVGProject +// +// Created by 栗子 on 2018/9/7. +// Copyright © 2018年 http://www.cnblogs.com/Lrx-lizi/ https://github.com/lrxlizi/ https://blog.csdn.net/qq_33608748. All rights reserved. +// + +#import + +@interface UIImage (SVGTool) + +/** + @param name svg name xxx.svg + @param size image size + @return svg image + */ ++(UIImage *)svgImgNamed:(NSString *)name size:(CGSize)size; + + +/** + @param name svg name -->xxx.svg + @param size image size + @param color image color + @return svg image + */ ++ (UIImage *)svgImageNamed:(NSString *)name size:(CGSize)size imageColor:(UIColor *)color; + +@end diff --git a/MRMobileRun/MRRunning/UIImage+SVGTool.m b/MRMobileRun/MRRunning/UIImage+SVGTool.m new file mode 100644 index 0000000..574b988 --- /dev/null +++ b/MRMobileRun/MRRunning/UIImage+SVGTool.m @@ -0,0 +1,58 @@ +// +// UIImage+SVGTool.m +// SVGProject +// +// Created by 栗子 on 2018/9/7. +// Copyright © 2018年 http://www.cnblogs.com/Lrx-lizi/ https://github.com/lrxlizi/ https://blog.csdn.net/qq_33608748. All rights reserved. +// + +#import "UIImage+SVGTool.h" + +#import + +@implementation UIImage (SVGTool) + +/** + @param name svg name-->xxx.svg + @param size image size + @return svg image + */ ++(UIImage *)svgImgNamed:(NSString *)name size:(CGSize)size{ + SVGKImage *svgImg = [SVGKImage imageNamed:name]; + svgImg.size = size; + return svgImg.UIImage; +} + + +/** + @param name svg name -->xxx.svg + @param size image size + @param color image color + @return svg image + */ ++ (UIImage *)svgImageNamed:(NSString *)name size:(CGSize)size imageColor:(UIColor *)color { + + SVGKImage *svgImage = [SVGKImage imageNamed:name]; + svgImage.size = size; + CGRect rect = CGRectMake(0, 0, svgImage.size.width, svgImage.size.height); + CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(svgImage.UIImage.CGImage); + BOOL opaque = alphaInfo == kCGImageAlphaNoneSkipLast + || alphaInfo == kCGImageAlphaNoneSkipFirst + || alphaInfo == kCGImageAlphaNone; + UIGraphicsBeginImageContextWithOptions(svgImage.size, opaque, svgImage.scale); + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextTranslateCTM(context, 0, svgImage.size.height); + CGContextScaleCTM(context, 1.0, -1.0); + CGContextSetBlendMode(context, kCGBlendModeNormal); + CGContextClipToMask(context, rect, svgImage.UIImage.CGImage); + CGContextSetFillColorWithColor(context, color.CGColor); + CGContextFillRect(context, rect); + UIImage *imageOut = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return imageOut; +} + + + + +@end diff --git a/MRMobileRun/MRRunning/ZYLCountdownView.h b/MRMobileRun/MRRunning/ZYLCountdownView.h deleted file mode 100644 index 645ed0e..0000000 --- a/MRMobileRun/MRRunning/ZYLCountdownView.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// ZYLCountdownView.h -// MRMobileRun -// -// Created by 丁磊 on 2020/4/7. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface ZYLCountdownView : UIView -@property (nonatomic, strong) UILabel *countLabel; -@property (nonatomic, strong) UIButton *startButton; -@end - -NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/ZYLCountdownView.m b/MRMobileRun/MRRunning/ZYLCountdownView.m deleted file mode 100644 index 05160c3..0000000 --- a/MRMobileRun/MRRunning/ZYLCountdownView.m +++ /dev/null @@ -1,48 +0,0 @@ -// -// ZYLCountdownView.m -// MRMobileRun -// -// Created by 丁磊 on 2020/4/7. -// - -#import "ZYLCountdownView.h" -#import -@implementation ZYLCountdownView - -- (instancetype)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - if (self) { - self.backgroundColor = COLOR_WITH_HEX(0x64686F); - - self.countLabel = [[UILabel alloc] init]; - self.countLabel.font = [UIFont fontWithName:@"Impact" size:160*kRateY]; - self.countLabel.backgroundColor = [UIColor clearColor]; - self.countLabel.textColor = [UIColor whiteColor]; - self.countLabel.textAlignment = NSTextAlignmentCenter; - self.countLabel.numberOfLines = 1; - [self addSubview: self.countLabel]; - [self.countLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.centerY.equalTo(self.mas_centerY).mas_offset(-130*kRateY); - make.centerX.equalTo(self.mas_centerX); - make.width.mas_equalTo(200*kRateX); - make.height.mas_equalTo(200*kRateY); - }]; - - self.startButton = [[UIButton alloc]init]; - self.startButton.titleLabel.textColor = [UIColor whiteColor]; - self.startButton.titleLabel.font = [UIFont fontWithName:@"PingFangSC" size:16*kRateX]; - [self.startButton setTitle:@"直接开始" forState:UIControlStateNormal]; - self.startButton.backgroundColor = COLOR_WITH_HEX(0xFFFFFF); - [self addSubview: self.startButton]; - [self.startButton mas_makeConstraints:^(MASConstraintMaker *make) { - make.bottom.equalTo(self.mas_bottom).mas_offset(-229*kRateY); - make.centerX.equalTo(self.mas_centerX); - make.width.mas_equalTo(168*kRateX); - make.height.mas_equalTo(52*kRateY); - }]; - } - return self; -} - -@end diff --git a/MRMobileRun/MRRunning/ZYLMD5Encrypt.h b/MRMobileRun/MRRunning/ZYLMD5Encrypt.h deleted file mode 100644 index 11979e9..0000000 --- a/MRMobileRun/MRRunning/ZYLMD5Encrypt.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// ZYLMD5Encrypt.h -// MRMobileRun -// -// Created by 丁磊 on 2019/5/4. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface ZYLMD5Encrypt : NSObject -// MD5加密 - -// 32位小写 -+(NSString *)MD5ForLower32Bate:(NSString *)str; -// 32位大写 -+(NSString *)MD5ForUpper32Bate:(NSString *)str; -// 16为大写 -+(NSString *)MD5ForUpper16Bate:(NSString *)str; -// 16位小写 -+(NSString *)MD5ForLower16Bate:(NSString *)str; -@end - -NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/ZYLMD5Encrypt.m b/MRMobileRun/MRRunning/ZYLMD5Encrypt.m deleted file mode 100644 index cff8a6a..0000000 --- a/MRMobileRun/MRRunning/ZYLMD5Encrypt.m +++ /dev/null @@ -1,71 +0,0 @@ -// -// ZYLMD5Encrypt.m -// MRMobileRun -// -// Created by 丁磊 on 2019/5/4. -// - -#import "ZYLMD5Encrypt.h" -#import - -@implementation ZYLMD5Encrypt - - -#pragma mark - 32位 小写 -+(NSString *)MD5ForLower32Bate:(NSString *)str{ - - //要进行UTF8的转码 - const char* input = [str UTF8String]; - unsigned char result[CC_MD5_DIGEST_LENGTH]; - CC_MD5(input, (CC_LONG)strlen(input), result); - - NSMutableString *digest = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; - for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { - [digest appendFormat:@"%02x", result[i]]; - } - - return digest; -} - -#pragma mark - 32位 大写 -+(NSString *)MD5ForUpper32Bate:(NSString *)str{ - - //要进行UTF8的转码 - const char* input = [str UTF8String]; - unsigned char result[CC_MD5_DIGEST_LENGTH]; - CC_MD5(input, (CC_LONG)strlen(input), result); - - NSMutableString *digest = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; - for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { - [digest appendFormat:@"%02X", result[i]]; - } - - return digest; -} - -#pragma mark - 16位 大写 -+(NSString *)MD5ForUpper16Bate:(NSString *)str{ - - NSString *md5Str = [self MD5ForUpper32Bate:str]; - - NSString *string; - for (int i=0; i<24; i++) { - string=[md5Str substringWithRange:NSMakeRange(8, 16)]; - } - return string; -} - - -#pragma mark - 16位 小写 -+(NSString *)MD5ForLower16Bate:(NSString *)str{ - - NSString *md5Str = [self MD5ForLower32Bate:str]; - - NSString *string; - for (int i=0; i<24; i++) { - string=[md5Str substringWithRange:NSMakeRange(8, 16)]; - } - return string; -} - -@end diff --git a/MRMobileRun/MRRunning/ZYLPolling.h b/MRMobileRun/MRRunning/ZYLPolling.h deleted file mode 100644 index a9fa5d9..0000000 --- a/MRMobileRun/MRRunning/ZYLPolling.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// ZYLPolling.h -// MRMobileRun -// -// Created by 丁磊 on 2019/5/7. -// - -//轮询 - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface ZYLPolling : NSObject - - - -@end - -NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/ZYLPolling.m b/MRMobileRun/MRRunning/ZYLPolling.m deleted file mode 100644 index 899ae60..0000000 --- a/MRMobileRun/MRRunning/ZYLPolling.m +++ /dev/null @@ -1,43 +0,0 @@ -// -// ZYLPolling.m -// MRMobileRun -// -// Created by 丁磊 on 2019/5/7. -// - -#import "ZYLPolling.h" - -@implementation ZYLPolling - -+ (void)judgeActionIsEndWithTimer:(NSTimer *)judgeActionIsEndTimer { - dispatch_queue_t judgeActionIsEndQueue = dispatch_queue_create("judgeActionIsEndQueue", DISPATCH_QUEUE_SERIAL); - - __block NSTimer *judgeActionIsEndTimer1 = judgeActionIsEndTimer; - dispatch_async(judgeActionIsEndQueue, ^{ - judgeActionIsEndTimer1 = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(action) userInfo:nil repeats:YES]; - NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; - [runLoop addTimer:judgeActionIsEndTimer1 forMode:NSDefaultRunLoopMode]; - [runLoop run]; - }); -} - -- (void)action { - // 邀约是否结束(有一个人上传数据就结束)若结束 上传数据 -// AFHTTPSessionManager *isEndManager = [AFHTTPSessionManager manager]; -// NSString *isEndStrUrl = [kJudegEndUrl stringByAppendingString:[NSString stringWithFormat:@"%ld", self.invite_id]]; -// -// [isEndManager GET:isEndStrUrl parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { -// -// NSString *isEndStr = responseObject[@"data"][@"result"]; -// -// -// if ([isEndStr isEqualToString:@"END"]) { -// //此处结束跑步,传本次跑步的数据 -// -// } -// -// } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { -// NSLog(@"%@", error); -// }]; -} -@end diff --git a/MRMobileRun/MRRunning/ZYLRecordTimeString.h b/MRMobileRun/MRRunning/ZYLRecordTimeString.h deleted file mode 100644 index a9d9a04..0000000 --- a/MRMobileRun/MRRunning/ZYLRecordTimeString.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// ZYLRecordTimeString.h -// MRMobileRun -// -// Created by 丁磊 on 2019/5/6. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface ZYLRecordTimeString : NSObject -+ (NSString *)getTimeStringWithSecond:(int )second; -@end - -NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/ZYLRecordTimeString.m b/MRMobileRun/MRRunning/ZYLRecordTimeString.m deleted file mode 100644 index 4610c2b..0000000 --- a/MRMobileRun/MRRunning/ZYLRecordTimeString.m +++ /dev/null @@ -1,46 +0,0 @@ -// -// ZYLRecordTimeString.m -// MRMobileRun -// -// Created by 丁磊 on 2019/5/6. -// - -#import "ZYLRecordTimeString.h" - -@implementation ZYLRecordTimeString -+ (NSString *)getTimeStringWithSecond:(int)second{ - - NSString *secondString = [[NSString alloc] init]; - NSString *timeString = [[NSString alloc] init]; - NSString *minuteString = [[NSString alloc] init]; - NSString *hourString = [[NSString alloc] init]; - NSString *secondStr = [NSString stringWithFormat:@"%d",second%3600%60]; - if (second%3600%60 <10 ) { - secondString = [NSString stringWithFormat:@"%@%@",@"0",secondStr]; - } - else{ - secondString = [NSString stringWithFormat:@"%@",secondStr]; - } - NSString * minuteStr = [NSString stringWithFormat:@"%d",second%3600/60]; - - if (second%3600/60<10) { - minuteString = [NSString stringWithFormat:@"%@%@",@"0",minuteStr]; - } - else{ - minuteString = [NSString stringWithFormat:@"%@",minuteStr]; - - } - NSString * hourStr = [NSString stringWithFormat:@"%d",second/3600]; - if (second/3600 <10) { - hourString = [NSString stringWithFormat:@"%@%@",@"0",hourStr]; - } - else{ - hourString = [NSString stringWithFormat:@"%@",hourStr]; - - } - timeString = [NSString stringWithFormat:@"%@%@%@%@%@",hourString,@":",minuteString,@":",secondString]; - NSLog(@"%@",timeString); - return timeString; - -}//这是将秒数转化为HH:MM:SS格式数据的一个方法 -@end diff --git a/MRMobileRun/MRRunning/ZYLRunningRecordView.h b/MRMobileRun/MRRunning/ZYLRunningRecordView.h deleted file mode 100644 index 500bfdc..0000000 --- a/MRMobileRun/MRRunning/ZYLRunningRecordView.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// ZYLRunningRecordView.h -// MRMobileRun -// -// Created by 丁磊 on 2019/5/2. -// - -#import -#import "MRRunningLabel.h" -#import "MRNumLabel.h" -NS_ASSUME_NONNULL_BEGIN - -@interface ZYLRunningRecordView : UIView -- (instancetype)init; -@property (nonatomic,strong) MRRunningLabel *runningTimeLabel; - -@property (nonatomic,strong) MRNumLabel *runningDiastanceLabel; -@end - -NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/ZYLRunningRecordView.m b/MRMobileRun/MRRunning/ZYLRunningRecordView.m deleted file mode 100644 index 3e910fd..0000000 --- a/MRMobileRun/MRRunning/ZYLRunningRecordView.m +++ /dev/null @@ -1,108 +0,0 @@ -// -// ZYLRunningRecordView.m -// MRMobileRun -// -// Created by 丁磊 on 2019/5/2. -// - -#import "ZYLRunningRecordView.h" -#import - -@interface ZYLRunningRecordView () -@property (nonatomic,strong) UILabel *title; -@property (nonatomic,strong) UIImageView *showLabelView; -@property (nonatomic,strong) UIImageView *dividingLineView; -@property (nonatomic,strong) UIImageView *iconImageView; -@property (nonatomic,strong) UILabel *kmLabel; -@property (nonatomic,strong) UILabel *timeLabel; -@end -@implementation ZYLRunningRecordView - -- (instancetype)init{ - if (self = [super init]) { - [self initUI]; - return self; - } - return self; -} - -- (void)initUI{ - self.showLabelView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)]; - self.showLabelView.image = [UIImage imageNamed:@"里程用时计数白色板底"]; - [self addSubview:self.showLabelView]; - [self.showLabelView mas_makeConstraints:^(MASConstraintMaker *make) { - // make.edges.equalTo (self).with.insets(UIEdgeInsetsMake(0 ,0 ,0 ,0)); - make.top.equalTo(self.mas_top); - make.left.equalTo(self.mas_left); - make.height.equalTo(self.mas_height); - make.width.equalTo(self.mas_width); - }]; - - self.iconImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)]; - self.iconImageView.image = [UIImage imageNamed:@"用时icon"]; - - [self addSubview:self.iconImageView]; - - [self.iconImageView mas_makeConstraints:^(MASConstraintMaker *make) { -// make.edges.equalTo (self.showLabelView).with.insets(UIEdgeInsetsMake(61.0/1334.0*screenHeigth, 415.0/750*screenWidth,116.0/1334.0*screenHeigth, 226.0/750.0*screenWidth)); - make.top.equalTo(self.mas_top).mas_offset(25); - make.left.equalTo(self.mas_left).mas_offset(200); - make.height.mas_equalTo(16); - make.width.mas_equalTo(14); - }]; - - self.dividingLineView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)]; - self.dividingLineView.image = [UIImage imageNamed:@"Group 5"]; - [self addSubview:self.dividingLineView]; - [self.dividingLineView mas_makeConstraints:^(MASConstraintMaker *make) { -// make.edges.equalTo (self.showLabelView).with.insets(UIEdgeInsetsMake(54.0/1334.0*screenHeigth, 360.0/750*screenWidth, 55.0/1334.0*screenHeigth, 304.0/750.0*screenWidth)); - make.centerX.equalTo(self.mas_centerX); - make.top.equalTo(self.mas_top).mas_offset(15); - make.width.mas_equalTo(1); - make.height.equalTo(self.mas_height).mas_offset(-40); - }]; - - self.kmLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 100)]; - self.kmLabel.text = @"公里"; - self.kmLabel.font = [UIFont boldSystemFontOfSize: 12.0]; - self.kmLabel.textColor = [UIColor colorWithRed:148.0/255.0 green:147.0/255.0 blue:174.0/255.0 alpha:1]; - [self addSubview:self.kmLabel]; - [self.kmLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.right.equalTo(self.mas_centerX).mas_offset(-10); - make.bottom.equalTo(self.mas_bottom).mas_offset(-25); - make.width.mas_equalTo(30); - make.height.mas_equalTo(20); - }]; - - self.timeLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 100)]; - self.timeLabel.text = @"用时"; - self.timeLabel.font = [UIFont boldSystemFontOfSize:12.0]; - self.timeLabel.textColor = [UIColor colorWithRed:143.0/255.0 green:142.0/255.0 blue:169.0/255.0 alpha:1]; - [self addSubview:self.timeLabel]; - [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) { -// make.edges.equalTo (self.showLabelView).with.insets(UIEdgeInsetsMake(55.0/1334.0*screenHeigth, 456.0/750*screenWidth, 113.0/1334.0*screenHeigth, 160.0/750.0*screenWidth)); - make.left.equalTo(self.iconImageView.mas_right).mas_offset(5); - make.top.equalTo(self.iconImageView.mas_top).mas_offset(0); - make.width.mas_equalTo(30); - make.height.mas_equalTo(20); - }]; - - self.runningTimeLabel = [[MRRunningLabel alloc]init]; - self.runningTimeLabel.textColor = [UIColor blackColor]; - [self addSubview:self.runningTimeLabel]; - [self.runningTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo (self.showLabelView).with.insets(UIEdgeInsetsMake(75.0/1334.0*screenHeigth, 390.0/750*screenWidth, 45.0/1334.0*screenHeigth, 50.0/750.0*screenWidth)); - }]; - - self.runningDiastanceLabel = [[MRNumLabel alloc]init]; - self.runningDiastanceLabel.text = @"0.000"; - self.runningDiastanceLabel.font = [UIFont fontWithName:@"DINAlternate-Bold" size:49.0*screenWidth/414.0]; - [self addSubview:self.runningDiastanceLabel]; - [self.runningDiastanceLabel mas_makeConstraints:^(MASConstraintMaker *make) { - make.edges.equalTo (self.showLabelView).with.insets(UIEdgeInsetsMake(38.0/1334.0*screenHeigth, 59.0/750*screenWidth, 33.0/1334.0*screenHeigth, 414.0/750.0*screenWidth)); - }]; - -} - - -@end diff --git a/MRMobileRun/MRRunning/ZYLRunningTabView.h b/MRMobileRun/MRRunning/ZYLRunningTabView.h deleted file mode 100644 index 2cf2b34..0000000 --- a/MRMobileRun/MRRunning/ZYLRunningTabView.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// ZYLRunningTabView.h -// MRMobileRun -// -// Created by 丁磊 on 2019/5/2. -// - -#import -#import "MRStopBtu.h" -#import "MRPauseAndResumeBtu.h" -NS_ASSUME_NONNULL_BEGIN - -@interface ZYLRunningTabView : UIView -@property (nonatomic,strong) MRPauseAndResumeBtu *pauseAndResumeBtu; -//继续暂停按钮 -@property (nonatomic,strong) MRStopBtu *stopBtu; -//停止按钮 -@end - -NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/ZYLRunningTabView.m b/MRMobileRun/MRRunning/ZYLRunningTabView.m deleted file mode 100644 index d832b5d..0000000 --- a/MRMobileRun/MRRunning/ZYLRunningTabView.m +++ /dev/null @@ -1,119 +0,0 @@ -// -// ZYLRunningTabView.m -// MRMobileRun -// -// Created by 丁磊 on 2019/5/2. -// - -#import "ZYLRunningTabView.h" -#import - -@interface ZYLRunningTabView () - -@property (nonatomic,strong) UIImageView *navImageView; -//导航栏底部图片 -@property (nonatomic,strong) UIImageView *bottomImageView; -//视图底部图片 -@end - -@implementation ZYLRunningTabView -- (instancetype)init{ - if (self = [super init]) { - self.frame = CGRectMake(0, 0, screenWidth, 160); - [self initUI]; - - return self; - } - return self; -} - -- (void)initUI{ - [self initpauseAndResumeBtu]; - [self initstopBtu]; - [self initBackGruondView]; -} - - -- (void)initpauseAndResumeBtu{ - //初始化暂停继续按钮 - self.pauseAndResumeBtu = [[MRPauseAndResumeBtu alloc]init]; -// self.pauseAndResumeBtu.contentEdgeInsets = UIEdgeInsetsMake(screenHeigth *48.0 /1334,screenWidth *56.0/750, screenHeigth *64.0 /1334, screenWidth *52.0/750); - [self addSubview:self.pauseAndResumeBtu]; - [self.pauseAndResumeBtu setTitle:@"暂停" forState:UIControlStateNormal]; - if (kIs_iPhoneX) { - [self.pauseAndResumeBtu mas_makeConstraints:^(MASConstraintMaker *make) { - // make.edges.equalTo (self).with.insets(UIEdgeInsetsMake(1074.0/1334.0*screenHeigth, 121.0/750*screenWidth, 50.0/1334.0*screenHeigth, 422.0/750.0*screenWidth)); - make.left.equalTo(self.mas_left).mas_offset(50); - make.centerY.equalTo(self.mas_centerY).mas_offset(0); - make.width.mas_equalTo(120); - make.height.mas_equalTo(120); - }]; - }else{ - [self.pauseAndResumeBtu mas_makeConstraints:^(MASConstraintMaker *make) { - // make.edges.equalTo (self).with.insets(UIEdgeInsetsMake(1074.0/1334.0*screenHeigth, 121.0/750*screenWidth, 50.0/1334.0*screenHeigth, 422.0/750.0*screenWidth)); - make.left.equalTo(self.mas_left).mas_offset(50); - make.centerY.equalTo(self.mas_centerY).mas_offset(0); - make.width.mas_equalTo(100); - make.height.mas_equalTo(100); - }]; - } -} - -- (void)initstopBtu{ - //初始化结束按钮 - - self.stopBtu = [[MRStopBtu alloc]init]; - [self addSubview:self.stopBtu]; -// self.stopBtu.contentEdgeInsets = UIEdgeInsetsMake(screenHeigth *48.0 /1334,screenWidth *60.0/750, screenHeigth *64.0 /1334, screenWidth *56.0/750); - if (kIs_iPhoneX) { - [self.stopBtu mas_makeConstraints:^(MASConstraintMaker *make) { - // make.edges.equalTo (self).with.insets(UIEdgeInsetsMake(1074.0/1334.0*screenHeigth, 121.0/750*screenWidth, 50.0/1334.0*screenHeigth, 422.0/750.0*screenWidth)); - make.right.equalTo(self.mas_right).mas_offset(-50); - make.centerY.equalTo(self.mas_centerY).mas_offset(0); - make.width.mas_equalTo(120); - make.height.mas_equalTo(120); - }]; - }else{ - [self.stopBtu mas_makeConstraints:^(MASConstraintMaker *make) { - // make.edges.equalTo (self).with.insets(UIEdgeInsetsMake(1074.0/1334.0*screenHeigth, 121.0/750*screenWidth, 50.0/1334.0*screenHeigth, 422.0/750.0*screenWidth)); - make.right.equalTo(self.mas_right).mas_offset(-50); - make.centerY.equalTo(self.mas_centerY).mas_offset(0); - make.width.mas_equalTo(100); - make.height.mas_equalTo(100); - }]; - } - -} - - - - -- (void)initBackGruondView{ - self.bottomImageView = [[UIImageView alloc]init]; - self.bottomImageView.image = [UIImage imageNamed:@"按钮底"]; - [self addSubview:self.bottomImageView]; - [self sendSubviewToBack:self.bottomImageView]; - [self.bottomImageView mas_makeConstraints:^(MASConstraintMaker *make) { -// make.edges.equalTo (self).with.insets(UIEdgeInsetsMake(997.0/1334.0*screenHeigth, 0 , 0, 0)); - make.left.equalTo(self.mas_left); - make.top.equalTo(self.mas_top); - make.right.equalTo(self.mas_right); - make.bottom.equalTo(self.mas_bottom); - }]; - - self.navImageView = [[UIImageView alloc]init]; - self.navImageView.image = [UIImage imageNamed:@"开始跑步nav+状态栏底"]; - [self addSubview:self.navImageView]; - [self sendSubviewToBack:self.navImageView]; - [self.navImageView mas_makeConstraints:^(MASConstraintMaker *make) { -// make.edges.equalTo (self).with.insets(UIEdgeInsetsMake(0, 0 , 1206.0/1334.0*screenHeigth, 0)); - make.left.equalTo(self.mas_left); - make.top.equalTo(self.mas_top); - make.right.equalTo(self.mas_right); - make.bottom.equalTo(self.mas_bottom); - }]; -} - - - -@end diff --git a/MRMobileRun/MRRunning/ZYLRunningViewController.h b/MRMobileRun/MRRunning/ZYLRunningViewController.h index 9ba1fa4..be2fe5f 100644 --- a/MRMobileRun/MRRunning/ZYLRunningViewController.h +++ b/MRMobileRun/MRRunning/ZYLRunningViewController.h @@ -9,10 +9,10 @@ NS_ASSUME_NONNULL_BEGIN -@interface ZYLRunningViewController : MRBaseViewController -//获取时间戳 -+(NSString *)currentDateInterval; -+(NSString *)MD5:(NSString *)input; +@interface ZYLRunningViewController :UIViewController //MRBaseViewController +////获取时间戳 +//+(NSString *)currentDateInterval; +//+(NSString *)MD5:(NSString *)input; @end NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/ZYLRunningViewController.m b/MRMobileRun/MRRunning/ZYLRunningViewController.m index 09b8b1d..eb518dc 100644 --- a/MRMobileRun/MRRunning/ZYLRunningViewController.m +++ b/MRMobileRun/MRRunning/ZYLRunningViewController.m @@ -10,434 +10,126 @@ *后面再改个sdk */ +#import "RunMainPageCV.h" #import "ZYLRunningViewController.h" +#import "MRTabBarController.h" + #import -#import "LJJInviteSearchResultViewController.h" #import #import -//#import -#import "ZYLTimeStamp.h" -#import "ZYLSteps.h" -#import "ZYLUptateRunningData.h" -#import "ZYLRunningTabView.h" -#import "ZYLRunningRecordView.h" -#import "MRAlertView.h" -#import "ZYLBackBtn.h" -#import "ZYLRecordTimeString.h" -#import "ZYLMainViewController.h" -#import -#import "MRLoginViewController.h" -#import "ZYLButtonNoticeView.h" -#import "ZYLUpdateData.h" #import "HttpClient.h" - @interface ZYLRunningViewController () -@property (strong, nonatomic) CLLocationManager *manager; -@property (strong, nonatomic) MKMapView *mapView; -@property (strong, nonatomic) NSMutableArray *locationArray; -@property (strong, nonatomic) NSString *beginTime; -@property (strong, nonatomic) NSString *endTime; -@property (nonatomic, weak) NSTimer *runTime; -@property (nonatomic, weak) NSTimer *presentTime; -@property (nonatomic, strong) ZYLButtonNoticeView *noticeView; -@property (strong, nonatomic) ZYLSteps *zylSteps; -@property (strong, nonatomic) ZYLRunningTabView *runTabView; -@property (strong, nonatomic) ZYLRunningRecordView *recordView; -@property (strong, nonatomic) MRAlertView *alertView; -@property (assign, nonatomic) double distance; -@property (copy, nonatomic) NSNumber *steps; -@property (nonatomic) int hour; -@property (nonatomic) int minute; -@property (nonatomic) int second; +{ NSTimer *timer; + NSInteger totalSeconds; +} +@property (nonatomic, strong) UILabel *NumberLabel; //数字倒数框 +@property (nonatomic, strong) UIButton *BeginBtn; //直接开始 +@property (nonatomic, strong) UIView *btnView; @end @implementation ZYLRunningViewController - - (void)viewWillAppear:(BOOL)animated{ - self.title = @"开始跑步"; - [self.navigationController setNavigationBarHidden:NO]; - - ZYLBackBtn *backBtn = [[ZYLBackBtn alloc] init]; - [backBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; - UIBarButtonItem *barItem =[[UIBarButtonItem alloc] initWithCustomView: backBtn]; - self.navigationItem.leftBarButtonItem = barItem; + [super viewWillAppear:YES]; + self.tabBarController.tabBar.hidden = YES; + NSArray *viewControllers = self.navigationController.viewControllers; + if ([viewControllers indexOfObject:self]) { + self.tabBarController.selectedIndex = 0; + } } - (void)viewDidLoad { [super viewDidLoad]; - - self.beginTime = [ZYLTimeStamp getTimeStamp]; -// [ZYLUptateRunningData ZYLPostUninviteRunningDataWithDataString: ]; - self.distance = 0; - self.locationArray = [NSMutableArray array]; - self.runTime = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(startTimer) userInfo:nil repeats:YES]; - self.second = self.minute = self.hour = 0; - - - [self.view addSubview: self.mapView]; - [self.view addSubview: self.runTabView]; - [self.view addSubview: self.recordView]; - [self loadConstrains]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(UpdataDataError) name:@"UpdateRunningDataError" object:nil]; - - NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; - if ([user objectForKey:@"runningData"]) { - [ZYLUptateRunningData ZYLPostUninviteRunningDataWithDataString: [user objectForKey:@"runningData"]]; - } - - self.manager = [[CLLocationManager alloc] init]; - [self.manager requestAlwaysAuthorization]; - self.manager.delegate= self; - self.manager.distanceFilter = 10; - self.manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; - [self.manager startUpdatingLocation]; -} - -//加载约束 -- (void)loadConstrains{ - if (kIs_iPhoneX) { - [self.mapView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.view.mas_top); - make.left.equalTo(self.view.mas_left); - make.height.equalTo(self.view.mas_height).mas_offset(-160); - make.width.equalTo(self.view.mas_width); - }]; - - [self.runTabView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.mapView.mas_bottom); - make.left.equalTo(self.view.mas_left); - make.height.mas_equalTo(160); - make.width.equalTo(self.view.mas_width); - }]; + self.view.backgroundColor = [UIColor colorWithRed:100/255.0 green:104/255.0 blue:111/255.0 alpha:1.0]; + [self Add]; + + //定时器 + totalSeconds = 3; +if (!timer) { + timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(changeLabelStr) userInfo:nil repeats:YES]; + [timer fire]; + } +} + +//添加控件 +- (void)Add{ + //数字倒数框 + self.NumberLabel = [[UILabel alloc] init]; + [self.view addSubview:self.NumberLabel]; + [self.NumberLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self.view); +// make.size.mas_equalTo(CGSizeMake(92, 195)); + make.left.right.equalTo(self.view); + make.height.mas_equalTo(195); - [self.recordView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.view.mas_top).mas_offset(120); - make.left.equalTo(self.view.mas_left).mas_offset(20); - make.height.mas_equalTo(120); - make.width.equalTo(self.view.mas_width).mas_offset(-40); - }]; - }else{ - [self.mapView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.view.mas_top); - make.left.equalTo(self.view.mas_left); - make.height.equalTo(self.view.mas_height).mas_offset(-130); - make.width.equalTo(self.view.mas_width); - }]; - - [self.runTabView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.mapView.mas_bottom); - make.left.equalTo(self.view.mas_left); - make.height.mas_equalTo(130); - make.width.equalTo(self.view.mas_width); - }]; - - [self.recordView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.view.mas_top).mas_offset(85); - make.left.equalTo(self.view.mas_left).mas_offset(20); - make.height.mas_equalTo(100); - make.width.equalTo(self.view.mas_width).mas_offset(-40); - }]; - } -} - -- (void)startTimer{ - if ([self.runTabView.pauseAndResumeBtu.titleLabel.text isEqualToString:@"暂停" ]) { - - self.second ++; - - if (self.second == 86400) { - self.second = 0; - } - NSLog(@"%d",self.second); - - } - - NSString *timeString = [ZYLRecordTimeString getTimeStringWithSecond:self.second]; - //获取跑步时间 - self.recordView.runningTimeLabel.text = timeString; - [self.recordView.runningDiastanceLabel setFontWithSize:49 andFloatTitle:self.distance/1000.0]; - -} - -#pragma mark - MKMapViewDelegate -/** - 更新用户位置,只要用户改变则调用此方法(包括第一次定位到用户位置) - 第一种画轨迹的方法:我们使用在地图上的变化来描绘轨迹,这种方式不用考虑从 CLLocationManager 取出的经纬度在 mapView 上显示有偏差的问题 - */ --(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{ - - NSString *latitude = [NSString stringWithFormat:@"%3.6f",userLocation.coordinate.latitude]; - NSString *longitude = [NSString stringWithFormat:@"%3.6f",userLocation.coordinate.longitude]; -// NSLog(@"更新的用户位置:纬度:%@, 经度:%@",latitude,longitude); - //设置地图显示范围(如果不进行区域设置会自动显示区域范围并指定当前用户位置为地图中心点) - MKCoordinateSpan span = MKCoordinateSpanMake(0.05, 0.05); - MKCoordinateRegion region =MKCoordinateRegionMake(userLocation.location.coordinate, span); - [_mapView setRegion:region animated:true]; - - if (self.locationArray.count != 0) { - - //从位置数组中取出最新的位置数据 - NSDictionary *dic = self.locationArray.lastObject; - NSString *latitudeStr = dic[@"latitude"]; - NSString *longitudeStr = dic[@"longitude"]; - CLLocationCoordinate2D startCoordinate = CLLocationCoordinate2DMake([latitudeStr doubleValue], [longitudeStr doubleValue]); - - //当前确定到的位置数据 - CLLocationCoordinate2D endCoordinate; - endCoordinate.latitude = userLocation.coordinate.latitude; - endCoordinate.longitude = userLocation.coordinate.longitude; - - //移动距离的计算 - double meters = [self calculateDistanceWithStart:startCoordinate end:endCoordinate]; - self.distance += meters; - NSLog(@"移动的距离为%f米",meters); - - //为了美化移动的轨迹,移动的位置超过10米,方可添加进位置的数组 - if (meters >= 10){ - -// NSLog(@"添加进位置数组"); - NSDictionary *dic = @{@"latitude": latitude, @"longitude": longitude}; - [self.locationArray addObject: dic]; - - //开始绘制轨迹 - CLLocationCoordinate2D pointsToUse[2]; - pointsToUse[0] = startCoordinate; - pointsToUse[1] = endCoordinate; - //调用 addOverlay 方法后,会进入 rendererForOverlay 方法,完成轨迹的绘制 - MKPolyline *lineOne = [MKPolyline polylineWithCoordinates:pointsToUse count:2]; - [_mapView addOverlay:lineOne]; - - }else{ - -// NSLog(@"不添加进位置数组"); - } - }else{ - NSDictionary *dic = @{@"latitude": latitude, @"longitude": longitude}; - [self.locationArray addObject: dic]; - //存放位置的数组,如果数组包含的对象个数为0,那么说明是第一次进入,将当前的位置添加到位置数组 - } -} - - --(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay{ - - if ([overlay isKindOfClass:[MKPolyline class]]){ -#pragma clang diagnostic push -#pragma clang diagnostic ignored"-Wdeprecated-declarations" - MKPolylineView *polyLineView = [[MKPolylineView alloc] initWithPolyline:overlay]; - polyLineView.lineWidth = 10; //折线宽度 - polyLineView.lineJoin = kCGLineJoinBevel;//连接类型 - polyLineView.strokeColor = [UIColor blueColor]; //折线颜色 - return (MKOverlayRenderer *)polyLineView; -#pragma clang diagnostic pop - } - return nil; -} - - -#pragma mark - CLLocationManagerDelegate -/** - * 当前定位授权状态发生改变时调用 - * - * @param manager 位置管理者 - * @param status 授权的状态 - */ --(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status -{ - switch (status) { - case kCLAuthorizationStatusNotDetermined:{ - NSLog(@"用户还未进行授权"); - break; - } - case kCLAuthorizationStatusDenied:{ - // 判断当前设备是否支持定位和定位服务是否开启 - if([CLLocationManager locationServicesEnabled]){ - - NSLog(@"用户不允许程序访问位置信息或者手动关闭了位置信息的访问,帮助跳转到设置界面"); - - NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; - if ([[UIApplication sharedApplication] canOpenURL:url]) { - [[UIApplication sharedApplication] openURL: url]; - } - }else{ - NSLog(@"定位服务关闭,弹出系统的提示框,点击设置可以跳转到定位服务界面进行定位服务的开启"); - } - break; - } - case kCLAuthorizationStatusRestricted:{ - NSLog(@"受限制的"); - break; - } - case kCLAuthorizationStatusAuthorizedAlways:{ - NSLog(@"授权允许在前台和后台均可使用定位服务"); - break; - } - case kCLAuthorizationStatusAuthorizedWhenInUse:{ - NSLog(@"授权允许在前台可使用定位服务"); - break; - } - - default: - break; - } -} -/** - 我们并没有把从 CLLocationManager 取出来的经纬度放到 mapView 上显示 - 原因: - 我们在此方法中取到的经纬度依据的标准是地球坐标,但是国内的地图显示按照的标准是火星坐标 - MKMapView 不用在做任何的处理,是因为 MKMapView 是已经经过处理的 - 也就导致此方法中获取的坐标在 mapView 上显示是有偏差的 - 解决的办法有很多种,可以上网就行查询,这里就不再多做赘述 - */ -- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations -{ - //设备的当前位置 - CLLocation *currLocation = [locations lastObject]; - - NSString *latitude = [NSString stringWithFormat:@"纬度:%3.5f",currLocation.coordinate.latitude]; - NSString *longitude = [NSString stringWithFormat:@"经度:%3.5f",currLocation.coordinate.longitude]; - NSString *altitude = [NSString stringWithFormat:@"高度值:%3.5f",currLocation.altitude]; - - NSLog(@"位置发生改变:纬度:%@,经度:%@,高度:%@",latitude,longitude,altitude); - - - [manager stopUpdatingLocation]; -} - -//定位失败的回调方法 -- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error -{ - NSLog(@"无法获取当前位置 error : %@",error.localizedDescription); -} - + }]; -#pragma mark - 距离测算 -- (double)calculateDistanceWithStart:(CLLocationCoordinate2D)start end:(CLLocationCoordinate2D)end { - - double meter = 0; + self.NumberLabel.font = [UIFont fontWithName:@"Impact" size: 160]; + self.NumberLabel.textColor = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0]; + self.NumberLabel.textAlignment = NSTextAlignmentCenter; + self.NumberLabel.text = @"0"; - double startLongitude = start.longitude; - double startLatitude = start.latitude; - double endLongitude = end.longitude; - double endLatitude = end.latitude; - double radLatitude1 = startLatitude * M_PI / 180.0; - double radLatitude2 = endLatitude * M_PI / 180.0; - double a = fabs(radLatitude1 - radLatitude2); - double b = fabs(startLongitude * M_PI / 180.0 - endLongitude * M_PI / 180.0); - double s = 2 * asin(sqrt(pow(sin(a/2),2) + cos(radLatitude1) * cos(radLatitude2) * pow(sin(b/2),2))); - s = s * 6378137; - - meter = round(s * 10000) / 10000; - return meter; -} -#pragma mark - button响应事件 - -//上传数据,返回首页 -- (void)back{ - //返回首页 -// [MGJRouter openURL:kMainVCPageURL -// withUserInfo:@{@"navigationVC" : self.navigationController, -// } -// completion:nil]; - ZYLMainViewController *mainVC = [[ZYLMainViewController alloc] init]; - UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController: mainVC]; - [UIApplication sharedApplication].keyWindow.rootViewController = nav; - [LJJInviteSearchResultViewController removeChildVc:self]; -} - -- (void)UpdateData{ - [self updateRunningData]; -// [self UpdataDataError]; -} - -- (void)stopRunning:(UIButton *)sender{ - [self.runTabView.pauseAndResumeBtu setTitle:@"暂停" forState:UIControlStateNormal]; - [self.runTabView.pauseAndResumeBtu setBackgroundImage:[UIImage imageNamed:@"暂停按钮"] forState:UIControlStateNormal]; - if ( self.distance <100 ||self.second < 60 ){ - self.alertView = [MRAlertView alertViewWithTitle:@"此次跑步路程过短哦,不能作为跑步记录保存,确定不跑了吗?" action:^{ - NSLog(@"哈哈哈哈哈"); - }]; - [self.alertView.okButton addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; - - [self.view addSubview:self.alertView]; - } - else{ - self.alertView = [MRAlertView alertViewWithTitle:@"确定结束此次跑步了吗?" action:^{ - NSLog(@"哈哈哈哈哈"); + //直接开始那一块儿不同颜色的view + UIView *view = [[UIView alloc] init]; + view.backgroundColor = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:0.2]; + [self.view addSubview:view]; + [view mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.NumberLabel); + make.top.equalTo(self.NumberLabel.mas_bottom).offset(91); + make.size.mas_equalTo(CGSizeMake(168, 52)); }]; - [self.alertView.okButton addTarget:self action:@selector(UpdateData) forControlEvents:UIControlEventTouchUpInside]; - [self.view addSubview:self.alertView]; - } -} - -- (void) updateRunningData{ - self.zylSteps = [[ZYLSteps alloc] init]; - self.endTime = [ZYLTimeStamp getTimeStamp]; - self.steps = [self.zylSteps getStepsFromBeginTime:[ZYLTimeStamp getDateFromTimeStamp:self.beginTime] ToEndTime:[ZYLTimeStamp getDateFromTimeStamp:self.endTime]]; - dispatch_queue_t updateRunningQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); - dispatch_async(updateRunningQueue, ^{ - NSString *dataStr = [ZYLUpdateData ZYLGetUpdateDataDictionaryWithBegintime: @([self.beginTime integerValue]) Endtime:@([self.endTime integerValue]) distance:[NSNumber numberWithDouble: self.distance] lat_lng:self.locationArray andSteps: self.steps]; - [ZYLUptateRunningData ZYLPostUninviteRunningDataWithDataString: dataStr]; - }); -} - -- (void)UpdataDataError{ - self.noticeView = [ZYLButtonNoticeView viewInitWithText:@"无网络,我们将自动记录你这次的跑步数据"]; - [self.view addSubview:self.noticeView]; - [self.noticeView mas_makeConstraints:^(MASConstraintMaker *make) { - make.bottom.equalTo(self.runTabView.mas_top).mas_offset(-20); - make.centerX.equalTo(self.view.mas_centerX); - make.width.mas_equalTo(300); - make.height.mas_equalTo(50); + self.btnView = view; + self.btnView.layer.cornerRadius = 12; + + self.BeginBtn = [[UIButton alloc] init]; + [self.view addSubview:self.BeginBtn]; + [self.BeginBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(view); + make.size.equalTo(view); }]; -} - -#pragma mark - 懒加载 -- (MKMapView *)mapView{ - if (!_mapView) { - _mapView = [[MKMapView alloc] init]; - _mapView.showsUserLocation = YES; - _mapView.userTrackingMode = MKUserTrackingModeFollow; - _mapView.delegate = self; + [self.BeginBtn setTintColor:[UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0]]; + self.BeginBtn.titleLabel.font = [UIFont fontWithName:@"PingFangSC" size: 16]; + [self.BeginBtn setTitle:@"直接开始" forState:UIControlStateNormal]; + [self.BeginBtn addTarget:self action:@selector(Begin) forControlEvents:UIControlEventTouchUpInside]; + self.BeginBtn.layer.cornerRadius = 12; + +} +//随计时器改变label里面的数字 +-(void)changeLabelStr +{ // int seconds = totalSeconds - 1; + self.NumberLabel.text =[NSString stringWithFormat:@"%ld",(long)totalSeconds--]; +// totalSeconds --; + if (totalSeconds == -1) { + [timer invalidate]; + self.NumberLabel.text = @"Go"; +// [self.BeginBtn removeFromSuperview]; +// [self.btnView removeFromSuperview]; + RunMainPageCV *cv = [[RunMainPageCV alloc] init]; + [self.navigationController pushViewController:cv animated:YES]; } - return _mapView; -} - -- (ZYLRunningRecordView *)recordView{ - if (!_recordView) { - _recordView = [[ZYLRunningRecordView alloc] init]; - } - return _recordView; -} - -- (ZYLRunningTabView *)runTabView{ - if (!_runTabView) { - _runTabView = [[ZYLRunningTabView alloc] init]; - [_runTabView.stopBtu addTarget:self action:@selector(stopRunning:) forControlEvents:UIControlEventTouchUpInside]; - } - return _runTabView; -} - -+(NSString *)currentDateInterval -{ - NSDate *dateNow = [NSDate date]; - NSString *time = [NSString stringWithFormat:@"%ld",(long)([dateNow timeIntervalSince1970] * 1000)]; - return time; -} - -+(NSString *)MD5:(NSString *)input -{ - const char *str = [input UTF8String]; - unsigned char digest[CC_MD5_DIGEST_LENGTH]; - CC_MD5(str, strlen(str), digest); - NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH *2]; - for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i ++) - { - [output appendFormat:@"%02x",digest[i]]; - } - return output; -} + CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; + NSValue *value1 = [NSNumber numberWithFloat:3.0f]; + NSValue *value2 = [NSNumber numberWithFloat:2.0f]; + NSValue *value3 = [NSNumber numberWithFloat:0.7f]; + NSValue *value4 = [NSNumber numberWithFloat:1.0f]; + anima.values = @[value1,value2,value3,value4]; + anima.duration = 0.5; + [self.NumberLabel.layer addAnimation:anima forKey:@"scalsTime"]; + +} + +//直接开始功能 +- (void)Begin{ + //切换到Go图片,并且跳转到基础界面 + [timer invalidate]; + self.NumberLabel.text = @"Go"; + self.tabBarController.tabBar.hidden = YES; + RunMainPageCV *cv = [[RunMainPageCV alloc] init]; + [self.navigationController pushViewController:cv animated:YES]; + +} +//- (void)dealloc{ +// [[NSNotificationCenter defaultCenter]removeObserver:self]; +//} @end diff --git a/MRMobileRun/MRRunning/ZYLSteps.h b/MRMobileRun/MRRunning/ZYLSteps.h deleted file mode 100644 index cde644e..0000000 --- a/MRMobileRun/MRRunning/ZYLSteps.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// ZYLSteps.h -// MRMobileRun -// -// Created by 丁磊 on 2019/5/3. -// - -#import -#import -NS_ASSUME_NONNULL_BEGIN - -typedef void(^GetStepsBlcok) (NSNumber *steps); - -@interface ZYLSteps : NSObject - -@property (nonatomic,copy)GetStepsBlcok getStepsBlcok; -- (NSNumber *)getStepsFromBeginTime:(NSDate *)begin ToEndTime:(NSDate *)end; -@end - -NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/ZYLSteps.m b/MRMobileRun/MRRunning/ZYLSteps.m deleted file mode 100644 index 185a619..0000000 --- a/MRMobileRun/MRRunning/ZYLSteps.m +++ /dev/null @@ -1,34 +0,0 @@ -// -// ZYLSteps.m -// MRMobileRun -// -// Created by 丁磊 on 2019/5/3. -// - -#import "ZYLSteps.h" - -@interface ZYLSteps () -@end -@implementation ZYLSteps -- (NSNumber *)getStepsFromBeginTime:(NSDate *)begin ToEndTime:(NSDate *)end{ - - CMPedometer *pedometer = [[CMPedometer alloc] init]; - if ([CMPedometer isStepCountingAvailable]) { - //获取昨天的步数与距离数据 - [pedometer queryPedometerDataFromDate:begin toDate:end withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) { - if (error) { - NSLog(@"error===%@",error); - } - else { - NSLog(@"步数===%@",pedometerData.numberOfSteps); - self.getStepsBlcok(pedometerData.numberOfSteps); - } - }]; - } else { - NSLog(@"不可用==="); - return @0; - } - return @0; -} - -@end diff --git a/MRMobileRun/MRRunning/ZYLUpdateData.h b/MRMobileRun/MRRunning/ZYLUpdateData.h deleted file mode 100644 index 9bc8399..0000000 --- a/MRMobileRun/MRRunning/ZYLUpdateData.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// ZYLUpdateData.h -// MRMobileRun -// -// Created by 丁磊 on 2019/5/3. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface ZYLUpdateData : NSObject -+ (NSString *)ZYLGetUpdateDataDictionaryWithBegintime:(NSNumber *)begin Endtime:(NSNumber *)end distance:(NSNumber *)distance lat_lng:(NSArray *)lat_lng andSteps:(NSNumber *)steps; -@end - -NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRRunning/ZYLUpdateData.m b/MRMobileRun/MRRunning/ZYLUpdateData.m deleted file mode 100644 index 66b1742..0000000 --- a/MRMobileRun/MRRunning/ZYLUpdateData.m +++ /dev/null @@ -1,30 +0,0 @@ -// -// ZYLUpdateData.m -// MRMobileRun -// -// Created by 丁磊 on 2019/5/3. -// - -#import "ZYLUpdateData.h" -#import "AESCipher.h" - -@implementation ZYLUpdateData -+ (NSString *)ZYLGetUpdateDataDictionaryWithBegintime:(NSNumber *)begin Endtime:(NSNumber *)end distance:(NSNumber *)distance lat_lng:(NSArray *)lat_lng andSteps:(NSNumber *)steps{ - NSUserDefaults *user = [[NSUserDefaults alloc] init]; - NSString *student = [user objectForKey:@"studentID"]; - NSDictionary *dic = @{@"begin_time": begin, - @"distance": distance, - @"end_time": end, - @"lat_lng": lat_lng, - @"steps": steps, - @"student_id": student - }; - NSError *parseError = nil; - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&parseError]; - NSString *str = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; - NSString *encryptedText = aesEncryptString(str, kDECRYPTKEY); - - return encryptedText; -} - -@end diff --git a/MRMobileRun/MRRunning/style.data b/MRMobileRun/MRRunning/style.data new file mode 100644 index 0000000..e673dc9 Binary files /dev/null and b/MRMobileRun/MRRunning/style.data differ diff --git a/MRMobileRun/MRRunning/style2.data b/MRMobileRun/MRRunning/style2.data new file mode 100644 index 0000000..6f197a2 Binary files /dev/null and b/MRMobileRun/MRRunning/style2.data differ diff --git a/MRMobileRun/MRRunning/style_extra.data b/MRMobileRun/MRRunning/style_extra.data new file mode 100644 index 0000000..110c927 Binary files /dev/null and b/MRMobileRun/MRRunning/style_extra.data differ diff --git a/MRMobileRun/MRRunning/style_extra2.data b/MRMobileRun/MRRunning/style_extra2.data new file mode 100644 index 0000000..3cec264 Binary files /dev/null and b/MRMobileRun/MRRunning/style_extra2.data differ diff --git "a/MRMobileRun/MRRunning/\346\232\202\345\201\234\347\231\275.svg" "b/MRMobileRun/MRRunning/\346\232\202\345\201\234\347\231\275.svg" new file mode 100644 index 0000000..7dd3aa8 --- /dev/null +++ "b/MRMobileRun/MRRunning/\346\232\202\345\201\234\347\231\275.svg" @@ -0,0 +1,12 @@ + + + + 跑步页/暂停/白 + Created with Sketch. + + + + + + + \ No newline at end of file diff --git "a/MRMobileRun/MRRunning/\346\232\202\345\201\234\351\273\221.svg" "b/MRMobileRun/MRRunning/\346\232\202\345\201\234\351\273\221.svg" new file mode 100644 index 0000000..0d49aa1 --- /dev/null +++ "b/MRMobileRun/MRRunning/\346\232\202\345\201\234\351\273\221.svg" @@ -0,0 +1,12 @@ + + + + 跑步页/暂停/黑 + Created with Sketch. + + + + + + + \ No newline at end of file diff --git "a/MRMobileRun/MRRunning/\347\273\223\346\235\237\347\231\275.svg" "b/MRMobileRun/MRRunning/\347\273\223\346\235\237\347\231\275.svg" new file mode 100644 index 0000000..1595bbc --- /dev/null +++ "b/MRMobileRun/MRRunning/\347\273\223\346\235\237\347\231\275.svg" @@ -0,0 +1,11 @@ + + + + 跑步页/结束/白 + Created with Sketch. + + + + + + \ No newline at end of file diff --git "a/MRMobileRun/MRRunning/\347\273\247\347\273\255\347\231\275.svg" "b/MRMobileRun/MRRunning/\347\273\247\347\273\255\347\231\275.svg" new file mode 100644 index 0000000..be6b6b7 --- /dev/null +++ "b/MRMobileRun/MRRunning/\347\273\247\347\273\255\347\231\275.svg" @@ -0,0 +1,11 @@ + + + + 跑步页/继续/白 + Created with Sketch. + + + + + + \ No newline at end of file diff --git "a/MRMobileRun/MRRunning/\351\224\201\345\256\232\347\201\260.svg" "b/MRMobileRun/MRRunning/\351\224\201\345\256\232\347\201\260.svg" new file mode 100644 index 0000000..8037c72 --- /dev/null +++ "b/MRMobileRun/MRRunning/\351\224\201\345\256\232\347\201\260.svg" @@ -0,0 +1,11 @@ + + + + 跑步页/锁定/小/灰 + Created with Sketch. + + + + + + \ No newline at end of file diff --git "a/MRMobileRun/MRRunning/\351\224\201\345\256\232\347\231\275.svg" "b/MRMobileRun/MRRunning/\351\224\201\345\256\232\347\231\275.svg" new file mode 100644 index 0000000..4e9d502 --- /dev/null +++ "b/MRMobileRun/MRRunning/\351\224\201\345\256\232\347\231\275.svg" @@ -0,0 +1,11 @@ + + + + 跑步页/锁定/小/白 + Created with Sketch. + + + + + + \ No newline at end of file diff --git "a/MRMobileRun/MRRunning/\351\224\201\345\256\232\351\273\221.svg" "b/MRMobileRun/MRRunning/\351\224\201\345\256\232\351\273\221.svg" new file mode 100644 index 0000000..2a506e7 --- /dev/null +++ "b/MRMobileRun/MRRunning/\351\224\201\345\256\232\351\273\221.svg" @@ -0,0 +1,11 @@ + + + + 跑步页/锁定小/黑 + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/MRMobileRun/MRSettinglView/AboutViewController.h b/MRMobileRun/MRSettinglView/AboutViewController.h new file mode 100644 index 0000000..aa15058 --- /dev/null +++ b/MRMobileRun/MRSettinglView/AboutViewController.h @@ -0,0 +1,16 @@ +// +// AboutViewController.h +// MRMobileRun +// +// Created by 杨远舟 on 2020/8/11. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface AboutViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRSettinglView/AboutViewController.m b/MRMobileRun/MRSettinglView/AboutViewController.m new file mode 100644 index 0000000..d5df9dd --- /dev/null +++ b/MRMobileRun/MRSettinglView/AboutViewController.m @@ -0,0 +1,197 @@ +// +// AboutViewController.m +// MRMobileRun +// +// Created by 杨远舟 on 2020/8/6. +// + +#import "AboutViewController.h" +#import "Masonry.h" +@interface AboutViewController () + +@end + +@implementation AboutViewController + +-(void)viewWillDisappear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; + +} +-(void)viewDidDisappear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; +} +-(void)viewDidAppear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; + id target = self.navigationController.interactivePopGestureRecognizer.delegate; + //handleNavigationTransition:为系统私有API,即系统自带侧滑手势的回调方法,在自己的手势上直接用它的回调方法 + UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)]; + panGesture.delegate = self; //设置手势代理,拦截手势触发 + [self.view addGestureRecognizer:panGesture]; + self.navigationController.interactivePopGestureRecognizer.enabled = NO; //禁止系统自带的滑动手势 +} + +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer +{ + if (self.navigationController.viewControllers.count <= 1) { + return NO; + } + return YES; +} + +- (void)handleNavigationTransition:(id)sender +{ + +} +-(void)viewWillAppear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; + self.navigationController.interactivePopGestureRecognizer.enabled = YES; //禁止系统自带的滑动手势 +} +- (void)viewDidLoad { + [super viewDidLoad]; + [self.navigationItem setTitle:@"关于约跑"]; + [self.navigationController setNavigationBarHidden:NO animated:NO]; + + self.navigationController.navigationBar.tintColor = [UIColor blackColor]; + UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + [backBtn setImage:[UIImage imageNamed:@"返回箭头4"] forState:UIControlStateNormal]; + [backBtn setImageEdgeInsets:UIEdgeInsetsMake(10, 5, 10, 5)]; + [backBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; + UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:backBtn]; + self.navigationItem.leftBarButtonItem = backItem; + + UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(125, 170, 130, 130)]; + imageView.image = [UIImage imageNamed:@"约跑"]; + imageView.layer.shadowColor = [UIColor blackColor].CGColor; + imageView.layer.shadowOffset= CGSizeMake(0,0);//偏移距离 + imageView.layer.shadowOpacity=0.03;//不透明度 + imageView.layer.shadowRadius=10.0;//半径 + [self.view addSubview:imageView]; + [imageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.view); + make.top.equalTo(self.view).offset(170*kRateY); + make.width.equalTo(@(130*kRateY)); + make.height.equalTo(@(130*kRateY)); + }]; + + UILabel *lable2 = [[UILabel alloc]initWithFrame:CGRectMake(145, 305,100, 50)]; + lable2.text = @"重邮约跑"; + lable2.textAlignment = NSTextAlignmentCenter; + [lable2 setFont:[UIFont fontWithName:@"Helvetica-Bold"size:23]]; + [self.view addSubview:lable2]; + [lable2 mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.view); + make.top.equalTo(self.view).offset(305*kRateY); + make.width.equalTo(@(100*kRateX)); + make.height.equalTo(@(50*kRateY)); + }]; + + UILabel *lable3 = [[UILabel alloc]initWithFrame:CGRectMake(147, 330, 100, 50)]; + lable3.text = @"Version 2.0.1"; + lable3.textAlignment = NSTextAlignmentCenter; + lable3.textColor = [UIColor lightGrayColor]; + lable3.font = [UIFont systemFontOfSize:15]; + [self.view addSubview:lable3]; + [lable3 mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.view); + make.top.equalTo(self.view).offset(330*kRateY); + make.width.equalTo(@(100*kRateX)); + make.height.equalTo(@(50*kRateY)); + }]; + + UILabel *lable4 = [[UILabel alloc]initWithFrame:CGRectMake(70, 655, 280, 50)]; + lable4.text = @"CopyRight@2013-2020 All Reserved"; + lable4.textAlignment = NSTextAlignmentCenter; + lable4.textColor = [UIColor lightGrayColor]; + lable4.font = [UIFont systemFontOfSize:15]; + [self.view addSubview:lable4]; + [lable4 mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.view); + make.top.equalTo(self.view).offset(665*kRateY); + make.width.equalTo(@(280*kRateX)); + make.height.equalTo(@(50*kRateY)); + }]; + + UIButton *btn1 = [[UIButton alloc]initWithFrame:CGRectMake(110, 630, 80, 30)]; + btn1.backgroundColor = [UIColor clearColor]; + [btn1 setTitle:@"检查更新" forState:UIControlStateNormal]; + [btn1 setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; + [btn1 addTarget:self action:@selector(actionAlert1) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:btn1]; + [btn1 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(110*kRateX); + make.top.equalTo(self.view).offset(630*kRateY); + make.width.equalTo(@(80*kRateX)); + make.height.equalTo(@(30*kRateY)); + }]; + + UIButton *btn2 = [[UIButton alloc]initWithFrame:CGRectMake(185, 630, 90, 30)]; + btn2.backgroundColor = [UIColor clearColor]; + [btn2 setTitle:@"| 使用条款" forState:UIControlStateNormal]; + [btn2 setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; + [btn2 addTarget:self action:@selector(actionAlert2) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:btn2]; + [btn2 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(185*kRateX); + make.top.equalTo(self.view).offset(630*kRateY); + make.width.equalTo(@(90*kRateX)); + make.height.equalTo(@(30*kRateY)); + }]; + + [self changeStyle]; + } + + - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection + { + [super traitCollectionDidChange:previousTraitCollection]; + [self changeStyle]; + } + + - (void)changeStyle { + if (@available(iOS 13.0, *)) { + if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) { + self.view.backgroundColor = [UIColor whiteColor]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:UIColor.blackColor forKey:NSForegroundColorAttributeName]; + self.navigationController.navigationBar.titleTextAttributes = dict; + self.navigationController.navigationBar.tintColor = [UIColor blackColor]; + } else { //深色模式 + + UIColor *color = [UIColor whiteColor]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:color forKey:NSForegroundColorAttributeName]; + self.navigationController.navigationBar.titleTextAttributes = dict; + self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; + + self.view.backgroundColor = [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } + } +- (void) back { + self.tabBarController.tabBar.hidden = NO; + [self.navigationController popViewControllerAnimated:YES]; +} + +- (void)actionAlert1{ + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"已是最新版本,无需更新"message:@""preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]; + [alertController addAction:cancelAction]; + [alertController addAction:okAction]; + [self presentViewController:alertController animated:YES completion:nil]; +} +- (void)actionAlert2{ + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"使用条款"message:@"版权归红岩网校所有,感谢您的使用"preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]; + + [alertController addAction:okAction]; + [self presentViewController:alertController animated:YES completion:nil]; +} +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/MRMobileRun/MRSettinglView/SportSettingViewController.h b/MRMobileRun/MRSettinglView/SportSettingViewController.h new file mode 100644 index 0000000..c58d89a --- /dev/null +++ b/MRMobileRun/MRSettinglView/SportSettingViewController.h @@ -0,0 +1,16 @@ +// +// SportSettingViewController.h +// MRMobileRun +// +// Created by 杨远舟 on 2020/8/11. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SportSettingViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRSettinglView/SportSettingViewController.m b/MRMobileRun/MRSettinglView/SportSettingViewController.m new file mode 100644 index 0000000..0533006 --- /dev/null +++ b/MRMobileRun/MRSettinglView/SportSettingViewController.m @@ -0,0 +1,173 @@ +// +// SportSettingViewController.m +// MRMobileRun +// +// Created by 杨远舟 on 2020/8/6. +// + +#import "SportSettingViewController.h" +#import "Masonry.h" +@interface SportSettingViewController () +@property(nonatomic, weak) UIButton *saveBtn; + +@end + +@implementation SportSettingViewController +-(void)viewWillDisappear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; + +} +-(void)viewDidDisappear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; +} +-(void)viewDidAppear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; + id target = self.navigationController.interactivePopGestureRecognizer.delegate; + //handleNavigationTransition:为系统私有API,即系统自带侧滑手势的回调方法,在自己的手势上直接用它的回调方法 + UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)]; + panGesture.delegate = self; //设置手势代理,拦截手势触发 + [self.view addGestureRecognizer:panGesture]; + self.navigationController.interactivePopGestureRecognizer.enabled = NO; //禁止系统自带的滑动手势 +} + +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer +{ + if (self.navigationController.viewControllers.count <= 1) { + return NO; + } + return YES; +} + +- (void)handleNavigationTransition:(id)sender +{ + +} +-(void)viewWillAppear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; + self.navigationController.interactivePopGestureRecognizer.enabled = YES; //禁止系统自带的滑动手势 +} +- (void)viewDidLoad { + [super viewDidLoad]; + [self.navigationItem setTitle:@"系统权限设置"]; + [self.navigationController setNavigationBarHidden:NO animated:NO]; + + self.navigationController.navigationBar.tintColor = [UIColor blackColor]; + UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + [backBtn setImage:[UIImage imageNamed:@"返回箭头4"] forState:UIControlStateNormal]; + [backBtn setImageEdgeInsets:UIEdgeInsetsMake(10, 5, 10, 5)]; + [backBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; + UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:backBtn]; + self.navigationItem.leftBarButtonItem = backItem; + + UIButton *saveBtn = [[UIButton alloc]initWithFrame:CGRectMake(15, 300, 345, 50)]; + saveBtn.backgroundColor = [UIColor darkGrayColor]; + [saveBtn setTitle:@"快速设置" forState:UIControlStateNormal]; + [saveBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [saveBtn addTarget:self action:@selector(actionSet) forControlEvents:UIControlEventTouchUpInside]; + [saveBtn.layer setMasksToBounds:YES]; + [saveBtn.layer setCornerRadius:10.0]; + [self.view addSubview:saveBtn]; + [saveBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.view); + make.top.equalTo(self.view).offset(300*kRateY); + make.width.equalTo(@(345*kRateX)); + make.height.equalTo(@(50*kRateY)); + }]; + + UILabel *lable1 = [[UILabel alloc]initWithFrame:CGRectMake(25, 80, 330, 100)]; + lable1.text = @"由于系统的省电规则与后台限制,会误将约跑正在记录运动的进程杀掉。为了避免运动数据统计不准确请打开以下权限。"; + lable1.numberOfLines = 5; + [self.view addSubview:lable1]; + [lable1 mas_makeConstraints:^(MASConstraintMaker *make) { + //make.centerX.equalTo(self.view); + make.left.equalTo(self.view).offset(25*kRateY); + make.right.equalTo(self.view).offset(-25*kRateY); + make.top.equalTo(self.view).offset(80*kRateY); + //make.width.equalTo(@(330*kRateY)); + make.height.equalTo(@(100*kRateY)); + }]; + + UILabel *lable2 = [[UILabel alloc]initWithFrame:CGRectMake(25, 150, 330, 100)]; + lable2.text = @"白名单/自启动设置方法。"; + [lable2 setFont:[UIFont fontWithName:@"Helvetica-Bold"size:18]]; + [self.view addSubview:lable2]; + [lable2 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(25*kRateY); + make.right.equalTo(self.view).offset(-25*kRateY); + make.top.equalTo(self.view).offset(163*kRateY); + make.height.equalTo(@(100*kRateY)); + }]; + + UILabel *lable3 = [[UILabel alloc]initWithFrame:CGRectMake(25, 190, 330, 100)]; + lable3.text = @"设置->重邮约跑->允许约跑后台刷新"; + lable3.numberOfLines = 1; + [self.view addSubview:lable3]; + [lable3 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(25*kRateY); + make.right.equalTo(self.view).offset(-25*kRateY); + make.top.equalTo(self.view).offset(190*kRateY); + make.height.equalTo(@(100*kRateY)); + }]; + [self changeStyle]; +} + +-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection +{ + [super traitCollectionDidChange:previousTraitCollection]; + [self changeStyle]; +} + +- (void)changeStyle { + if (@available(iOS 13.0, *)) { + if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) { + self.view.backgroundColor = [UIColor whiteColor]; + // self.tf.textColor = [UIColor blackColor]; + + // self.tf.backgroundColor = [UIColor colorWithRed:248/255.0 green:248/255.0 blue:248/255.0 alpha:1]; + self.saveBtn.backgroundColor = [UIColor darkGrayColor]; + [self.saveBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:UIColor.blackColor forKey:NSForegroundColorAttributeName]; + self.navigationController.navigationBar.titleTextAttributes = dict; + self.navigationController.navigationBar.tintColor = [UIColor blackColor]; + } else { //深色模式 + // self.tf.textColor = [UIColor whiteColor]; + + // self.tf.backgroundColor = [UIColor colorWithRed:75/255.0 green:76/255.0 blue:82/255.0 alpha:1]; + self.saveBtn.backgroundColor = [UIColor colorWithRed:222/255.0 green:223/255.0 blue:229/255.0 alpha:1]; + [self.saveBtn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; + UIColor *color = [UIColor whiteColor]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:color forKey:NSForegroundColorAttributeName]; + self.navigationController.navigationBar.titleTextAttributes = dict; + self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; + + self.view.backgroundColor = [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 +} + +- (void)back { + self.tabBarController.tabBar.hidden = NO; + [self.navigationController popViewControllerAnimated:YES]; +} +- (void)actionSet{ + if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) { + NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; + [[UIApplication sharedApplication]openURL:url options:@{} completionHandler:^(BOOL success) { + }]; + }else{ + //[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]] 应用标识 + NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"prefs:root=%@",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]]]; + [[UIApplication sharedApplication]openURL:url]; + } +} +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/MRMobileRun/MRSettinglView/SportSettingViewController.xib b/MRMobileRun/MRSettinglView/SportSettingViewController.xib new file mode 100644 index 0000000..239a54b --- /dev/null +++ b/MRMobileRun/MRSettinglView/SportSettingViewController.xib @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/MRMobileRun/MRSettinglView/YYZCommentViewController.h b/MRMobileRun/MRSettinglView/YYZCommentViewController.h new file mode 100644 index 0000000..88aa0d3 --- /dev/null +++ b/MRMobileRun/MRSettinglView/YYZCommentViewController.h @@ -0,0 +1,16 @@ +// +// YYZCommentViewController.h +// MRMobileRun +// +// Created by 杨远舟 on 2020/8/11. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface YYZCommentViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRSettinglView/YYZCommentViewController.m b/MRMobileRun/MRSettinglView/YYZCommentViewController.m new file mode 100644 index 0000000..ec97c52 --- /dev/null +++ b/MRMobileRun/MRSettinglView/YYZCommentViewController.m @@ -0,0 +1,129 @@ +// +// YYZCommentViewController.m +// MRMobileRun +// +// Created by 杨远舟 on 2020/8/6. +// +#import "Masonry.h" +#import "YYZCommentViewController.h" +#import "ZYLPersonalViewController.h" +@interface YYZCommentViewController () + +@end + +@implementation YYZCommentViewController +-(void)viewWillDisappear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; + +} +-(void)viewDidDisappear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; +} +-(void)viewDidAppear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; +} +-(void)viewWillAppear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; +} +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + + [self.navigationItem setTitle:@"意见反馈"]; + [self.navigationController setNavigationBarHidden:NO animated:NO]; + + + self.navigationController.navigationBar.tintColor = [UIColor blackColor]; + UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + [backBtn setImage:[UIImage imageNamed:@"返回箭头4"] forState:UIControlStateNormal]; + [backBtn setImageEdgeInsets:UIEdgeInsetsMake(10, 5, 10, 5)]; + [backBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; + UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:backBtn]; + self.navigationItem.leftBarButtonItem = backItem; + + UIButton *saveBtn = [[UIButton alloc]initWithFrame:CGRectMake(13, 630, 350, 50)]; + saveBtn.backgroundColor = [UIColor darkGrayColor]; + [saveBtn setTitle:@"提交反馈" forState:UIControlStateNormal]; + [saveBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [saveBtn addTarget:self action:@selector(actionBack) forControlEvents:UIControlEventTouchUpInside]; + [saveBtn.layer setMasksToBounds:YES]; + [saveBtn.layer setCornerRadius:10.0]; + [self.view addSubview:saveBtn]; + [saveBtn mas_makeConstraints:^(MASConstraintMaker *make) { + //make.centerX.equalTo(self.view); + make.left.equalTo(self.view).offset(18*kRateY); + make.right.equalTo(self.view).offset(-18*kRateY); + make.bottom.equalTo(self.view).offset(-160*kRateY); + make.height.greaterThanOrEqualTo(@(50*kRateY)); + }]; + + UITextField *tf = [[UITextField alloc]initWithFrame:CGRectMake(18, 110, 342, 100)]; + tf.borderStyle = UITextBorderStyleNone; + tf.placeholder = @"请在此处写下你反馈的意见"; + //[tf setValue:[UIFont boldSystemFontOfSize:10] forKeyPath:@"_placeholderLabel.font"]; + tf.layer.cornerRadius = 13; + tf.layer.masksToBounds = YES; + tf.contentVerticalAlignment = UIControlContentVerticalAlignmentTop; + tf.backgroundColor = [UIColor colorWithRed:248/255.0 green:248/255.0 blue:248/255.0 alpha:1]; + UIView *paddingLeftView = [[UIView alloc] init]; + CGRect frame = tf.frame; + frame.size.width = 12; + paddingLeftView.frame = frame; + tf.leftViewMode = UITextFieldViewModeAlways; + tf.leftView = paddingLeftView; + [self.view addSubview:tf]; + [tf mas_makeConstraints:^(MASConstraintMaker *make) { + //make.centerX.equalTo(self.view); + make.left.equalTo(self.view).offset(18*kRateY); + make.right.equalTo(self.view).offset(-18*kRateY); + make.top.equalTo(self.view).offset(100*kRateY); + make.height.greaterThanOrEqualTo(@(100*kRateY)); + }]; + + if (@available(iOS 13.0, *)) { + UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return [UIColor whiteColor]; + } else { //深色模式 + tf.textColor = [UIColor whiteColor]; + tf.backgroundColor = [UIColor colorWithRed:75/255.0 green:76/255.0 blue:82/255.0 alpha:1]; + saveBtn.backgroundColor = [UIColor colorWithRed:222/255.0 green:223/255.0 blue:229/255.0 alpha:1]; + [saveBtn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; + UIColor *color = [UIColor whiteColor]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:color forKey:UITextAttributeTextColor]; + self.navigationController.navigationBar.titleTextAttributes = dict; + self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; + + return [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } + }]; + self.view.backgroundColor = rightColor; //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } +} +- (void) back { + self.tabBarController.tabBar.hidden = NO; + [self.navigationController popViewControllerAnimated:YES]; +} +- (void)actionBack{ + + ZYLPersonalViewController *vc1 = [[ZYLPersonalViewController alloc]init]; + + [self.navigationController popViewControllerAnimated:YES]; + + + + // Do any additional setup after loading the view. + +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/MRMobileRun/MRSettinglView/YYZTextView.xib b/MRMobileRun/MRSettinglView/YYZTextView.xib new file mode 100644 index 0000000..8b759e7 --- /dev/null +++ b/MRMobileRun/MRSettinglView/YYZTextView.xib @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/MRMobileRun/MRSettinglView/YYZTextViewController.h b/MRMobileRun/MRSettinglView/YYZTextViewController.h new file mode 100644 index 0000000..77c9b0d --- /dev/null +++ b/MRMobileRun/MRSettinglView/YYZTextViewController.h @@ -0,0 +1,18 @@ +// +// YYZTextViewController.h +// MRMobileRun +// +// Created by 杨远舟 on 2020/8/11. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface YYZTextViewController : UIViewController + +@property (nonatomic, assign) BOOL changeNickname; //是否是修改昵称 + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRSettinglView/YYZTextViewController.m b/MRMobileRun/MRSettinglView/YYZTextViewController.m new file mode 100644 index 0000000..37631a7 --- /dev/null +++ b/MRMobileRun/MRSettinglView/YYZTextViewController.m @@ -0,0 +1,250 @@ +#import "YYZTextViewController.h" +#import "ZYLPersonalViewController.h" +#import "Masonry.h" +#import +#import +#import +#import "ZYLChangeNickname.h" + +@interface YYZTextViewController () + +@property(nonatomic, weak)UITextView *tf; +@property(nonatomic, weak) UIButton *saveBtn; +@property(nonatomic, weak)UILabel *placeHolder; +@end + +@implementation YYZTextViewController +-(void)viewWillDisappear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; + +} +-(void)viewDidDisappear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; +} +-(void)viewDidAppear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; + //设置右滑返回的手势 + id target = self.navigationController.interactivePopGestureRecognizer.delegate; + //handleNavigationTransition:为系统私有API,即系统自带侧滑手势的回调方法,在自己的手势上直接用它的回调方法 + UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)]; + panGesture.delegate = self; //设置手势代理,拦截手势触发 + [self.view addGestureRecognizer:panGesture]; + self.navigationController.interactivePopGestureRecognizer.enabled = NO; //禁止系统自带的滑动手势 +} + +- (void)handleNavigationTransition:(id)sender +{ + +} +-(void)viewWillAppear:(BOOL)animated{ + [self.navigationController setNavigationBarHidden:NO animated:NO]; + +} +- (void)viewDidLoad { + [super viewDidLoad]; + + [self.navigationController setNavigationBarHidden:NO animated:NO]; + + self.navigationController.navigationBar.tintColor = [UIColor blackColor]; + UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + [backBtn setImage:[UIImage imageNamed:@"返回箭头4"] forState:UIControlStateNormal]; + [backBtn setImageEdgeInsets:UIEdgeInsetsMake(10, 5, 10, 5)]; + [backBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; + UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithCustomView:backBtn]; + self.navigationItem.leftBarButtonItem = backItem; + + UIButton *saveBtn = [[UIButton alloc]initWithFrame:CGRectMake(13, 630, 350, 50)]; + //UIButton *saveBtn = [[UIButton alloc]init]; + saveBtn.backgroundColor = [UIColor darkGrayColor]; + + [saveBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [saveBtn addTarget:self action:@selector(actionBack) forControlEvents:UIControlEventTouchUpInside]; + [saveBtn.layer setMasksToBounds:YES]; + [saveBtn.layer setCornerRadius:10.0]; + [self.view addSubview:saveBtn]; + [saveBtn mas_makeConstraints:^(MASConstraintMaker *make) { + //make.centerX.equalTo(self.view); + make.left.equalTo(self.view).offset(18*kRateY); + make.right.equalTo(self.view).offset(-18*kRateY); + make.bottom.equalTo(self.view).offset(-160*kRateY); + make.height.greaterThanOrEqualTo(@(50*kRateY)); + }]; + self.saveBtn = saveBtn; +//输入框 + + unsigned int count = 0; + Ivar *ivars = class_copyIvarList([UITextView class], &count); + + for (int i = 0; i < count; i++) { + Ivar ivar = ivars[i]; + const char *name = ivar_getName(ivar); + NSString *objcName = [NSString stringWithUTF8String:name]; + NSLog(@"%d : %@",i,objcName); + } + UITextView *tf = [[UITextView alloc]initWithFrame:CGRectMake(18, 110, 342, 100)]; + tf.layer.cornerRadius = 13;//设置边框圆角 + tf.layer.masksToBounds = YES; + tf.textContainerInset = UIEdgeInsetsMake(15, 10, 10, 10);//设置边界间距 + + if (self.changeNickname) { + [self.navigationItem setTitle:@"修改昵称"]; + [saveBtn setTitle:@"保存昵称" forState:UIControlStateNormal]; + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *signature = [user objectForKey:@"nickname"]; + tf.text=signature; + } else { + [self.navigationItem setTitle:@"个性签名"]; + [saveBtn setTitle:@"保存签名" forState:UIControlStateNormal]; + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *signature = [user objectForKey:@"signature"]; + tf.text=signature; + } + tf.backgroundColor = [UIColor colorWithRed:248/255.0 green:248/255.0 blue:248/255.0 alpha:1]; + [self.view addSubview:tf]; + self.tf=tf; + + UIToolbar * topView = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 30)]; + [topView setBarStyle:UIBarStyleDefault]; + UIBarButtonItem * btnSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil]; + UIBarButtonItem * doneButton = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:self action:@selector(dismissKeyBoard)]; + NSArray * buttonsArray = [NSArray arrayWithObjects:btnSpace, doneButton, nil]; + + [topView setItems:buttonsArray]; + [tf setInputAccessoryView:topView]; + + UILabel *placeHolderLabel = [[UILabel alloc] init]; + if (self.changeNickname) { + placeHolderLabel.text = @"请在此处写下你的昵称"; + } else { + placeHolderLabel.text = @"请在此处写下你的个性签名"; + } + placeHolderLabel.numberOfLines = 0; + placeHolderLabel.textColor = [UIColor lightGrayColor]; + [placeHolderLabel sizeToFit]; + [tf addSubview:placeHolderLabel]; + // same font + tf.font = [UIFont systemFontOfSize:16.f]; + placeHolderLabel.font = [UIFont systemFontOfSize:16.f]; + [tf setValue:placeHolderLabel forKey:@"_placeholderLabel"]; + + [tf mas_makeConstraints:^(MASConstraintMaker *make) { + //make.centerX.equalTo(self.view); + make.left.equalTo(self.view).offset(18*kRateY); + make.right.equalTo(self.view).offset(-18*kRateY); + make.top.equalTo(self.mas_topLayoutGuideBottom).offset(20*kRateY); + make.height.greaterThanOrEqualTo(@(100*kRateY)); + }]; + [self changeStyle]; +} + +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection +{ + [super traitCollectionDidChange:previousTraitCollection]; + [self changeStyle]; +} + +- (void)changeStyle { + if (@available(iOS 13.0, *)) { + if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) { + self.view.backgroundColor = [UIColor whiteColor]; + self.tf.textColor = [UIColor blackColor]; + + self.tf.backgroundColor = [UIColor colorWithRed:248/255.0 green:248/255.0 blue:248/255.0 alpha:1]; + self.saveBtn.backgroundColor = [UIColor darkGrayColor]; + [self.saveBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:UIColor.blackColor forKey:NSForegroundColorAttributeName]; + self.navigationController.navigationBar.titleTextAttributes = dict; + self.navigationController.navigationBar.tintColor = [UIColor blackColor]; + } else { //深色模式 + self.tf.textColor = [UIColor whiteColor]; + + self.tf.backgroundColor = [UIColor colorWithRed:75/255.0 green:76/255.0 blue:82/255.0 alpha:1]; + self.saveBtn.backgroundColor = [UIColor colorWithRed:222/255.0 green:223/255.0 blue:229/255.0 alpha:1]; + [self.saveBtn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; + UIColor *color = [UIColor whiteColor]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:color forKey:NSForegroundColorAttributeName]; + self.navigationController.navigationBar.titleTextAttributes = dict; + self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; + + self.view.backgroundColor = [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } +} + +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer +{ + if (self.navigationController.viewControllers.count <= 1) { + return NO; + } + return YES; +} + + +- (void) back { + self.tabBarController.tabBar.hidden = NO; + [self.navigationController popViewControllerAnimated:YES]; +} +- (void)actionBack{ + + if (self.changeNickname) { + [self changeNicknameReq]; + } else { + [self saveSignature]; + } + + // Do any additional setup after loading the view. + +} + +- (void)changeNicknameReq +{ + [ZYLChangeNickname uploadChangedNickname:self.tf.text]; +} + +- (void)saveSignature +{ + NSUserDefaults *user2 = [NSUserDefaults standardUserDefaults]; + NSString *token = [user2 objectForKey:@"token"]; + AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; + [manager.requestSerializer setValue: token forHTTPHeaderField: @"token"]; + [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + NSDictionary *param = @{@"token": token , @"signature": self.tf.text}; + //NSDictionary *param = @{@"token": token, @"nickname": nickname}; + + + [manager POST:@"https://cyxbsmobile.redrock.team/wxapi/mobile-run/modify/signature" parameters: param constructingBodyWithBlock:nil success:^(NSURLSessionDataTask *task, id responseObject) { + NSLog(@"success"); + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + [user setObject:self.tf.text forKey:@"signature"]; + [user synchronize]; + [self.navigationController popViewControllerAnimated:YES]; + + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSLog(@"=====%@", error); // 404 500 + //MBProgressHUD 服务器异常 请稍后重试 + }]; +} + +-(void) dismissKeyBoard{ + [self.tf resignFirstResponder]; +} + +/* + +\#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation + +\- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + + // Get the new view controller using [segue destinationViewController]. + + // Pass the selected object to the new view controller. + +} + +*/ + + + +@end diff --git a/MRMobileRun/MRSettinglView/YYZTextViewController.xib b/MRMobileRun/MRSettinglView/YYZTextViewController.xib new file mode 100644 index 0000000..b61dc62 --- /dev/null +++ b/MRMobileRun/MRSettinglView/YYZTextViewController.xib @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/MRMobileRun/MRSettinglView/ZYLChangeNickname.m b/MRMobileRun/MRSettinglView/ZYLChangeNickname.m index 5fe9c33..d1fafff 100644 --- a/MRMobileRun/MRSettinglView/ZYLChangeNickname.m +++ b/MRMobileRun/MRSettinglView/ZYLChangeNickname.m @@ -20,18 +20,23 @@ @implementation ZYLChangeNickname + (void)uploadChangedNickname:(NSString *)nickname{ NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; NSString *token = [user objectForKey:@"token"]; - NSString *student_id = [user objectForKey:@"studentID"]; +// NSString *student_id = [user objectForKey:@"studentID"]; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; [manager.requestSerializer setValue: token forHTTPHeaderField: @"token"]; [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; - NSDictionary *dic = @{@"nickname": nickname}; - __block NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil]; - NSDictionary *param = @{@"student_id": student_id, @"data": data}; +// NSDictionary *dic = @{@"nickname": nickname}; +// __block NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil]; +// NSDictionary *param = @{@"student_id": student_id, @"data": data}; + NSDictionary *param = @{@"token": token, @"nickname": nickname}; - [manager POST:kNicknameUrl parameters: param constructingBodyWithBlock:^(id formData) { + [manager POST:kNicknameUrl parameters:param constructingBodyWithBlock:^(id formData) { ; } success:^(NSURLSessionDataTask *task, id responseObject) { NSLog(@"%@",responseObject[@"message"]); + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + [user setObject:nickname forKey:@"nickname"]; + [user synchronize]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"getNicknameSuccess" object:nil]; } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"%@",error); }]; diff --git a/MRMobileRun/MRSettinglView/ZYLPersonalViewController.m b/MRMobileRun/MRSettinglView/ZYLPersonalViewController.m index ba62469..fd90b35 100644 --- a/MRMobileRun/MRSettinglView/ZYLPersonalViewController.m +++ b/MRMobileRun/MRSettinglView/ZYLPersonalViewController.m @@ -15,6 +15,10 @@ #import "MRTabBarController.h" #import #import +#import "YYZCommentViewController.h" +#import "YYZTextViewController.h" +#import "AboutViewController.h" +#import "SportSettingViewController.h" @interface ZYLPersonalViewController () //@property (strong, nonatomic) ZYLPersonalInformationView *personalInformationView; @@ -28,6 +32,7 @@ @interface ZYLPersonalViewController () @implementation ZYLPersonalViewController - (void)viewWillAppear:(BOOL)animated{ + [super viewDidAppear:animated]; self.view.backgroundColor = [UIColor clearColor]; [self.navigationController setNavigationBarHidden: NO]; // 设置透明导航栏 @@ -35,36 +40,131 @@ - (void)viewWillAppear:(BOOL)animated{ self.navigationController.navigationBar.shadowImage = [UIImage new]; self.navigationController.navigationBar.translucent = YES; self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor blackColor]}; // title颜色 - self.title = @"设置"; + + //self.title = @"设置"; + if (@available(iOS 13.0, *)) { + UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return [UIColor whiteColor]; + } else { //深色模式 + self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor whiteColor]}; + return [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } + }]; + self.view.backgroundColor = rightColor; //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } + [self->_bkgView YYZdarkChange]; + + + +} +-(void)viewWillDisappear:(BOOL)animated{ + [self->_bkgView YYZdarkChange]; + + } +-(void)viewDidDisappear:(BOOL)animated{ + [self->_bkgView YYZdarkChange]; +} +-(void)viewDidAppear:(BOOL)animated{ + [self->_bkgView YYZdarkChange]; +} - (void)viewDidLoad { [super viewDidLoad]; + // [self setOverrideUserInterfaceStyle:UIUserInterfaceStyleDark]; self.userDefaults = [NSUserDefaults standardUserDefaults]; // [self.view addSubview: self.personalInformationView]; [ZYLAvatarRequest ZYLGetAvatar]; [self.view addSubview: self.bkgView]; + [_bkgView YYZdarkChange]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getAvatar:) name:@"getAvatar" object:nil]; // NSData *imageData = [[NSData alloc] init]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myAvatar:) name:@"getAvatarSuccess" object: nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myAvatar:) name:@"getAvatarSuccess" object: nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myNickname:) name:@"getNicknameSuccess" object: nil]; + + + UIButton *textBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + textBtn.frame = CGRectMake(0, 210*kRateY, screenWidth, 70*kRateY); + textBtn.backgroundColor = [UIColor clearColor]; + [textBtn addTarget:self action:@selector(actionText) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:textBtn]; + + UIButton *aboutBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + aboutBtn.frame = CGRectMake(0, 280*kRateY, screenWidth, 70*kRateY); + aboutBtn.backgroundColor = [UIColor clearColor]; + [aboutBtn addTarget:self action:@selector(actionAbout) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:aboutBtn]; + + UIButton *settingBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + settingBtn.frame = CGRectMake(0, 350*kRateY, screenWidth, 70*kRateY); + settingBtn.backgroundColor = [UIColor clearColor]; + [settingBtn addTarget:self action:@selector(actionSetting) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:settingBtn]; + UIButton *commentBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + commentBtn.frame = CGRectMake(0, 420*kRateY, screenWidth, 70*kRateY); + commentBtn.backgroundColor = [UIColor clearColor]; + [commentBtn addTarget:self action:@selector(actionComment) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:commentBtn]; + + if (@available(iOS 13.0, *)) { + UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return [UIColor whiteColor]; + } else { //深色模式 + self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor whiteColor]}; + + return [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } + }]; + [self->_bkgView YYZdarkChange]; + self.view.backgroundColor = rightColor; //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } + + } +- (void)handleNavigationTransition:(id)sender +{ + +} + + +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection +{ + [super traitCollectionDidChange:previousTraitCollection]; + [self->_bkgView YYZdarkChange]; +} + +- (void)actionText{ + YYZTextViewController *vc1 =[[YYZTextViewController alloc]init]; + [self.navigationController pushViewController:vc1 animated:YES]; +} +- (void)actionAbout{ + AboutViewController *vc1 =[[AboutViewController alloc]init]; + [self.navigationController pushViewController:vc1 animated:YES]; +} +- (void)actionSetting{ + SportSettingViewController *vc1 =[[SportSettingViewController alloc]init]; + [self.navigationController pushViewController:vc1 animated:YES]; +} + +- (void)actionComment{ + //YYZCommentViewController *vc1 =[[YYZCommentViewController alloc]init]; + //[self.navigationController pushViewController:vc1 animated:YES]; + NSString *qq_number = @"983292781"; + NSString* urlStr = [NSString stringWithFormat:@"mqqapi://card/show_pslcard?src_type=internal&version=1&uin=%@&key=%@&card_type=group&source=external", qq_number, @"44a6e01f2dab126f87ecd2ec7b7e66ae259b30535fd0c2c25776271e8c0ac08f"]; + NSURL* url = [NSURL URLWithString:urlStr]; + if ([[UIApplication sharedApplication] canOpenURL:url]) { + [[UIApplication sharedApplication] openURL:url]; + } +} + + + - (void)clickLogoutBtu{ - [[NSNotificationCenter defaultCenter] postNotificationName:@"hideTabBar" object:nil]; -// NSDictionary *dic = [self.userDefaults dictionaryRepresentation]; -// for (id key in dic) -// { -// if ([key isEqual:@"studentID"] || [key isEqual:@"password"] || [key isEqual:@"nickname"] || [key isEqual:@"class_id"] || [key isEqual:@"token"]) -// { -// NSLog(@"非空%@ is %@",key,[self.userDefaults objectForKey:key]); -// [self.userDefaults removeObjectForKey:key]; -// } -// else -// { -// NSLog(@"空%@ is %@",key,[self.userDefaults objectForKey:key]); -// } -// } -// [self.userDefaults synchronize]; + [self clearAllUserDefaultsData]; [MGJRouter openURL:kLoginVCPageURL withUserInfo:@{@"navigationVC" : self.navigationController, } @@ -84,48 +184,62 @@ - (void)clickAvatarBtu{ self.imageView.image = [UIImage imageWithData: [defaults objectForKey:@"myAvatar"]]; ZYLPhotoSelectedVIew *selectView = [ZYLPhotoSelectedVIew selectViewWithDestinationImageView: self.imageView delegate:self]; selectView.iconImage = self.imageView.image; - [self.view addSubview:selectView]; + + [UIApplication.sharedApplication.keyWindow addSubview:selectView]; } -- (void)getAvatar:(NSNotification*)notification{ - NSLog(@"\n\n\n\n获取成功\n\n\n\n"); - NSData *imageData = UIImageJPEGRepresentation(self.imageView.image, 1); -// // 将图片存储在本地 - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults setObject:imageData forKey: @"myAvatar"]; - [defaults synchronize]; - [self.bkgView.iconCell.iconButton setImage:[UIImage imageWithData:imageData] forState:UIControlStateNormal]; +- (void)clearAllUserDefaultsData { + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + NSDictionary *dic = [userDefaults dictionaryRepresentation]; + for (id key in dic) { + [userDefaults removeObjectForKey:key]; + } + [userDefaults synchronize]; +} +- (void)myNickname:(NSNotification *)notification +{ + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + self.bkgView.nicknameCell.nicknameTextFiled.text = [user objectForKey:@"nickname"]; + self.nicknameDic = [[NSMutableDictionary alloc]init]; + [self.nicknameDic setObject:self.bkgView.nicknameCell.nicknameTextFiled.text forKey:@"nickname"]; + [self.navigationController popViewControllerAnimated:YES]; +} +- (void)getAvatar:(NSNotification*)notification{ + NSLog(@"\n\n\n\n获取成功\n\n\n\n"); +// NSData *imageData = UIImageJPEGRepresentation(self.imageView.image, 1); +//// // 将图片存储在本地 +// [self.bkgView.iconCell.iconButton setImage:[UIImage imageWithData:imageData] forState:UIControlStateNormal]; [ZYLUploadAvatar UpdateAvatarWithImage:self.imageView.image]; } -- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ - - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"修改昵称" message:@"请在下方文本框内输入新的昵称" preferredStyle:UIAlertControllerStyleAlert]; - [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField){ - }]; - - UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; - [cancelAction setValue:[UIColor blackColor] forKey:@"titleTextColor"]; - - UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { - UITextField *nickName = alertController.textFields.firstObject; - if (![nickName.text isEqualToString:@""]) { - NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; - [user setObject:nickName.text forKey:@"nickname"]; - self.bkgView.nicknameCell.nicknameTextFiled.text = nickName.text; - self.nicknameDic = [[NSMutableDictionary alloc]init]; - [self.nicknameDic setObject:self.bkgView.nicknameCell.nicknameTextFiled.text forKey:@"nickname"]; - [ZYLChangeNickname uploadChangedNickname:nickName.text]; - } - }]; +- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ - [okAction setValue:[UIColor blackColor] forKey:@"titleTextColor"]; - [alertController addAction:cancelAction]; - [alertController addAction:okAction]; - [self presentViewController:alertController animated:YES completion:nil]; + YYZTextViewController *vc1 =[[YYZTextViewController alloc]init]; + vc1.changeNickname = YES; + [self.navigationController pushViewController:vc1 animated:YES]; +// UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"修改昵称" message:@"请在下方文本框内输入新的昵称" preferredStyle:UIAlertControllerStyleAlert]; +// [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField){ +// +// }]; +// +// UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; +// [cancelAction setValue:[UIColor blackColor] forKey:@"titleTextColor"]; +// +// UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { +// UITextField *nickName = alertController.textFields.firstObject; +// if (![nickName.text isEqualToString:@""]) { +// +// [ZYLChangeNickname uploadChangedNickname:nickName.text]; +// } +// }]; +// +// [okAction setValue:[UIColor blackColor] forKey:@"titleTextColor"]; +// [alertController addAction:cancelAction]; +// [alertController addAction:okAction]; +// [self presentViewController:alertController animated:YES completion:nil]; return NO; } @@ -138,6 +252,7 @@ - (ZYLSettingBackgound *)bkgView{ [_bkgView.iconCell.iconButton addTarget: self action:@selector(clickAvatarBtu) forControlEvents:UIControlEventTouchUpInside]; [_bkgView.logoutBtn addTarget:self action:@selector(clickLogoutBtu) forControlEvents:UIControlEventTouchUpInside]; _bkgView.nicknameCell.nicknameTextFiled.text = [_userDefaults objectForKey:@"nickname"]; + [_bkgView.iconCell.iconButton setImage:[UIImage imageWithData: [_userDefaults objectForKey:@"myAvatar"]] forState:UIControlStateNormal]; _bkgView.nicknameCell.nicknameTextFiled.delegate = self; _bkgView.nicknameCell.nicknameTextFiled.returnKeyType = UIReturnKeyDone; } diff --git a/MRMobileRun/MRSettinglView/ZYLPhotoSelectedVIew.h b/MRMobileRun/MRSettinglView/ZYLPhotoSelectedVIew.h index b74e798..f6bf6ea 100644 --- a/MRMobileRun/MRSettinglView/ZYLPhotoSelectedVIew.h +++ b/MRMobileRun/MRSettinglView/ZYLPhotoSelectedVIew.h @@ -10,7 +10,7 @@ NS_ASSUME_NONNULL_BEGIN @interface ZYLPhotoSelectedVIew : UIView -@property (nonatomic, weak) UIImage *iconImage; +@property (nonatomic, strong) UIImage *iconImage; + (instancetype)selectViewWithDestinationImageView:(UIImageView *)imageView delegate:(UIViewController *)delegate; diff --git a/MRMobileRun/MRSettinglView/ZYLPhotoSelectedVIew.m b/MRMobileRun/MRSettinglView/ZYLPhotoSelectedVIew.m index f1b2705..ef44778 100644 --- a/MRMobileRun/MRSettinglView/ZYLPhotoSelectedVIew.m +++ b/MRMobileRun/MRSettinglView/ZYLPhotoSelectedVIew.m @@ -16,15 +16,15 @@ static const NSInteger normalColor = 0x64686F; @interface ZYLPhotoSelectedVIew () -@property UIImageView *selectWindowImageView; -@property UIImageView *horizonalLine; -@property UIButton *selectButton; -@property UIButton *takePhotoButton; -@property UIView *effectView; -@property UIButton *cancelButton; -@property CGFloat rateX; -@property CGFloat rateY; -@property UIImageView *destinationImageView; +@property (nonatomic, strong) UIView *selectWindowImageView; +@property (nonatomic, strong) UIImageView *horizonalLine; +@property (nonatomic, strong)UIButton *selectButton; +@property (nonatomic, strong) UIButton *takePhotoButton; +@property (nonatomic, strong)UIView *effectView; +@property (nonatomic, strong) UIButton *cancelButton; +@property (nonatomic, assign) CGFloat rateX; +@property (nonatomic, assign) CGFloat rateY; +@property (nonatomic, strong) UIImageView *destinationImageView; @property (nonatomic, weak) UIViewController *delegate; @property (nonatomic, strong) UIImageView *iconImageView; @end @@ -68,12 +68,19 @@ - (void)initEffectView { } - (void)initAlertView { - UIImage *i1 = [UIImage imageNamed:@"换头像弹窗"]; - self.selectWindowImageView = [[UIImageView alloc] initWithImage:i1]; + +// UIImage *i1 = [UIImage imageNamed:@"换头像弹窗"]; + self.selectWindowImageView = [[UIView alloc] init]; self.selectWindowImageView.userInteractionEnabled = YES; + self.selectWindowImageView.layer.cornerRadius = 12; + self.selectWindowImageView.layer.masksToBounds = YES; + self.selectWindowImageView.backgroundColor = [UIColor whiteColor]; [self addSubview:self.selectWindowImageView]; + - self.iconImageView = [[UIImageView alloc] initWithImage: self.iconImage]; + self.iconImageView = [[UIImageView alloc] initWithImage: self.destinationImageView.image]; + self.iconImageView.contentMode = UIViewContentModeScaleAspectFill; + [self.selectWindowImageView addSubview: self.iconImageView]; self.selectButton = [[UIButton alloc] init]; @@ -94,7 +101,7 @@ - (void)initAlertView { self.takePhotoButton.layer.masksToBounds = YES; self.takePhotoButton.tag = 1; [self.takePhotoButton addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside]; - [self.selectWindowImageView addSubview:self.takePhotoButton]; +// [self.selectWindowImageView addSubview:self.takePhotoButton]; self.cancelButton = [[UIButton alloc] init]; [self.cancelButton setTitle:@"取消" forState:UIControlStateNormal]; @@ -109,6 +116,31 @@ - (void)initAlertView { UIImage *i2 = [UIImage imageNamed:@"horizonal_line"]; self.horizonalLine = [[UIImageView alloc] initWithImage:i2]; [self.selectWindowImageView addSubview:self.horizonalLine]; + + [self changeStyle]; + +} + +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection +{ + [super traitCollectionDidChange:previousTraitCollection]; + [self changeStyle]; +} + +- (void)changeStyle { + if (@available(iOS 13.0, *)) { + if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleLight || UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleUnspecified) { + self.selectWindowImageView.backgroundColor = [UIColor whiteColor]; + self.selectButton.backgroundColor = UIColorFromRGB(normalColor); + [self.selectButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [self.cancelButton setBackgroundColor:UIColorFromRGB(alertColor)]; + } else { + self.selectWindowImageView.backgroundColor = UIColorFromRGB(0x4a4d52); + self.selectButton.backgroundColor = UIColorFromRGB(0xdce0e6); + [self.selectButton setTitleColor:UIColorFromRGB(0x333739) forState:UIControlStateNormal]; + self.cancelButton.backgroundColor = UIColorFromRGB(0x55d5e2); + } + } } - (void)click:(id)button { @@ -134,9 +166,9 @@ - (void)click:(id)button { } } else if (theButton.tag == 2) { //取消 + } self.hidden = YES; - } - (void)takePhoto:(UIImagePickerControllerSourceType)type { @@ -163,38 +195,38 @@ - (void)imagePickerController:(UIImagePickerController *)picker didFinishPicking - (void)updateConstraints { [self.selectWindowImageView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.mas_top).with.offset(216*self.rateY); //with is an optional semantic filler + make.centerY.equalTo(self).offset(-33*self.rateY); //with is an optional semantic filler make.centerX.equalTo(self.mas_centerX); make.width.equalTo(@(306*self.rateX)); - make.height.equalTo(@(250.5*self.rateY)); + make.height.equalTo(@(309*self.rateX)); }]; [self.iconImageView mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.selectWindowImageView.mas_top).mas_offset(10*self.rateY); + make.top.equalTo(self.selectWindowImageView.mas_top).mas_offset(30*self.rateX); make.centerX.equalTo(self.selectWindowImageView.mas_centerX); - make.width.equalTo(self.selectWindowImageView.mas_width).mas_offset(-100); - make.height.equalTo(self.selectWindowImageView.mas_width).mas_offset(-100); + make.width.equalTo(self.selectWindowImageView.mas_width).mas_offset(-126); + make.height.equalTo(self.iconImageView.mas_width); }]; - self.iconImageView.layer.cornerRadius = self.iconImageView.width/2; - self.iconImageView.layer.masksToBounds = YES; + self.iconImageView.layer.cornerRadius = self.destinationImageView.image.size.width / 2.0; + self.iconImageView.clipsToBounds = YES; [self.selectButton mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.iconImageView.mas_bottom).mas_offset(10*self.rateY); //with is an optional semantic filler - make.centerX.equalTo(self.selectWindowImageView.mas_centerX); - make.width.mas_equalTo(86*self.rateX); - make.height.equalTo(@(44*self.rateY)); - }]; - [self.takePhotoButton mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.iconImageView.mas_bottom).mas_offset(10*self.rateY); //with is an optional semantic filler - make.left.equalTo(self.selectWindowImageView.mas_left).mas_offset(15); - make.width.mas_equalTo(86*self.rateX); - make.height.equalTo(@(44*self.rateY)); + make.top.equalTo(self.iconImageView.mas_bottom).mas_offset(30*self.rateX); //with is an optional semantic filler + make.centerX.equalTo(self.selectWindowImageView.mas_centerX).multipliedBy(0.5).offset(5*self.rateX); + make.width.mas_equalTo(130*self.rateX); + make.height.equalTo(@(44*self.rateX)); }]; +// [self.takePhotoButton mas_makeConstraints:^(MASConstraintMaker *make) { +// make.top.equalTo(self.iconImageView.mas_bottom).mas_offset(30*self.rateY); //with is an optional semantic filler +// make.left.equalTo(self.selectWindowImageView.mas_left).mas_offset(15); +// make.width.mas_equalTo(86*self.rateX); +// make.height.equalTo(@(44*self.rateY)); +// }]; [self.cancelButton mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.iconImageView.mas_bottom).mas_offset(10*self.rateY); //with is an optional semantic filler - make.right.equalTo(self.selectWindowImageView.mas_right).mas_offset(-15); - make.width.mas_equalTo(86*self.rateX); - make.height.equalTo(@(44*self.rateY)); + make.top.equalTo(self.iconImageView.mas_bottom).mas_offset(30*self.rateX); //with is an optional semantic filler + make.centerX.equalTo(self.selectWindowImageView.mas_centerX).multipliedBy(1.5).offset(-5*self.rateX); + make.width.mas_equalTo(130*self.rateX); + make.height.equalTo(@(44*self.rateX)); }]; // [self.horizonalLine mas_makeConstraints:^(MASConstraintMaker *make) { // make.top.equalTo(self.selectWindowImageView.mas_top).with.offset(54.5*2*self.rateY); //with is an optional semantic filler @@ -212,9 +244,15 @@ + (instancetype)selectViewWithDestinationImageView:(UIImageView *)imageView dele - (void)clickEffectView { self.hidden = YES; - } +- (void)layoutSubviews +{ + [super layoutSubviews]; + self.iconImageView.layer.cornerRadius = CGRectGetWidth(self.selectWindowImageView.frame) / 2.0 - 63; +} + + + (BOOL)requiresConstraintBasedLayout { return YES; } diff --git a/MRMobileRun/MRSettinglView/ZYLSettingBackgound.h b/MRMobileRun/MRSettinglView/ZYLSettingBackgound.h index c1e1728..fabea35 100644 --- a/MRMobileRun/MRSettinglView/ZYLSettingBackgound.h +++ b/MRMobileRun/MRSettinglView/ZYLSettingBackgound.h @@ -23,6 +23,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, strong) ZYLSettingNomalCell *suggestionCell; @property (nonatomic, strong) UIButton *logoutBtn; //@property (nonatomic, strong) ZYLNicknameTextField *nicknameTextFiled; +-(void) YYZdarkChange; @end - NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRSettinglView/ZYLSettingBackgound.m b/MRMobileRun/MRSettinglView/ZYLSettingBackgound.m index 11a022d..e15c026 100644 --- a/MRMobileRun/MRSettinglView/ZYLSettingBackgound.m +++ b/MRMobileRun/MRSettinglView/ZYLSettingBackgound.m @@ -49,7 +49,7 @@ - (void)initCells{ self.aboutCell = [[ZYLSettingNomalCell alloc] init]; self.aboutCell.frame = CGRectMake(0, 210*kRateY, screenWidth, 70*kRateY); - self.aboutCell.textLab.text = @"关于跑酷"; + self.aboutCell.textLab.text = @"关于约跑"; self.aboutCell.iconImage.image = [UIImage imageNamed:@"setting_about"]; [self addSubview: self.aboutCell]; @@ -67,8 +67,33 @@ - (void)initCells{ self.switchCell = [[ZYLSettingDarkModeCell alloc] init]; self.switchCell.frame = CGRectMake(0, 420*kRateY, screenWidth, 70*kRateY); - [self addSubview: self.switchCell]; - + // [self addSubview: self.switchCell]; + + + if (@available(iOS 13.0, *)) { + if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) { + } + else { //深色模式 + self.iconCell.textLab.textColor = [UIColor whiteColor]; + self.nicknameCell.textLab.textColor = [UIColor whiteColor]; + self.signCell.textLab.textColor = [UIColor whiteColor]; + self.aboutCell.textLab.textColor = [UIColor whiteColor]; + self.suggestionCell.textLab.textColor = [UIColor whiteColor]; + self.permissionCell.textLab.textColor = [UIColor whiteColor]; + self.switchCell.textLab.textColor = [UIColor whiteColor]; + + self.signCell.iconImage.image = [UIImage imageNamed:@"setting_sign_dark"]; + self.aboutCell.iconImage.image = [UIImage imageNamed:@"setting_about_dark"]; + self.permissionCell.iconImage.image = [UIImage imageNamed: @"setting_authority_dark"]; + self.suggestionCell.iconImage.image = [UIImage imageNamed:@"setting_suggestion_dark"]; + self.iconCell.iconImage.image = [UIImage imageNamed:@"setting_icon_dark"]; + self.nicknameCell.iconImage.image = [UIImage imageNamed:@"setting_nickname_dark"]; + self.switchCell.iconImage.image = [UIImage imageNamed:@"setting_darkMode_dark"]; + + } + } else { + // Fallback on earlier versions + } } - (void)initLogoutButton{ @@ -81,6 +106,46 @@ - (void)initLogoutButton{ [self addSubview: self.logoutBtn]; } +-(void)YYZdarkChange{ + if (@available(iOS 13.0, *)){ + + if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) { + self.iconCell.textLab.textColor = [UIColor blackColor]; + self.nicknameCell.textLab.textColor = [UIColor blackColor]; + self.signCell.textLab.textColor = [UIColor blackColor]; + self.aboutCell.textLab.textColor = [UIColor blackColor]; + self.suggestionCell.textLab.textColor = [UIColor blackColor]; + self.permissionCell.textLab.textColor = [UIColor blackColor]; + //self.switchCell.textLab.textColor = [UIColor blackColor]; + + self.signCell.iconImage.image = [UIImage imageNamed:@"setting_sign"]; + self.aboutCell.iconImage.image = [UIImage imageNamed:@"setting_about"]; + self.permissionCell.iconImage.image = [UIImage imageNamed: @"setting_authority"]; + self.suggestionCell.iconImage.image = [UIImage imageNamed:@"setting_suggestion"]; + self.iconCell.iconImage.image = [UIImage imageNamed:@"setting_icon"]; + self.nicknameCell.iconImage.image = [UIImage imageNamed:@"setting_nickname"]; + //self.switchCell.iconImage.image = [UIImage imageNamed:@"setting_darkMode"]; + } + else { //深色模式 + self.iconCell.textLab.textColor = [UIColor whiteColor]; + self.nicknameCell.textLab.textColor = [UIColor whiteColor]; + self.signCell.textLab.textColor = [UIColor whiteColor]; + self.aboutCell.textLab.textColor = [UIColor whiteColor]; + self.suggestionCell.textLab.textColor = [UIColor whiteColor]; + self.permissionCell.textLab.textColor = [UIColor whiteColor]; + //self.switchCell.textLab.textColor = [UIColor whiteColor]; + + self.signCell.iconImage.image = [UIImage imageNamed:@"setting_sign_dark"]; + self.aboutCell.iconImage.image = [UIImage imageNamed:@"setting_about_dark"]; + self.permissionCell.iconImage.image = [UIImage imageNamed: @"setting_authority_dark"]; + self.suggestionCell.iconImage.image = [UIImage imageNamed:@"setting_suggestion_dark"]; + self.iconCell.iconImage.image = [UIImage imageNamed:@"setting_icon_dark"]; + self.nicknameCell.iconImage.image = [UIImage imageNamed:@"setting_nickname_dark"]; + // self.switchCell.iconImage.image = [UIImage imageNamed:@"setting_darkMode_dark"]; + } + } +} + diff --git a/MRMobileRun/MRSettinglView/ZYLSettingDarkModeCell.m b/MRMobileRun/MRSettinglView/ZYLSettingDarkModeCell.m index a9272c7..dd61c6d 100644 --- a/MRMobileRun/MRSettinglView/ZYLSettingDarkModeCell.m +++ b/MRMobileRun/MRSettinglView/ZYLSettingDarkModeCell.m @@ -17,6 +17,7 @@ - (instancetype)init self.iconImage.image = [UIImage imageNamed:@"setting_darkMode"]; self.arrowImage.hidden = YES; self.mySwitch = [[UISwitch alloc] initWithFrame: CGRectMake(screenWidth-70*kRateX, 17*kRateY, 52*kRateX, 30*kRateY)]; + [self.mySwitch addTarget:self action:@selector(DarkChange:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview: self.mySwitch]; // [self.mySwitch mas_makeConstraints:^(MASConstraintMaker *make) { // make.centerX.equalTo(self.mas_centerX); @@ -28,4 +29,12 @@ - (instancetype)init return self; } +- (void)DarkChange:(UISwitch *)sender{ + if(sender.on == YES){ + printf("adsad\nfsdfds"); + [self setOverrideUserInterfaceStyle:UIUserInterfaceStyleDark]; + } + else + [self setOverrideUserInterfaceStyle:UIUserInterfaceStyleLight]; +} @end diff --git a/MRMobileRun/MRSettinglView/ZYLSettingNomalCell.m b/MRMobileRun/MRSettinglView/ZYLSettingNomalCell.m index 057330e..fc7f4c9 100644 --- a/MRMobileRun/MRSettinglView/ZYLSettingNomalCell.m +++ b/MRMobileRun/MRSettinglView/ZYLSettingNomalCell.m @@ -48,6 +48,22 @@ - (void)initTextLabel{ make.height.mas_equalTo(25*kRateY); make.width.mas_equalTo(140*kRateX); }]; + +// if (@available(iOS 13.0, *)) { +// UIColor *color = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trait) { +// +// if (trait.userInterfaceStyle == UIUserInterfaceStyleDark) { +// return UIColor.whiteColor; +// } else { +// return COLOR_WITH_HEX(0x333739); +// } +// +// }]; +// self.textLab.textColor = color; +// } else { +// self.textLab.textColor = COLOR_WITH_HEX(0x333739); +// } + } - (void)initArrowImage{ diff --git a/MRMobileRun/MRSettinglView/ZYLUploadAvatar.m b/MRMobileRun/MRSettinglView/ZYLUploadAvatar.m index 44ab09e..b690b6b 100644 --- a/MRMobileRun/MRSettinglView/ZYLUploadAvatar.m +++ b/MRMobileRun/MRSettinglView/ZYLUploadAvatar.m @@ -25,11 +25,16 @@ + (void)UpdateAvatarWithImage:(UIImage *)image{ __block NSString *student_id = [user objectForKey:@"studentID"]; __block NSData *avatar = UIImageJPEGRepresentation(image, 1); - [manager POST: kUploadAvatarUrl parameters:nil constructingBodyWithBlock:^(id formData) { + [manager POST: kUploadAvatarUrl parameters:@{@"token": token} constructingBodyWithBlock:^(id formData) { [formData appendPartWithFormData:[student_id dataUsingEncoding: NSUTF8StringEncoding] name:@"student_id"]; - [formData appendPartWithFileData: avatar name: @"file" fileName: [NSString stringWithFormat:@"%@,jpg",student_id] mimeType: @"image/jpg"]; + [formData appendPartWithFileData: avatar name: @"avatar" fileName: [NSString stringWithFormat:@"%@,jpg",student_id] mimeType: @"image/jpg"]; } success:^(NSURLSessionDataTask *task, id responseObject) { NSLog(@"%@",responseObject[@"message"]); + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:avatar forKey: @"myAvatar"]; + [defaults synchronize]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"getAvatarSuccess" object:nil]; + } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"%@",error); }]; diff --git a/MRMobileRun/MRTabBar/MGDTabBar.h b/MRMobileRun/MRTabBar/MGDTabBar.h new file mode 100644 index 0000000..ece3e9a --- /dev/null +++ b/MRMobileRun/MRTabBar/MGDTabBar.h @@ -0,0 +1,16 @@ +// +// MGDTabBar.h +// MRMobileRun +// +// Created by 阿栋 on 2020/8/21. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDTabBar : UITabBar +@property (nonatomic,strong)UIButton *centerBtn; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRTabBar/MGDTabBar.m b/MRMobileRun/MRTabBar/MGDTabBar.m new file mode 100644 index 0000000..2738227 --- /dev/null +++ b/MRMobileRun/MRTabBar/MGDTabBar.m @@ -0,0 +1,73 @@ +// +// MGDTabBar.m +// MRMobileRun +// +// Created by 阿栋 on 2020/8/21. +// + +#import "MGDTabBar.h" + +@implementation MGDTabBar +- (instancetype)init +{ + self = [super init]; + if (self) { + if (@available(iOS 11.0, *)) { + self.backgroundColor = MGDColor3; + } else { + // Fallback on earlier versions + } + [self setUI]; + } + return self; +} +#pragma 设置UI布局 +- (void)setUI{ + self.centerBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + + //设置button大小为图片尺寸 + UIImage *normalImage = [UIImage imageNamed:@"begin"]; + if (@available(iOS 11.0, *)) { + [self.centerBtn setBackgroundColor:RunBackColor]; + } else { + // Fallback on earlier versions + } + self.centerBtn.layer.cornerRadius = 32; + [self.centerBtn setImage:normalImage forState:UIControlStateNormal]; + self.centerBtn.adjustsImageWhenHighlighted = NO; + //设置图片位置居中显示 + if (kIs_iPhoneX) { + self.centerBtn.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width - 64)/2, -32 + 19, 64, 64); + }else { + self.centerBtn.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width - 64)/2, -32 + 13, 64, 64); + } + + [self addSubview:self.centerBtn]; +} +//解决超出superView点击无效问题 +- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{ + UIView *view = [super hitTest:point withEvent:event]; + if (!view){ + //转换坐标 + CGPoint tempPoint = [self.centerBtn convertPoint:point fromView:self]; + //判断点击的点是否在按钮区域内 + if (CGRectContainsPoint(self.centerBtn.bounds, tempPoint)){ + //返回按钮 + return self.centerBtn; + } + } + return view; +} + +-(CGSize)sizeThatFits:(CGSize)size{ + CGSize sizeThatFits = [super sizeThatFits:size]; + if (kIs_iPhoneX) { + sizeThatFits.height = 83; + }else { + sizeThatFits.height = 49; + } + return sizeThatFits; +} + +@end + diff --git a/MRMobileRun/MRTabBar/MGDTabBarViewController.h b/MRMobileRun/MRTabBar/MGDTabBarViewController.h new file mode 100644 index 0000000..af64da3 --- /dev/null +++ b/MRMobileRun/MRTabBar/MGDTabBarViewController.h @@ -0,0 +1,19 @@ +// +// MGDTabBarViewController.h +// MRMobileRun +// +// Created by 阿栋 on 2020/8/21. +// + +#import +#import "ZYLMainViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDTabBarViewController : UITabBarController + + + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRTabBar/MGDTabBarViewController.m b/MRMobileRun/MRTabBar/MGDTabBarViewController.m new file mode 100644 index 0000000..f63fbd9 --- /dev/null +++ b/MRMobileRun/MRTabBar/MGDTabBarViewController.m @@ -0,0 +1,112 @@ +// +// MGDTabBarViewController.m +// MRMobileRun +// +// Created by 阿栋 on 2020/8/21. +// + +#import "MGDTabBarViewController.h" +#import "MGDTabBar.h" +#import "ZYLMainViewController.h" +#import "ZYLPersonalViewController.h" +#import "ZYLRunningViewController.h" +#import "ZYLRankViewController.h" +#import "LJJInviteRunVC.h" +#import "MGDMineViewController.h" +#import "ZYLMainViewController.h" + +@interface MGDTabBarViewController () +@property (strong, nonatomic) NSMutableArray *btnArr; +@property (strong, nonatomic) NSMutableArray *textArr; +@property (strong, nonatomic) ZYLMainViewController *vc1; +@property (strong, nonatomic) ZYLRankViewController *vc2; +@property (strong, nonatomic) ZYLRunningViewController *vc3; +@property (strong, nonatomic) ZYLPersonalViewController *vc4; +@property (strong, nonatomic) MGDMineViewController *vc5; +@property (strong, nonatomic) MGDTabBar *tabBar; + + +@end + +@implementation MGDTabBarViewController + +@dynamic tabBar; + +-(void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + [self.navigationController setNavigationBarHidden:YES]; + self.delegate = self; + self.tabBar = [[MGDTabBar alloc] init]; + [self.tabBar.centerBtn addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside]; + //设置背景颜色透明 + self.tabBar.translucent = YES; + //利用KVC,将自定义tabBar,赋给系统tabBar + [self setValue:self.tabBar forKeyPath:@"tabBar"]; + [self addChildViewControllers]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; +} + +//添加子控制器 +- (void)addChildViewControllers{ + self.vc1 = [[ZYLMainViewController alloc] init]; + self.vc1.tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0,-6, 0); + self.vc1.tabBarItem.image = [[UIImage imageNamed:@"mainView_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + self.vc1.tabBarItem.selectedImage = [[UIImage imageNamed:@"mainView_highlighted"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + + self.vc2 = [[ZYLRankViewController alloc] init]; + self.vc2.tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0,-6, 0); + self.vc2.tabBarItem.image = [[UIImage imageNamed:@"rank_nomal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + self.vc2.tabBarItem.selectedImage = [[UIImage imageNamed:@"rank_highlighted"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + + self.vc3 = [[ZYLRunningViewController alloc] init]; + + self.vc4 = [[ZYLPersonalViewController alloc] init]; + self.vc4.tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0,-6, 0); + self.vc4.tabBarItem.image = [[UIImage imageNamed:@"setting_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + self.vc4.tabBarItem.selectedImage = [[UIImage imageNamed:@"setting_highlighted"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + + self.vc5 = [[MGDMineViewController alloc] init]; + self.vc5.tabBarItem.imageInsets = UIEdgeInsetsMake(6, 0,-6, 0); + self.vc5.tabBarItem.image = [[UIImage imageNamed:@"MyView_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + self.vc5.tabBarItem.selectedImage = [[UIImage imageNamed:@"MyView_highlighted"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + + NSArray *itemArrays = @[self.vc1,self.vc2,self.vc3,self.vc4,self.vc5]; + self.viewControllers = itemArrays; +} +- (void)buttonAction{ + //关联中间按钮 + self.selectedIndex = 2; + +} +//tabbar选择时的代理 +- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{ + + [self.tabBar.centerBtn.layer removeAllAnimations]; +} + +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection { + [super traitCollectionDidChange:previousTraitCollection]; + if (@available(iOS 13.0, *)) { + if ([self.traitCollection hasDifferentColorAppearanceComparedToTraitCollection:previousTraitCollection]) { + // 执行操作 + NSLog(@"改变了模式"); + self.vc1.tabBarItem.image = [[UIImage imageNamed:@"mainView_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + self.vc1.tabBarItem.selectedImage = [[UIImage imageNamed:@"mainView_highlighted"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + self.vc2.tabBarItem.image = [[UIImage imageNamed:@"rank_nomal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + self.vc2.tabBarItem.selectedImage = [[UIImage imageNamed:@"rank_highlighted"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + self.vc4.tabBarItem.image = [[UIImage imageNamed:@"setting_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + self.vc4.tabBarItem.selectedImage = [[UIImage imageNamed:@"setting_highlighted"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + self.vc5.tabBarItem.image = [[UIImage imageNamed:@"MyView_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + self.vc5.tabBarItem.selectedImage = [[UIImage imageNamed:@"MyView_highlighted"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; + } + } else { + // Fallback on earlier versions + NSLog(@"未改变模式"); + } + +} + +@end diff --git a/MRMobileRun/MRTabBar/MRTabBarController.h b/MRMobileRun/MRTabBar/MRTabBarController.h index f4d498a..c97c64c 100644 --- a/MRMobileRun/MRTabBar/MRTabBarController.h +++ b/MRMobileRun/MRTabBar/MRTabBarController.h @@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN @interface MRTabBarController : UITabBarController @property (strong, nonatomic) MRTabBarView *tabView; //@property (assign, nonatomic) id delegate; - +- (void)showTabView; @end NS_ASSUME_NONNULL_END diff --git a/MRMobileRun/MRTabBar/MRTabBarController.m b/MRMobileRun/MRTabBar/MRTabBarController.m index 2e9042e..fa7f4d3 100644 --- a/MRMobileRun/MRTabBar/MRTabBarController.m +++ b/MRMobileRun/MRTabBar/MRTabBarController.m @@ -21,6 +21,7 @@ #import "ZYLRunningViewController.h" #import "ZYLRankViewController.h" #import "LJJInviteRunVC.h" +#import "MGDMineViewController.h" #import #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width @interface MRTabBarController () @@ -31,6 +32,13 @@ @interface MRTabBarController () @implementation MRTabBarController -(void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:animated]; + //移除系统自带的tabBar + for (UIView *child in self.tabBar.subviews) { + if ([child isKindOfClass:[UIControl class]]) { + [child removeFromSuperview]; + } + } [self.navigationController setNavigationBarHidden:YES]; } @@ -80,7 +88,7 @@ - (void)addAllChildViewController{ ZYLPersonalViewController *vc4 = [[ZYLPersonalViewController alloc] init]; [self addChildViewController:vc4 title:@"设置" imageNamed:@"setting_normal" selectedImageNamed:@"setting_highlighted" tag:4]; - UIViewController *vc5 = [[UIViewController alloc] init]; + MGDMineViewController *vc5 = [[MGDMineViewController alloc] init]; [self addChildViewController:vc5 title:@"我的" imageNamed:@"MyView_normal" selectedImageNamed:@"MyView_highlighted" tag:5]; } @@ -107,6 +115,13 @@ - (void)showTabView{ self.tabView.hidden = NO; } +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +//- (void)setHidesBottomBarWhenPushed:(BOOL)hidesBottomBarWhenPushed{ +// self.tabView.hidden = hidesBottomBarWhenPushed; +//} #pragma mark - TabBarViewDelegate - (void)tabBarView:(MRTabBarView *_Nullable)view didSelectedItemAtIndex:(NSInteger) index { diff --git a/MRMobileRun/MVVMDemoModule/.DS_Store b/MRMobileRun/MVVMDemoModule/.DS_Store deleted file mode 100644 index 0680b9e..0000000 Binary files a/MRMobileRun/MVVMDemoModule/.DS_Store and /dev/null differ diff --git a/MRMobileRun/PrefixHeader 2.pch b/MRMobileRun/PrefixHeader 2.pch new file mode 100644 index 0000000..d798a34 --- /dev/null +++ b/MRMobileRun/PrefixHeader 2.pch @@ -0,0 +1,157 @@ +// +// PrefixHeader.pch +// MRMobileRun +// +// Created by 丁磊 on 2019/3/23. +// + +#ifndef PrefixHeader_pch +#define PrefixHeader_pch +#define kStatusBarHeigh [[UIApplication sharedApplication] statusBarFrame].size.height //导航栏高度 +#define screenHeigth [UIScreen mainScreen].bounds.size.height +#define screenWidth [UIScreen mainScreen].bounds.size.width +#define kRateX [UIScreen mainScreen].bounds.size.width/375 //以iPhoneX为基准 +#define kRateY [UIScreen mainScreen].bounds.size.height/812 //以iPhoneX为基准 +#define kIs_iphone (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) +#define kIs_iPhoneX screenWidth >=375.0f && screenHeigth >=812.0f&& kIs_iphone +#define kHeadHeight kIs_iPhoneX? 44:20 +/*TabBar高度*/ +#define kTabBarHeight (CGFloat)(kIs_iPhoneX?(49.0 + 34.0):(49.0)) + +/** +黑暗模式背景颜色 + */ +/* + 跑步页的深色模式颜色 + */ +#define k_DarkBkgColor [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1.0] +//关于黑暗模式的颜色 + //白色模式是白色 + #define WhiteColor [UIColor colorNamed:@"whiteColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //白天是灰色 +#define GrayColor [UIColor colorNamed:@"grayColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + +//结束页面的底部view背景色 +#define bottomColor [UIColor colorNamed:@"BottomColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //结束页面的字体颜色 +#define bottomTitleColor [UIColor colorNamed:@"bottomTitleColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //结束页面的公里的字的颜色 +#define kmColor [UIColor colorNamed:@"BottomUnitColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //结束页面的结束按钮字体颜色 +#define OverColor [UIColor colorNamed:@"OverBtnColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //结束页面的结束按钮背景色 +#define OverBackColor [UIColor colorNamed:@"OverBtnBackColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + +//配速、时间、燃烧卡路里 显示数字的字体颜色 +#define SpeedTextColor [UIColor colorNamed:@"SpeedNumberLblTextColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //显示公里数字的字体颜色 +#define MilesColor [UIColor colorNamed:@"milesColor" inBundle:[NSBundle mainBundle]compatibleWithTraitCollection:nil] + //显示@“公里”的字体颜色 +#define MilesTxetColor [UIColor colorNamed:@"milesTextColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + +//跑步结束后的提示界面的警告框 +#define SZHAlertColor [UIColor colorNamed:@"SZHAlertColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +//跑步结束后提示界面内的label的字体颜色 +#define SZHAlertTextColor [UIColor colorNamed:@"SZHAlertTextColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +//跑步结束后提示界面的蒙板 +#define SZHAlertViewColor [UIColor colorNamed:@"SZHAlertViewColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +//跑步结束后提示界面的结束按钮字体颜色 +#define SZHAlertEndBtnTexteColor [UIColor colorNamed:@"SZHAlertEndBtnTexteColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + +//十六进制色值转化UIColor +#define COLOR_WITH_HEX(hexValue) [UIColor colorWithRed:((float)((hexValue & 0xFF0000) >> 16)) / 255.0 green:((float)((hexValue & 0xFF00) >> 8)) / 255.0 blue:((float)(hexValue & 0xFF)) / 255.0 alpha:1.0f] + + + +//"我的"页面的黑暗模式适配 +#define MGDColor1 [UIColor colorNamed:@"MGDColor-1" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDColor2 [UIColor colorNamed:@"MGDColor-2" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDTextColor1 [UIColor colorNamed:@"MGDTextColor-1" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDTextColor2 [UIColor colorNamed:@"MGDTextColor-2" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDColor3 [UIColor colorNamed:@"MGDColor-3" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDlineColor [UIColor colorNamed:@"MGDLineColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDLineColor1 [UIColor colorNamed:@"MGDLineColor-1" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDtextXColor [UIColor colorNamed:@"MGDTextXColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDdividerColor [UIColor colorNamed:@"MGDDividerColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + +//高德地图的key +#define MAMAP_KEY @"030a8e0b2b3c762f76c33bf8eeb6ce11" + + +//各页面组件化地址 +#define kMainVCPageURL @"ZYL://pushMainVC" +#define kPersonnalVCPageURL @"ZYL://pushPersonnalVC" +#define kRankVCPageURL @"ZYL://pushRankVC" +#define kRunningVCPageURL @"ZYL://pushRunningVC" +#define kInviteVCPageURL @"ZYL://pushInviteVC" +#define kLoginVCPageURL @"ZYL://pushLoginVC" + + +//各接口URL +//上传邀约信息 +#define kCommitRunTogetherInfo @"https://wx.redrock.team/mobilerun/invite/update" +//轮询是否收到邀约 +#define kCycleYesOrNoInviteSuccess @"https://wx.redrock.team/mobilerun/invite/invited" +//查询最近一次邀约是否成功 +#define kTheLastInviteOkOrNot @"https://wx.redrock.team/mobilerun/invite/history/result" +//回传是否接受邀请 + +#define kWhetherAcceptTheInvite @"https://wx.redrock.team/mobilerun/invite/result" +//查询历史邀约数据 +#define ktheDataAboutHistoryInvited @"https://wx.redrock.team/mobilerun/invite/history" +//邀约上传跑步数据 +#define kLaunchTheInviteRunData @"hhttps://wx.redrock.team/mobilerun/invite/update_data" + +//上传跑步数据 +#define HandUpRunData @"https://cyxbsmobile.redrock.team/wxapi/mobile-run/sportRecord" + +//历史足迹 +#define kHistoryTrack @"https://wx.redrock.team/mobilerun/user/lat_lng" + +//登陆URL 跟学号和身份证后六位(post) +#define kLoginURL @"https://cyxbsmobile.redrock.team/wxapi/mobile-run/login" +//注销登陆(get) +#define kLoginoutURL @"https://wx.redrock.team/mobilerun/user/loginout" +//获取头像,后接学号+.jpg +#define kAvatorURL @"https://wx.redrock.team/mobilerun/head_img/" +//排名名单 +//token作为header +/* + 后跟time(时间段:days, weekends, months, all) + rank(哪一个榜单(student_distance_rank, student_invitation_rank, class_distance_rank)) + page 分页 + */ +#define kRankListURL @"https://wx.redrock.team/mobilerun/rank_list" +//排名 +/* + 后跟time(时间段:days, weekends, months, all) + rank(哪一个榜单(student_distance_rank, student_invitation_rank, class_distance_rank)) + 学号,id + */ +#define kRankURL @"https://wx.redrock.team/mobilerun/mobilerun/rank" +//头像url 后面加学号.jpg +#define kUserAvatarUrl @"https://wx.redrock.team/mobilerun/" +//上传头像(post) +#define kUploadAvatarUrl @"https://wx.redrock.team/mobilerun/user/upload" +//修改昵称(post) +#define kNicknameUrl @"https://wx.redrock.team/mobilerun/user/info/update" +//查询跑步记录(get) +//后跟student_id和page +#define kRunningHistoryUrl @"https://wx.redrock.team/mobilerun/user/lat_lng" +//查询被邀请人的消息(post) +#define kSearchInfoUrl @"https://wx.redrock.team/mobilerun/invite/searchinfo" +//邀约历史记录 +#define kInvitationHistoryRecordUrl @"https://wx.redrock.team/mobilerun/invite/history" +//查询被邀请人的消息 + +#define kSearchInfoUrl @"http://111.230.169.17:8080/mobilerun/invite/searchinfo" +#define cancelTheInvite @"http://111.230.169.17:8080/mobilerun/invite/cancel" +#define SALT @"runningtogether" +#define kDECRYPTKEY @"redrockmobilerun" +#define HEADERHEIGHT (STATUSBARHEIGHT+NVGBARHEIGHT) + +#define NVGBARHEIGHT (44) + +#define STATUSBARHEIGHT [[UIApplication sharedApplication] statusBarFrame].size.height + +#endif /* PrefixHeader_pch */ diff --git a/MRMobileRun/PrefixHeader.pch b/MRMobileRun/PrefixHeader.pch index 4ed0f84..f8742fd 100644 --- a/MRMobileRun/PrefixHeader.pch +++ b/MRMobileRun/PrefixHeader.pch @@ -21,9 +21,67 @@ //黑暗模式背景颜色 #define k_DarkBkgColor [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1.0] +//登陆页的背景颜色 +#define LoginBackground [UIColor colorNamed:@"LoginBackgroundColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +//登陆页的按钮颜色 +#define LoginButton [UIColor colorNamed:@"LoginButtonColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +//登陆页的字体颜色 +#define LoginText [UIColor colorNamed:@"LoginTextColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +//登陆页的提示字体的颜色 +#define LoginPal [UIColor colorNamed:@"LoginPalColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +//关于黑暗模式的颜色 + //白色模式是白色 + #define WhiteColor [UIColor colorNamed:@"whiteColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //白天是灰色 +#define GrayColor [UIColor colorNamed:@"grayColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + +//跑步按钮的背景图 +#define RunBackColor [UIColor colorNamed:@"RunBtnColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + +//结束页面的底部view背景色 +#define bottomColor [UIColor colorNamed:@"BottomColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //结束页面的字体颜色 +#define bottomTitleColor [UIColor colorNamed:@"bottomTitleColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //结束页面的公里的字的颜色 +#define kmColor [UIColor colorNamed:@"BottomUnitColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //结束页面的结束按钮字体颜色 +#define OverColor [UIColor colorNamed:@"OverBtnColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //结束页面的结束按钮背景色 +#define OverBackColor [UIColor colorNamed:@"OverBtnBackColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + +//配速、时间、燃烧卡路里 显示数字的字体颜色 +#define SpeedTextColor [UIColor colorNamed:@"SpeedNumberLblTextColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //显示公里数字的字体颜色 +#define MilesColor [UIColor colorNamed:@"milesColor" inBundle:[NSBundle mainBundle]compatibleWithTraitCollection:nil] + //显示@“公里”的字体颜色 +#define MilesTxetColor [UIColor colorNamed:@"milesTextColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + + +//跑步结束后的提示界面的警告框 +#define SZHAlertColor [UIColor colorNamed:@"SZHAlertColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +//跑步结束后提示界面内的label的字体颜色 +#define SZHAlertTextColor [UIColor colorNamed:@"SZHAlertTextColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +//跑步结束后提示界面的蒙板 +#define SZHAlertViewColor [UIColor colorNamed:@"SZHAlertViewColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +//跑步结束后提示界面的结束按钮字体颜色 +#define SZHAlertEndBtnTexteColor [UIColor colorNamed:@"SZHAlertEndBtnTexteColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define ContinueBtnTextColor [UIColor colorNamed:@"ContinueTextColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //十六进制色值转化UIColor #define COLOR_WITH_HEX(hexValue) [UIColor colorWithRed:((float)((hexValue & 0xFF0000) >> 16)) / 255.0 green:((float)((hexValue & 0xFF00) >> 8)) / 255.0 blue:((float)(hexValue & 0xFF)) / 255.0 alpha:1.0f] + +//"我的"页面的黑暗模式适配 +#define MGDColor1 [UIColor colorNamed:@"MGDColor-1" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDColor2 [UIColor colorNamed:@"MGDColor-2" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDTextColor1 [UIColor colorNamed:@"MGDTextColor-1" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDTextColor2 [UIColor colorNamed:@"MGDTextColor-2" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDColor3 [UIColor colorNamed:@"MGDColor-3" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDlineColor [UIColor colorNamed:@"MGDLineColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDLineColor1 [UIColor colorNamed:@"MGDLineColor-1" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDtextXColor [UIColor colorNamed:@"MGDTextXColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] +#define MGDdividerColor [UIColor colorNamed:@"MGDDividerColor" inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil] + //高德地图的key #define MAMAP_KEY @"030a8e0b2b3c762f76c33bf8eeb6ce11" @@ -55,7 +113,7 @@ #define kHistoryTrack @"https://wx.redrock.team/mobilerun/user/lat_lng" //登陆URL 跟学号和身份证后六位(post) -#define kLoginURL @"https://cyxbsmobile.redrock.team/wxapi/mobilerun/login" +#define kLoginURL @"https://cyxbsmobile.redrock.team/wxapi/mobile-run/login" //注销登陆(get) #define kLoginoutURL @"https://wx.redrock.team/mobilerun/user/loginout" //获取头像,后接学号+.jpg @@ -78,9 +136,9 @@ //头像url 后面加学号.jpg #define kUserAvatarUrl @"https://wx.redrock.team/mobilerun/" //上传头像(post) -#define kUploadAvatarUrl @"https://wx.redrock.team/mobilerun/user/upload" +#define kUploadAvatarUrl @"https://cyxbsmobile.redrock.team/wxapi/mobile-run/modify/avatar" //修改昵称(post) -#define kNicknameUrl @"https://wx.redrock.team/mobilerun/user/info/update" +#define kNicknameUrl @"https://cyxbsmobile.redrock.team/wxapi/mobile-run/modify/nickname" //查询跑步记录(get) //后跟student_id和page #define kRunningHistoryUrl @"https://wx.redrock.team/mobilerun/user/lat_lng" @@ -90,6 +148,15 @@ #define kInvitationHistoryRecordUrl @"https://wx.redrock.team/mobilerun/invite/history" //查询被邀请人的消息 +//上传跑步数据 +#define HandUpRunData @"https://cyxbsmobile.redrock.team/wxapi/mobile-run/sportRecord" +//获取三大数据 +#define TotalDataUrl @"https://cyxbsmobile.redrock.team/wxapi/mobile-run/getTotalData" +//获取所有运动记录 +#define AllSportRecordUrl @"https://cyxbsmobile.redrock.team/wxapi/mobile-run/getAllSportRecord" +//获取一定数量的运动记录 +#define SportListUrl @"https://cyxbsmobile.redrock.team/wxapi/mobile-run/getSportRecordList" + #define kSearchInfoUrl @"http://111.230.169.17:8080/mobilerun/invite/searchinfo" #define cancelTheInvite @"http://111.230.169.17:8080/mobilerun/invite/cancel" #define SALT @"runningtogether" diff --git a/MRMobileRun/ViewController/.DS_Store b/MRMobileRun/ViewController/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/MRMobileRun/ViewController/.DS_Store and /dev/null differ diff --git a/MRMobileRun/YBPopupMenu/YBPopupMenu.h b/MRMobileRun/YBPopupMenu/YBPopupMenu.h new file mode 100755 index 0000000..def0963 --- /dev/null +++ b/MRMobileRun/YBPopupMenu/YBPopupMenu.h @@ -0,0 +1,266 @@ +// +// YBPopupMenu.h +// YBPopupMenu +// +// Created by lyb on 2017/5/10. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import +#import "YBPopupMenuPath.h" + +// 过期提醒 +#define YBDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead) + +typedef NS_ENUM(NSInteger , YBPopupMenuType) { + YBPopupMenuTypeDefault = 0, + YBPopupMenuTypeDark +}; + +/** + 箭头方向优先级 + + 当控件超出屏幕时会自动调整成反方向 + */ +typedef NS_ENUM(NSInteger , YBPopupMenuPriorityDirection) { + YBPopupMenuPriorityDirectionTop = 0, //Default + YBPopupMenuPriorityDirectionBottom, + YBPopupMenuPriorityDirectionLeft, + YBPopupMenuPriorityDirectionRight, + YBPopupMenuPriorityDirectionNone //不自动调整 +}; + +@class YBPopupMenu; +@protocol YBPopupMenuDelegate + +@optional + +///////旧版本///////// +/** + 点击事件回调 + */ +- (void)ybPopupMenuDidSelectedAtIndex:(NSInteger)index ybPopupMenu:(YBPopupMenu *)ybPopupMenu YBDeprecated("请替用 ybPopupMenu: didSelectedAtIndex: 方法"); +- (void)ybPopupMenuBeganDismiss; +- (void)ybPopupMenuDidDismiss; +- (void)ybPopupMenuBeganShow; +- (void)ybPopupMenuDidShow; + +///////新版本///////// +- (void)ybPopupMenu:(YBPopupMenu *)ybPopupMenu didSelectedAtIndex:(NSInteger)index; + +/** + 自定义cell + + 可以自定义cell,设置后会忽略 fontSize textColor backColor type 属性 + cell 的高度是根据 itemHeight 的,直接设置无效 + 建议cell 背景色设置为透明色,不然切的圆角显示不出来 + */ +- (UITableViewCell *)ybPopupMenu:(YBPopupMenu *)ybPopupMenu cellForRowAtIndex:(NSInteger)index; + +@end + +@interface YBPopupMenu : UIView + +/** + 标题数组 只读属性 + */ +@property (nonatomic, strong, readonly) NSArray * titles; + +/** + 图片数组 只读属性 + */ +@property (nonatomic, strong, readonly) NSArray * images; + +/** + tableView Default separatorStyle is UITableViewCellSeparatorStyleNone + */ +@property (nonatomic, strong) UITableView * tableView; + +/** + 文字颜色数组 只读属性 + */ +@property (nonatomic, copy) NSArray * textColors; + +/** + 圆角半径 Default is 5.0 + */ +@property (nonatomic, assign) CGFloat cornerRadius; + +/** + 自定义圆角 Default is UIRectCornerAllCorners + + 当自动调整方向时corner会自动转换至镜像方向 + */ +@property (nonatomic, assign) UIRectCorner rectCorner; + +/** + 是否显示阴影 Default is YES + */ +@property (nonatomic, assign , getter=isShadowShowing) BOOL isShowShadow; + +/** + 是否显示灰色覆盖层 Default is YES + */ +@property (nonatomic, assign) BOOL showMaskView; + +/** + 选择菜单项后消失 Default is YES + */ +@property (nonatomic, assign) BOOL dismissOnSelected; + +/** + 点击菜单外消失 Default is YES + */ +@property (nonatomic, assign) BOOL dismissOnTouchOutside; + +/** + 设置字体大小 自定义cell时忽略 Default is 15 + */ +@property (nonatomic, assign) CGFloat fontSize; + +/** + 设置字体颜色 自定义cell时忽略 Default is [UIColor blackColor] + */ +@property (nonatomic, strong) UIColor * textColor; + +/** + 设置偏移距离 (>= 0) Default is 0.0 + */ +@property (nonatomic, assign) CGFloat offset; + +/** + 边框宽度 Default is 0.0 + + 设置边框需 > 0 + */ +@property (nonatomic, assign) CGFloat borderWidth; + +/** + 边框颜色 Default is LightGrayColor + + borderWidth <= 0 无效 + */ +@property (nonatomic, strong) UIColor * borderColor; + +/** + 箭头宽度 Default is 15 + */ +@property (nonatomic, assign) CGFloat arrowWidth; + +/** + 箭头高度 Default is 10 + */ +@property (nonatomic, assign) CGFloat arrowHeight; + +/** + 箭头位置 Default is center + + 只有箭头优先级是YBPopupMenuPriorityDirectionLeft/YBPopupMenuPriorityDirectionRight/YBPopupMenuPriorityDirectionNone时需要设置 + */ +@property (nonatomic, assign) CGFloat arrowPosition; + +/** + 箭头方向 Default is YBPopupMenuArrowDirectionTop + */ +@property (nonatomic, assign) YBPopupMenuArrowDirection arrowDirection; + +/** + 箭头优先方向 Default is YBPopupMenuPriorityDirectionTop + + 当控件超出屏幕时会自动调整箭头位置 + */ +@property (nonatomic, assign) YBPopupMenuPriorityDirection priorityDirection; + +/** + 可见的最大行数 Default is 5; + */ +@property (nonatomic, assign) NSInteger maxVisibleCount; + +/** + menu背景色 自定义cell时忽略 Default is WhiteColor + */ +@property (nonatomic, strong) UIColor * backColor; + +/** + item的高度 Default is 44; + */ +@property (nonatomic, assign) CGFloat itemHeight; + +/** + popupMenu距离最近的Screen的距离 Default is 10 + */ +@property (nonatomic, assign) CGFloat minSpace; + +/** + 设置显示模式 自定义cell时忽略 Default is YBPopupMenuTypeDefault + */ +@property (nonatomic, assign) YBPopupMenuType type; + +/** + 代理 + */ +@property (nonatomic, weak) id delegate; + +/** + 在指定位置弹出 + + @param titles 标题数组 数组里是NSString/NSAttributedString + @param icons 图标数组 数组里是NSString/UIImage + @param itemWidth 菜单宽度 + @param delegate 代理 + */ ++ (YBPopupMenu *)showAtPoint:(CGPoint)point + titles:(NSArray *)titles + icons:(NSArray *)icons + menuWidth:(CGFloat)itemWidth + delegate:(id)delegate; + +/** + 在指定位置弹出(推荐方法) + + @param point 弹出的位置 + @param titles 标题数组 数组里是NSString/NSAttributedString + @param icons 图标数组 数组里是NSString/UIImage + @param itemWidth 菜单宽度 + @param otherSetting 其他设置 + */ ++ (YBPopupMenu *)showAtPoint:(CGPoint)point + titles:(NSArray *)titles + icons:(NSArray *)icons + menuWidth:(CGFloat)itemWidth + otherSettings:(void (^) (YBPopupMenu * popupMenu))otherSetting; + +/** + 依赖指定view弹出 + + @param titles 标题数组 数组里是NSString/NSAttributedString + @param icons 图标数组 数组里是NSString/UIImage + @param itemWidth 菜单宽度 + @param delegate 代理 + */ ++ (YBPopupMenu *)showRelyOnView:(UIView *)view + titles:(NSArray *)titles + icons:(NSArray *)icons + menuWidth:(CGFloat)itemWidth + delegate:(id)delegate; + +/** + 依赖指定view弹出(推荐方法) + + @param titles 标题数组 数组里是NSString/NSAttributedString + @param icons 图标数组 数组里是NSString/UIImage + @param itemWidth 菜单宽度 + @param otherSetting 其他设置 + */ ++ (YBPopupMenu *)showRelyOnView:(UIView *)view + titles:(NSArray *)titles + icons:(NSArray *)icons + menuWidth:(CGFloat)itemWidth + otherSettings:(void (^) (YBPopupMenu * popupMenu))otherSetting; + +/** + 消失 + */ +- (void)dismiss; + +@end diff --git a/MRMobileRun/YBPopupMenu/YBPopupMenu.m b/MRMobileRun/YBPopupMenu/YBPopupMenu.m new file mode 100755 index 0000000..77977fd --- /dev/null +++ b/MRMobileRun/YBPopupMenu/YBPopupMenu.m @@ -0,0 +1,770 @@ +// +// YBPopupMenu.m +// YBPopupMenu +// +// Created by lyb on 2017/5/10. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import "YBPopupMenu.h" +#import "YBPopupMenuPath.h" + +#define YBScreenWidth [UIScreen mainScreen].bounds.size.width +#define YBScreenHeight [UIScreen mainScreen].bounds.size.height +#define YBMainWindow [UIApplication sharedApplication].keyWindow +#define YB_SAFE_BLOCK(BlockName, ...) ({ !BlockName ? nil : BlockName(__VA_ARGS__); }) + +#pragma mark - ///////////// +#pragma mark - private cell + +@interface YBPopupMenuCell : UITableViewCell +@property (nonatomic, assign) BOOL isShowSeparator; +@property (nonatomic, strong) UIColor * separatorColor; +@end + +@implementation YBPopupMenuCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + if (self) { + _isShowSeparator = YES; + _separatorColor = [UIColor lightGrayColor]; + [self setNeedsDisplay]; + } + return self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + CGRect frame = self.textLabel.frame; + frame.size.width = self.bounds.size.width; + self.textLabel.frame = frame; +} + +- (void)setIsShowSeparator:(BOOL)isShowSeparator +{ + _isShowSeparator = isShowSeparator; + [self setNeedsDisplay]; +} + +- (void)setSeparatorColor:(UIColor *)separatorColor +{ + _separatorColor = separatorColor; + [self setNeedsDisplay]; +} + +- (void)drawRect:(CGRect)rect +{ + if (!_isShowSeparator) return; + UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, rect.size.height - 0.5, rect.size.width, 0.5)]; + [_separatorColor setFill]; + [bezierPath fillWithBlendMode:kCGBlendModeNormal alpha:1]; + [bezierPath closePath]; +} + +@end + + + +@interface YBPopupMenu () +< +UITableViewDelegate, +UITableViewDataSource +> + +@property (nonatomic, strong) UIView * menuBackView; +@property (nonatomic) CGRect relyRect; +@property (nonatomic, assign) CGFloat itemWidth; +@property (nonatomic) CGPoint point; +@property (nonatomic, assign) BOOL isCornerChanged; +@property (nonatomic, strong) UIColor * separatorColor; +@property (nonatomic, assign) BOOL isChangeDirection; +@end + +@implementation YBPopupMenu + +- (instancetype)init +{ + self = [super init]; + if (self) { + [self setDefaultSettings]; + } + return self; +} + +#pragma mark - publics ++ (YBPopupMenu *)showAtPoint:(CGPoint)point titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth delegate:(id)delegate +{ + YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init]; + popupMenu.point = point; + popupMenu.titles = titles; + popupMenu.images = icons; + popupMenu.itemWidth = itemWidth; + popupMenu.delegate = delegate; + [popupMenu show]; + return popupMenu; +} + ++ (YBPopupMenu *)showRelyOnView:(UIView *)view titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth delegate:(id)delegate +{ + CGRect absoluteRect = [view convertRect:view.bounds toView:YBMainWindow]; + CGPoint relyPoint = CGPointMake(absoluteRect.origin.x + absoluteRect.size.width / 2, absoluteRect.origin.y + absoluteRect.size.height); + YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init]; + popupMenu.point = relyPoint; + popupMenu.relyRect = absoluteRect; + popupMenu.titles = titles; + popupMenu.images = icons; + popupMenu.itemWidth = itemWidth; + popupMenu.delegate = delegate; + [popupMenu show]; + return popupMenu; +} + ++ (YBPopupMenu *)showAtPoint:(CGPoint)point titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth otherSettings:(void (^) (YBPopupMenu * popupMenu))otherSetting +{ + YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init]; + popupMenu.point = point; + popupMenu.titles = titles; + popupMenu.images = icons; + popupMenu.itemWidth = itemWidth; + YB_SAFE_BLOCK(otherSetting,popupMenu); + [popupMenu show]; + return popupMenu; +} + ++ (YBPopupMenu *)showRelyOnView:(UIView *)view titles:(NSArray *)titles icons:(NSArray *)icons menuWidth:(CGFloat)itemWidth otherSettings:(void (^) (YBPopupMenu * popupMenu))otherSetting +{ + CGRect absoluteRect = [view convertRect:view.bounds toView:YBMainWindow]; + CGPoint relyPoint = CGPointMake(absoluteRect.origin.x + absoluteRect.size.width / 2, absoluteRect.origin.y + absoluteRect.size.height); + YBPopupMenu *popupMenu = [[YBPopupMenu alloc] init]; + popupMenu.point = relyPoint; + popupMenu.relyRect = absoluteRect; + popupMenu.titles = titles; + popupMenu.images = icons; + popupMenu.itemWidth = itemWidth; + YB_SAFE_BLOCK(otherSetting,popupMenu); + [popupMenu show]; + return popupMenu; +} + +- (void)dismiss +{ + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuBeganDismiss)]) { + [self.delegate ybPopupMenuBeganDismiss]; + } + [UIView animateWithDuration: 0.25 animations:^{ + self.layer.affineTransform = CGAffineTransformMakeScale(0.1, 0.1); + self.alpha = 0; + self->_menuBackView.alpha = 0; + } completion:^(BOOL finished) { + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuDidDismiss)]) { + [self.delegate ybPopupMenuDidDismiss]; + } + self.delegate = nil; + [self removeFromSuperview]; + [self->_menuBackView removeFromSuperview]; + }]; +} + +#pragma mark tableViewDelegate & dataSource +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return _titles.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell * tableViewCell = nil; + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenu:cellForRowAtIndex:)]) { + tableViewCell = [self.delegate ybPopupMenu:self cellForRowAtIndex:indexPath.row]; + } + + if (tableViewCell) { + return tableViewCell; + } + + static NSString * identifier = @"ybPopupMenu"; + YBPopupMenuCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; + if (!cell) { + cell = [[YBPopupMenuCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier]; + cell.textLabel.numberOfLines = 0; + } + cell.selectionStyle = UITableViewCellSelectionStyleNone; + cell.backgroundColor = [UIColor clearColor]; + if (_textColors.count > indexPath.row) { + cell.textLabel.textColor = _textColors[indexPath.row]; + + }else { + cell.textLabel.textColor = _textColor; + } + cell.textLabel.font = [UIFont systemFontOfSize:_fontSize]; + if ([_titles[indexPath.row] isKindOfClass:[NSAttributedString class]]) { + cell.textLabel.attributedText = _titles[indexPath.row]; + }else if ([_titles[indexPath.row] isKindOfClass:[NSString class]]) { + cell.textLabel.text = _titles[indexPath.row]; + }else { + cell.textLabel.text = nil; + } + cell.separatorColor = _separatorColor; + if (_images.count >= indexPath.row + 1) { + if ([_images[indexPath.row] isKindOfClass:[NSString class]]) { + cell.imageView.image = [UIImage imageNamed:_images[indexPath.row]]; + }else if ([_images[indexPath.row] isKindOfClass:[UIImage class]]){ + cell.imageView.image = _images[indexPath.row]; + }else { + cell.imageView.image = nil; + } + }else { + cell.imageView.image = nil; + } + return cell; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath +{ + return _itemHeight; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + if (_dismissOnSelected) [self dismiss]; + + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuDidSelectedAtIndex:ybPopupMenu:)]) { + +// [self.delegate ybPopupMenuDidSelectedAtIndex:indexPath.row ybPopupMenu:self]; + } + + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenu:didSelectedAtIndex:)]) { + [self.delegate ybPopupMenu:self didSelectedAtIndex:indexPath.row]; + } +} + +#pragma mark - scrollViewDelegate +- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView +{ + if ([[self getLastVisibleCell] isKindOfClass:[YBPopupMenuCell class]]) { + YBPopupMenuCell *cell = [self getLastVisibleCell]; + cell.isShowSeparator = YES; + } +} + +- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView +{ + if ([[self getLastVisibleCell] isKindOfClass:[YBPopupMenuCell class]]) { + YBPopupMenuCell *cell = [self getLastVisibleCell]; + cell.isShowSeparator = NO; + } +} + +- (YBPopupMenuCell *)getLastVisibleCell +{ + NSArray *indexPaths = [self.tableView indexPathsForVisibleRows]; + indexPaths = [indexPaths sortedArrayUsingComparator:^NSComparisonResult(NSIndexPath * _Nonnull obj1, NSIndexPath * _Nonnull obj2) { + return obj1.row < obj2.row; + }]; + NSIndexPath *indexPath = indexPaths.firstObject; + return [self.tableView cellForRowAtIndexPath:indexPath]; +} + +#pragma mark - privates +- (void)show +{ + [YBMainWindow addSubview:_menuBackView]; + [YBMainWindow addSubview:self]; + if ([[self getLastVisibleCell] isKindOfClass:[YBPopupMenuCell class]]) { + YBPopupMenuCell *cell = [self getLastVisibleCell]; + cell.isShowSeparator = NO; + } + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuBeganShow)]) { + [self.delegate ybPopupMenuBeganShow]; + } + self.layer.affineTransform = CGAffineTransformMakeScale(0.1, 0.1); + [UIView animateWithDuration: 0.25 animations:^{ + self.layer.affineTransform = CGAffineTransformMakeScale(1.0, 1.0); + self.alpha = 1; + self->_menuBackView.alpha = 1; + } completion:^(BOOL finished) { + if (self.delegate && [self.delegate respondsToSelector:@selector(ybPopupMenuDidShow)]) { + [self.delegate ybPopupMenuDidShow]; + } + }]; +} + +- (void)setDefaultSettings +{ + _cornerRadius = 5.0; + _rectCorner = UIRectCornerAllCorners; + self.isShowShadow = YES; + _dismissOnSelected = YES; + _dismissOnTouchOutside = YES; + _fontSize = 15; + _textColor = [UIColor blackColor]; + _offset = 0.0; + _relyRect = CGRectZero; + _point = CGPointZero; + _borderWidth = 0.0; + _borderColor = [UIColor lightGrayColor]; + _arrowWidth = 15.0; + _arrowHeight = 10.0; + if (@available(iOS 11.0, *)) { + self.backColor = MGDColor1; + } else { + // Fallback on earlier versions + } + _type = YBPopupMenuTypeDefault; + _arrowDirection = YBPopupMenuArrowDirectionTop; + _priorityDirection = YBPopupMenuPriorityDirectionTop; + _minSpace = 10.0; + _maxVisibleCount = 5; + _itemHeight = 44; + _isCornerChanged = NO; + _showMaskView = YES; + _menuBackView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, YBScreenWidth, YBScreenHeight)]; + _menuBackView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.1]; + _menuBackView.alpha = 0; + UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(touchOutSide)]; + [_menuBackView addGestureRecognizer: tap]; + self.alpha = 0; + self.backgroundColor = [UIColor clearColor]; + [self addSubview:self.tableView]; +} + +- (UITableView *)tableView +{ + if (!_tableView) { + _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; + _tableView.backgroundColor = [UIColor clearColor]; + _tableView.tableFooterView = [UIView new]; + _tableView.delegate = self; + _tableView.dataSource = self; + _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; + } + return _tableView; +} + +- (void)touchOutSide +{ + if (_dismissOnTouchOutside) { + [self dismiss]; + } +} + +- (void)setIsShowShadow:(BOOL)isShowShadow +{ + _isShowShadow = isShowShadow; + self.layer.shadowOpacity = isShowShadow ? 0.5 : 0; + self.layer.shadowOffset = CGSizeMake(0, 0); + self.layer.shadowRadius = isShowShadow ? 2.0 : 0; +} + +- (void)setShowMaskView:(BOOL)showMaskView +{ + _showMaskView = showMaskView; + _menuBackView.backgroundColor = showMaskView ? [[UIColor blackColor] colorWithAlphaComponent:0.1] : [UIColor clearColor]; +} + +- (void)setType:(YBPopupMenuType)type +{ + _type = type; + switch (type) { + case YBPopupMenuTypeDark: + { + _textColor = [UIColor lightGrayColor]; + _backColor = [UIColor colorWithRed:0.25 green:0.27 blue:0.29 alpha:1]; + _separatorColor = [UIColor lightGrayColor]; + } + break; + + default: + { + _textColor = [UIColor blackColor]; + _backColor = [UIColor whiteColor]; + _separatorColor = [UIColor lightGrayColor]; + } + break; + } + [self updateUI]; +} + +- (void)setFontSize:(CGFloat)fontSize +{ + _fontSize = fontSize; + [self.tableView reloadData]; +} + +- (void)setTextColor:(UIColor *)textColor +{ + _textColor = textColor; + [self.tableView reloadData]; +} + +- (void)setPoint:(CGPoint)point +{ + _point = point; + [self updateUI]; +} + +- (void)setItemWidth:(CGFloat)itemWidth +{ + _itemWidth = itemWidth; + [self updateUI]; +} + +- (void)setItemHeight:(CGFloat)itemHeight +{ + _itemHeight = itemHeight; + [self updateUI]; +} + +- (void)setBorderWidth:(CGFloat)borderWidth +{ + _borderWidth = borderWidth; + [self updateUI]; +} + +- (void)setBorderColor:(UIColor *)borderColor +{ + _borderColor = borderColor; + [self updateUI]; +} + +- (void)setArrowPosition:(CGFloat)arrowPosition +{ + _arrowPosition = arrowPosition; + [self updateUI]; +} + +- (void)setArrowWidth:(CGFloat)arrowWidth +{ + _arrowWidth = arrowWidth; + [self updateUI]; +} + +- (void)setArrowHeight:(CGFloat)arrowHeight +{ + _arrowHeight = arrowHeight; + [self updateUI]; +} + +- (void)setArrowDirection:(YBPopupMenuArrowDirection)arrowDirection +{ + _arrowDirection = arrowDirection; + [self updateUI]; +} + +- (void)setMaxVisibleCount:(NSInteger)maxVisibleCount +{ + _maxVisibleCount = maxVisibleCount; + [self updateUI]; +} + +- (void)setBackColor:(UIColor *)backColor +{ + _backColor = backColor; + [self updateUI]; +} + +- (void)setTitles:(NSArray *)titles +{ + _titles = titles; + [self updateUI]; +} + +- (void)setImages:(NSArray *)images +{ + _images = images; + [self updateUI]; +} + +- (void)setPriorityDirection:(YBPopupMenuPriorityDirection)priorityDirection +{ + _priorityDirection = priorityDirection; + [self updateUI]; +} + +- (void)setRectCorner:(UIRectCorner)rectCorner +{ + _rectCorner = rectCorner; + [self updateUI]; +} + +- (void)setCornerRadius:(CGFloat)cornerRadius +{ + _cornerRadius = cornerRadius; + [self updateUI]; +} + +- (void)setOffset:(CGFloat)offset +{ + _offset = offset; + [self updateUI]; +} + +- (void)updateUI +{ + CGFloat height; + if (_titles.count > _maxVisibleCount) { + height = _itemHeight * _maxVisibleCount + _borderWidth * 2; + self.tableView.bounces = YES; + }else { + height = _itemHeight * _titles.count + _borderWidth * 2; + self.tableView.bounces = NO; + } + _isChangeDirection = NO; + if (_priorityDirection == YBPopupMenuPriorityDirectionTop) { + if (_point.y + height + _arrowHeight > YBScreenHeight - _minSpace) { + _arrowDirection = YBPopupMenuArrowDirectionBottom; + _isChangeDirection = YES; + }else { + _arrowDirection = YBPopupMenuArrowDirectionTop; + _isChangeDirection = NO; + } + }else if (_priorityDirection == YBPopupMenuPriorityDirectionBottom) { + if (_point.y - height - _arrowHeight < _minSpace) { + _arrowDirection = YBPopupMenuArrowDirectionTop; + _isChangeDirection = YES; + }else { + _arrowDirection = YBPopupMenuArrowDirectionBottom; + _isChangeDirection = NO; + } + }else if (_priorityDirection == YBPopupMenuPriorityDirectionLeft) { + if (_point.x + _itemWidth + _arrowHeight > YBScreenWidth - _minSpace) { + _arrowDirection = YBPopupMenuArrowDirectionRight; + _isChangeDirection = YES; + }else { + _arrowDirection = YBPopupMenuArrowDirectionLeft; + _isChangeDirection = NO; + } + }else if (_priorityDirection == YBPopupMenuPriorityDirectionRight) { + if (_point.x - _itemWidth - _arrowHeight < _minSpace) { + _arrowDirection = YBPopupMenuArrowDirectionLeft; + _isChangeDirection = YES; + }else { + _arrowDirection = YBPopupMenuArrowDirectionRight; + _isChangeDirection = NO; + } + } + [self setArrowPosition]; + [self setRelyRect]; + if (_arrowDirection == YBPopupMenuArrowDirectionTop) { + CGFloat y = _isChangeDirection ? _point.y : _point.y; + if (_arrowPosition > _itemWidth / 2) { + self.frame = CGRectMake(YBScreenWidth - _minSpace - _itemWidth, y, _itemWidth, height + _arrowHeight); + }else if (_arrowPosition < _itemWidth / 2) { + self.frame = CGRectMake(_minSpace, y, _itemWidth, height + _arrowHeight); + }else { + self.frame = CGRectMake(_point.x - _itemWidth / 2, y, _itemWidth, height + _arrowHeight); + } + }else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) { + CGFloat y = _isChangeDirection ? _point.y - _arrowHeight - height : _point.y - _arrowHeight - height; + if (_arrowPosition > _itemWidth / 2) { + self.frame = CGRectMake(YBScreenWidth - _minSpace - _itemWidth, y, _itemWidth, height + _arrowHeight); + }else if (_arrowPosition < _itemWidth / 2) { + self.frame = CGRectMake(_minSpace, y, _itemWidth, height + _arrowHeight); + }else { + self.frame = CGRectMake(_point.x - _itemWidth / 2, y, _itemWidth, height + _arrowHeight); + } + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) { + CGFloat x = _isChangeDirection ? _point.x : _point.x; + if (_arrowPosition < _itemHeight / 2) { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + }else if (_arrowPosition > _itemHeight / 2) { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + }else { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + } + }else if (_arrowDirection == YBPopupMenuArrowDirectionRight) { + CGFloat x = _isChangeDirection ? _point.x - _itemWidth - _arrowHeight : _point.x - _itemWidth - _arrowHeight; + if (_arrowPosition < _itemHeight / 2) { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + }else if (_arrowPosition > _itemHeight / 2) { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + }else { + self.frame = CGRectMake(x, _point.y - _arrowPosition, _itemWidth + _arrowHeight, height); + } + }else if (_arrowDirection == YBPopupMenuArrowDirectionNone) { + + } + + if (_isChangeDirection) { + [self changeRectCorner]; + } + [self setAnchorPoint]; + [self setOffset]; + [self.tableView reloadData]; + [self setNeedsDisplay]; +} + +- (void)setRelyRect +{ + if (CGRectEqualToRect(_relyRect, CGRectZero)) { + return; + } + if (_arrowDirection == YBPopupMenuArrowDirectionTop) { + _point.y = _relyRect.size.height + _relyRect.origin.y; + }else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) { + _point.y = _relyRect.origin.y; + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) { + _point = CGPointMake(_relyRect.origin.x + _relyRect.size.width, _relyRect.origin.y + _relyRect.size.height / 2); + }else { + _point = CGPointMake(_relyRect.origin.x, _relyRect.origin.y + _relyRect.size.height / 2); + } +} + + +- (void)setFrame:(CGRect)frame +{ + [super setFrame:frame]; + if (_arrowDirection == YBPopupMenuArrowDirectionTop) { + self.tableView.frame = CGRectMake(_borderWidth, _borderWidth + _arrowHeight, frame.size.width - _borderWidth * 2, frame.size.height - _arrowHeight); + }else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) { + self.tableView.frame = CGRectMake(_borderWidth, _borderWidth, frame.size.width - _borderWidth * 2, frame.size.height - _arrowHeight); + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) { + self.tableView.frame = CGRectMake(_borderWidth + _arrowHeight, _borderWidth , frame.size.width - _borderWidth * 2 - _arrowHeight, frame.size.height); + }else if (_arrowDirection == YBPopupMenuArrowDirectionRight) { + self.tableView.frame = CGRectMake(_borderWidth , _borderWidth , frame.size.width - _borderWidth * 2 - _arrowHeight, frame.size.height); + } +} + +- (void)changeRectCorner +{ + if (_isCornerChanged || _rectCorner == UIRectCornerAllCorners) { + return; + } + BOOL haveTopLeftCorner = NO, haveTopRightCorner = NO, haveBottomLeftCorner = NO, haveBottomRightCorner = NO; + if (_rectCorner & UIRectCornerTopLeft) { + haveTopLeftCorner = YES; + } + if (_rectCorner & UIRectCornerTopRight) { + haveTopRightCorner = YES; + } + if (_rectCorner & UIRectCornerBottomLeft) { + haveBottomLeftCorner = YES; + } + if (_rectCorner & UIRectCornerBottomRight) { + haveBottomRightCorner = YES; + } + + if (_arrowDirection == YBPopupMenuArrowDirectionTop || _arrowDirection == YBPopupMenuArrowDirectionBottom) { + + if (haveTopLeftCorner) { + _rectCorner = _rectCorner | UIRectCornerBottomLeft; + }else { + _rectCorner = _rectCorner & (~UIRectCornerBottomLeft); + } + if (haveTopRightCorner) { + _rectCorner = _rectCorner | UIRectCornerBottomRight; + }else { + _rectCorner = _rectCorner & (~UIRectCornerBottomRight); + } + if (haveBottomLeftCorner) { + _rectCorner = _rectCorner | UIRectCornerTopLeft; + }else { + _rectCorner = _rectCorner & (~UIRectCornerTopLeft); + } + if (haveBottomRightCorner) { + _rectCorner = _rectCorner | UIRectCornerTopRight; + }else { + _rectCorner = _rectCorner & (~UIRectCornerTopRight); + } + + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft || _arrowDirection == YBPopupMenuArrowDirectionRight) { + if (haveTopLeftCorner) { + _rectCorner = _rectCorner | UIRectCornerTopRight; + }else { + _rectCorner = _rectCorner & (~UIRectCornerTopRight); + } + if (haveTopRightCorner) { + _rectCorner = _rectCorner | UIRectCornerTopLeft; + }else { + _rectCorner = _rectCorner & (~UIRectCornerTopLeft); + } + if (haveBottomLeftCorner) { + _rectCorner = _rectCorner | UIRectCornerBottomRight; + }else { + _rectCorner = _rectCorner & (~UIRectCornerBottomRight); + } + if (haveBottomRightCorner) { + _rectCorner = _rectCorner | UIRectCornerBottomLeft; + }else { + _rectCorner = _rectCorner & (~UIRectCornerBottomLeft); + } + } + + _isCornerChanged = YES; +} + +- (void)setOffset +{ + if (_itemWidth == 0) return; + + CGRect originRect = self.frame; + + if (_arrowDirection == YBPopupMenuArrowDirectionTop) { + originRect.origin.y += _offset; + }else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) { + originRect.origin.y -= _offset; + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) { + originRect.origin.x += _offset; + }else if (_arrowDirection == YBPopupMenuArrowDirectionRight) { + originRect.origin.x -= _offset; + } + self.frame = originRect; +} + +- (void)setAnchorPoint +{ + if (_itemWidth == 0) return; + + CGPoint point = CGPointMake(0.5, 0.5); + if (_arrowDirection == YBPopupMenuArrowDirectionTop) { + point = CGPointMake(_arrowPosition / _itemWidth, 0); + }else if (_arrowDirection == YBPopupMenuArrowDirectionBottom) { + point = CGPointMake(_arrowPosition / _itemWidth, 1); + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft) { + point = CGPointMake(0, (_itemHeight - _arrowPosition) / _itemHeight); + }else if (_arrowDirection == YBPopupMenuArrowDirectionRight) { + point = CGPointMake(1, (_itemHeight - _arrowPosition) / _itemHeight); + } + CGRect originRect = self.frame; + self.layer.anchorPoint = point; + self.frame = originRect; +} + +- (void)setArrowPosition +{ + if (_priorityDirection == YBPopupMenuPriorityDirectionNone) { + return; + } + if (_arrowDirection == YBPopupMenuArrowDirectionTop || _arrowDirection == YBPopupMenuArrowDirectionBottom) { + if (_point.x + _itemWidth / 2 > YBScreenWidth - _minSpace) { + _arrowPosition = _itemWidth - (YBScreenWidth - _minSpace - _point.x); + }else if (_point.x < _itemWidth / 2 + _minSpace) { + _arrowPosition = _point.x - _minSpace; + }else { + _arrowPosition = _itemWidth / 2; + } + + }else if (_arrowDirection == YBPopupMenuArrowDirectionLeft || _arrowDirection == YBPopupMenuArrowDirectionRight) { +// if (_point.y + _itemHeight / 2 > YBScreenHeight - _minSpace) { +// _arrowPosition = _itemHeight - (YBScreenHeight - _minSpace - _point.y); +// }else if (_point.y < _itemHeight / 2 + _minSpace) { +// _arrowPosition = _point.y - _minSpace; +// }else { +// _arrowPosition = _itemHeight / 2; +// } + } +} + +- (void)drawRect:(CGRect)rect +{ + UIBezierPath *bezierPath = [YBPopupMenuPath yb_bezierPathWithRect:rect rectCorner:_rectCorner cornerRadius:_cornerRadius borderWidth:_borderWidth borderColor:_borderColor backgroundColor:_backColor arrowWidth:_arrowWidth arrowHeight:_arrowHeight arrowPosition:_arrowPosition arrowDirection:_arrowDirection]; + [bezierPath fill]; + [bezierPath stroke]; +} + +@end diff --git a/MRMobileRun/YBPopupMenu/YBPopupMenuPath.h b/MRMobileRun/YBPopupMenu/YBPopupMenuPath.h new file mode 100755 index 0000000..314a803 --- /dev/null +++ b/MRMobileRun/YBPopupMenu/YBPopupMenuPath.h @@ -0,0 +1,39 @@ +// +// YBPopupMenuPath.h +// YBPopupMenu +// +// Created by lyb on 2017/5/9. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import + +typedef NS_ENUM(NSInteger, YBPopupMenuArrowDirection) { + YBPopupMenuArrowDirectionTop = 0, //箭头朝上 + YBPopupMenuArrowDirectionBottom, //箭头朝下 + YBPopupMenuArrowDirectionLeft, //箭头朝左 + YBPopupMenuArrowDirectionRight, //箭头朝右 + YBPopupMenuArrowDirectionNone //没有箭头 +}; + +@interface YBPopupMenuPath : NSObject + ++ (CAShapeLayer *)yb_maskLayerWithRect:(CGRect)rect + rectCorner:(UIRectCorner)rectCorner + cornerRadius:(CGFloat)cornerRadius + arrowWidth:(CGFloat)arrowWidth + arrowHeight:(CGFloat)arrowHeight + arrowPosition:(CGFloat)arrowPosition + arrowDirection:(YBPopupMenuArrowDirection)arrowDirection; + ++ (UIBezierPath *)yb_bezierPathWithRect:(CGRect)rect + rectCorner:(UIRectCorner)rectCorner + cornerRadius:(CGFloat)cornerRadius + borderWidth:(CGFloat)borderWidth + borderColor:(UIColor *)borderColor + backgroundColor:(UIColor *)backgroundColor + arrowWidth:(CGFloat)arrowWidth + arrowHeight:(CGFloat)arrowHeight + arrowPosition:(CGFloat)arrowPosition + arrowDirection:(YBPopupMenuArrowDirection)arrowDirection; +@end diff --git a/MRMobileRun/YBPopupMenu/YBPopupMenuPath.m b/MRMobileRun/YBPopupMenu/YBPopupMenuPath.m new file mode 100755 index 0000000..e577f2a --- /dev/null +++ b/MRMobileRun/YBPopupMenu/YBPopupMenuPath.m @@ -0,0 +1,172 @@ +// +// YBPopupMenuPath.m +// YBPopupMenu +// +// Created by lyb on 2017/5/9. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import "YBPopupMenuPath.h" +#import "YBRectConst.h" + +@implementation YBPopupMenuPath + ++ (CAShapeLayer *)yb_maskLayerWithRect:(CGRect)rect + rectCorner:(UIRectCorner)rectCorner + cornerRadius:(CGFloat)cornerRadius + arrowWidth:(CGFloat)arrowWidth + arrowHeight:(CGFloat)arrowHeight + arrowPosition:(CGFloat)arrowPosition + arrowDirection:(YBPopupMenuArrowDirection)arrowDirection +{ + CAShapeLayer *shapeLayer = [CAShapeLayer layer]; + shapeLayer.path = [self yb_bezierPathWithRect:rect rectCorner:rectCorner cornerRadius:cornerRadius borderWidth:0 borderColor:nil backgroundColor:nil arrowWidth:arrowWidth arrowHeight:arrowHeight arrowPosition:arrowPosition arrowDirection:arrowDirection].CGPath; + return shapeLayer; +} + + ++ (UIBezierPath *)yb_bezierPathWithRect:(CGRect)rect + rectCorner:(UIRectCorner)rectCorner + cornerRadius:(CGFloat)cornerRadius + borderWidth:(CGFloat)borderWidth + borderColor:(UIColor *)borderColor + backgroundColor:(UIColor *)backgroundColor + arrowWidth:(CGFloat)arrowWidth + arrowHeight:(CGFloat)arrowHeight + arrowPosition:(CGFloat)arrowPosition + arrowDirection:(YBPopupMenuArrowDirection)arrowDirection +{ + UIBezierPath *bezierPath = [UIBezierPath bezierPath]; + if (borderColor) { + [borderColor setStroke]; + } + if (backgroundColor) { + [backgroundColor setFill]; + } + bezierPath.lineWidth = borderWidth; + rect = CGRectMake(borderWidth / 2, borderWidth / 2, YBRectWidth(rect) - borderWidth, YBRectHeight(rect) - borderWidth); + CGFloat topRightRadius = 0,topLeftRadius = 0,bottomRightRadius = 0,bottomLeftRadius = 0; + CGPoint topRightArcCenter,topLeftArcCenter,bottomRightArcCenter,bottomLeftArcCenter; + + if (rectCorner & UIRectCornerTopLeft) { + topLeftRadius = cornerRadius; + } + if (rectCorner & UIRectCornerTopRight) { + topRightRadius = cornerRadius; + } + if (rectCorner & UIRectCornerBottomLeft) { + bottomLeftRadius = cornerRadius; + } + if (rectCorner & UIRectCornerBottomRight) { + bottomRightRadius = cornerRadius; + } + + if (arrowDirection == YBPopupMenuArrowDirectionTop) { + topLeftArcCenter = CGPointMake(topLeftRadius + YBRectX(rect), arrowHeight + topLeftRadius + YBRectX(rect)); + topRightArcCenter = CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect), arrowHeight + topRightRadius + YBRectX(rect)); + bottomLeftArcCenter = CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) - bottomLeftRadius + YBRectX(rect)); + bottomRightArcCenter = CGPointMake(YBRectWidth(rect) - bottomRightRadius + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius + YBRectX(rect)); + if (arrowPosition < topLeftRadius + arrowWidth / 2) { + arrowPosition = topLeftRadius + arrowWidth / 2; + }else if (arrowPosition > YBRectWidth(rect) - topRightRadius - arrowWidth / 2) { + arrowPosition = YBRectWidth(rect) - topRightRadius - arrowWidth / 2; + } + [bezierPath moveToPoint:CGPointMake(arrowPosition - arrowWidth / 2, arrowHeight + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(arrowPosition, YBRectTop(rect) + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(arrowPosition + arrowWidth / 2, arrowHeight + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - topRightRadius, arrowHeight + YBRectX(rect))]; + [bezierPath addArcWithCenter:topRightArcCenter radius:topRightRadius startAngle:M_PI * 3 / 2 endAngle:2 * M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius - YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomRightArcCenter radius:bottomRightRadius startAngle:0 endAngle:M_PI_2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) + YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomLeftArcCenter radius:bottomLeftRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectX(rect), arrowHeight + topLeftRadius + YBRectX(rect))]; + [bezierPath addArcWithCenter:topLeftArcCenter radius:topLeftRadius startAngle:M_PI endAngle:M_PI * 3 / 2 clockwise:YES]; + + }else if (arrowDirection == YBPopupMenuArrowDirectionBottom) { + topLeftArcCenter = CGPointMake(topLeftRadius + YBRectX(rect),topLeftRadius + YBRectX(rect)); + topRightArcCenter = CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect), topRightRadius + YBRectX(rect)); + bottomLeftArcCenter = CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) - bottomLeftRadius + YBRectX(rect) - arrowHeight); + bottomRightArcCenter = CGPointMake(YBRectWidth(rect) - bottomRightRadius + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius + YBRectX(rect) - arrowHeight); + if (arrowPosition < bottomLeftRadius + arrowWidth / 2) { + arrowPosition = bottomLeftRadius + arrowWidth / 2; + }else if (arrowPosition > YBRectWidth(rect) - bottomRightRadius - arrowWidth / 2) { + arrowPosition = YBRectWidth(rect) - bottomRightRadius - arrowWidth / 2; + } + [bezierPath moveToPoint:CGPointMake(arrowPosition + arrowWidth / 2, YBRectHeight(rect) - arrowHeight + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(arrowPosition, YBRectHeight(rect) + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(arrowPosition - arrowWidth / 2, YBRectHeight(rect) - arrowHeight + YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) - arrowHeight + YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomLeftArcCenter radius:bottomLeftRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectX(rect), topLeftRadius + YBRectX(rect))]; + [bezierPath addArcWithCenter:topLeftArcCenter radius:topLeftRadius startAngle:M_PI endAngle:M_PI * 3 / 2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect), YBRectX(rect))]; + [bezierPath addArcWithCenter:topRightArcCenter radius:topRightRadius startAngle:M_PI * 3 / 2 endAngle:2 * M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius - YBRectX(rect) - arrowHeight)]; + [bezierPath addArcWithCenter:bottomRightArcCenter radius:bottomRightRadius startAngle:0 endAngle:M_PI_2 clockwise:YES]; + + }else if (arrowDirection == YBPopupMenuArrowDirectionLeft) { + topLeftArcCenter = CGPointMake(topLeftRadius + YBRectX(rect) + arrowHeight,topLeftRadius + YBRectX(rect)); + topRightArcCenter = CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect), topRightRadius + YBRectX(rect)); + bottomLeftArcCenter = CGPointMake(bottomLeftRadius + YBRectX(rect) + arrowHeight, YBRectHeight(rect) - bottomLeftRadius + YBRectX(rect)); + bottomRightArcCenter = CGPointMake(YBRectWidth(rect) - bottomRightRadius + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius + YBRectX(rect)); + if (arrowPosition < topLeftRadius + arrowWidth / 2) { + arrowPosition = topLeftRadius + arrowWidth / 2; + }else if (arrowPosition > YBRectHeight(rect) - bottomLeftRadius - arrowWidth / 2) { + arrowPosition = YBRectHeight(rect) - bottomLeftRadius - arrowWidth / 2; + } + [bezierPath moveToPoint:CGPointMake(arrowHeight + YBRectX(rect), arrowPosition + arrowWidth / 2)]; + [bezierPath addLineToPoint:CGPointMake(YBRectX(rect), arrowPosition)]; + [bezierPath addLineToPoint:CGPointMake(arrowHeight + YBRectX(rect), arrowPosition - arrowWidth / 2)]; + [bezierPath addLineToPoint:CGPointMake(arrowHeight + YBRectX(rect), topLeftRadius + YBRectX(rect))]; + [bezierPath addArcWithCenter:topLeftArcCenter radius:topLeftRadius startAngle:M_PI endAngle:M_PI * 3 / 2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - topRightRadius, YBRectX(rect))]; + [bezierPath addArcWithCenter:topRightArcCenter radius:topRightRadius startAngle:M_PI * 3 / 2 endAngle:2 * M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius - YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomRightArcCenter radius:bottomRightRadius startAngle:0 endAngle:M_PI_2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(arrowHeight + bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) + YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomLeftArcCenter radius:bottomLeftRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES]; + + }else if (arrowDirection == YBPopupMenuArrowDirectionRight) { + topLeftArcCenter = CGPointMake(topLeftRadius + YBRectX(rect),topLeftRadius + YBRectX(rect)); + topRightArcCenter = CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect) - arrowHeight, topRightRadius + YBRectX(rect)); + bottomLeftArcCenter = CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) - bottomLeftRadius + YBRectX(rect)); + bottomRightArcCenter = CGPointMake(YBRectWidth(rect) - bottomRightRadius + YBRectX(rect) - arrowHeight, YBRectHeight(rect) - bottomRightRadius + YBRectX(rect)); + if (arrowPosition < topRightRadius + arrowWidth / 2) { + arrowPosition = topRightRadius + arrowWidth / 2; + }else if (arrowPosition > YBRectHeight(rect) - bottomRightRadius - arrowWidth / 2) { + arrowPosition = YBRectHeight(rect) - bottomRightRadius - arrowWidth / 2; + } + [bezierPath moveToPoint:CGPointMake(YBRectWidth(rect) - arrowHeight + YBRectX(rect), arrowPosition - arrowWidth / 2)]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) + YBRectX(rect), arrowPosition)]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - arrowHeight + YBRectX(rect), arrowPosition + arrowWidth / 2)]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - arrowHeight + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius - YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomRightArcCenter radius:bottomRightRadius startAngle:0 endAngle:M_PI_2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) + YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomLeftArcCenter radius:bottomLeftRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectX(rect), arrowHeight + topLeftRadius + YBRectX(rect))]; + [bezierPath addArcWithCenter:topLeftArcCenter radius:topLeftRadius startAngle:M_PI endAngle:M_PI * 3 / 2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect) - arrowHeight, YBRectX(rect))]; + [bezierPath addArcWithCenter:topRightArcCenter radius:topRightRadius startAngle:M_PI * 3 / 2 endAngle:2 * M_PI clockwise:YES]; + + }else if (arrowDirection == YBPopupMenuArrowDirectionNone) { + topLeftArcCenter = CGPointMake(topLeftRadius + YBRectX(rect), topLeftRadius + YBRectX(rect)); + topRightArcCenter = CGPointMake(YBRectWidth(rect) - topRightRadius + YBRectX(rect), topRightRadius + YBRectX(rect)); + bottomLeftArcCenter = CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) - bottomLeftRadius + YBRectX(rect)); + bottomRightArcCenter = CGPointMake(YBRectWidth(rect) - bottomRightRadius + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius + YBRectX(rect)); + [bezierPath moveToPoint:CGPointMake(topLeftRadius + YBRectX(rect), YBRectX(rect))]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) - topRightRadius, YBRectX(rect))]; + [bezierPath addArcWithCenter:topRightArcCenter radius:topRightRadius startAngle:M_PI * 3 / 2 endAngle:2 * M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectWidth(rect) + YBRectX(rect), YBRectHeight(rect) - bottomRightRadius - YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomRightArcCenter radius:bottomRightRadius startAngle:0 endAngle:M_PI_2 clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(bottomLeftRadius + YBRectX(rect), YBRectHeight(rect) + YBRectX(rect))]; + [bezierPath addArcWithCenter:bottomLeftArcCenter radius:bottomLeftRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES]; + [bezierPath addLineToPoint:CGPointMake(YBRectX(rect), arrowHeight + topLeftRadius + YBRectX(rect))]; + [bezierPath addArcWithCenter:topLeftArcCenter radius:topLeftRadius startAngle:M_PI endAngle:M_PI * 3 / 2 clockwise:YES]; + } + + [bezierPath closePath]; + return bezierPath; +} + +@end diff --git a/MRMobileRun/YBPopupMenu/YBRectConst.h b/MRMobileRun/YBPopupMenu/YBRectConst.h new file mode 100755 index 0000000..c2481d4 --- /dev/null +++ b/MRMobileRun/YBPopupMenu/YBRectConst.h @@ -0,0 +1,54 @@ +// +// YBRectMake.h +// YBPopupMenu +// +// Created by lyb on 2017/5/9. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import + +UIKIT_STATIC_INLINE CGFloat YBRectWidth(CGRect rect) +{ + return rect.size.width; +} + +UIKIT_STATIC_INLINE CGFloat YBRectHeight(CGRect rect) +{ + return rect.size.height; +} + +UIKIT_STATIC_INLINE CGFloat YBRectX(CGRect rect) +{ + return rect.origin.x; +} + +UIKIT_STATIC_INLINE CGFloat YBRectY(CGRect rect) +{ + return rect.origin.y; +} + +UIKIT_STATIC_INLINE CGFloat YBRectTop(CGRect rect) +{ + return rect.origin.y; +} + +UIKIT_STATIC_INLINE CGFloat YBRectBottom(CGRect rect) +{ + return rect.origin.y + rect.size.height; +} + +UIKIT_STATIC_INLINE CGFloat YBRectLeft(CGRect rect) +{ + return rect.origin.x; +} + +UIKIT_STATIC_INLINE CGFloat YBRectRight(CGRect rect) +{ + return rect.origin.x + rect.size.width; +} + + + + + diff --git a/MRMobileRun/YBPopupMenu/YBRectConst.m b/MRMobileRun/YBPopupMenu/YBRectConst.m new file mode 100755 index 0000000..1819b46 --- /dev/null +++ b/MRMobileRun/YBPopupMenu/YBRectConst.m @@ -0,0 +1,11 @@ +// +// YBRectMake.m +// YBPopupMenu +// +// Created by lyb on 2017/5/9. +// Copyright © 2017年 lyb. All rights reserved. +// + +#import "YBRectConst.h" + + diff --git a/MRMobileRun/main.m b/MRMobileRun/main.m index e939350..06bc447 100644 --- a/MRMobileRun/main.m +++ b/MRMobileRun/main.m @@ -10,6 +10,9 @@ int main(int argc, char * argv[]) { @autoreleasepool { + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"MoreIsFirst"]; + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"MineIsFirst"]; + [[NSUserDefaults standardUserDefaults] synchronize]; return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } diff --git a/MRRunning/Impact.ttf b/MRRunning/Impact.ttf new file mode 100644 index 0000000..8f6da36 Binary files /dev/null and b/MRRunning/Impact.ttf differ diff --git a/MRRunning/LongPressView.h b/MRRunning/LongPressView.h new file mode 100644 index 0000000..0d1519c --- /dev/null +++ b/MRRunning/LongPressView.h @@ -0,0 +1,28 @@ +// +// LongPressView.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/20. +// + + +#import + +NS_ASSUME_NONNULL_BEGIN + +//解锁、结束时长按手势的解锁,配上slider的颜色 + +@interface LongPressView : UIView +@property (nonatomic, strong)UIImageView *imgView; +@property (nonatomic, strong)UILabel *titleLbl; +@property (nonatomic, strong)UIView *bgView; + +@property (nonatomic, strong)UIColor *sideColor; +@property (nonatomic,strong) CAShapeLayer *arcLayer; + +- (void)initLongPressView; +- (void)addTarget:(id)target select:(SEL)selectAction; +- (void)stopDraw; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/LongPressView.m b/MRRunning/LongPressView.m new file mode 100644 index 0000000..fe408bb --- /dev/null +++ b/MRRunning/LongPressView.m @@ -0,0 +1,124 @@ +// +// LongPressView.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/20. +// + +#import "LongPressView.h" +#import +#define DEGREES_TO_RADOANS(x) (M_PI * (x) / 180.0) // 将角度转为弧度 + +@interface LongPressView() +{ + SEL _action; +} +@property (unsafe_unretained,nonatomic) id target; +@end + +@implementation LongPressView + +- (void)initLongPressView{ + //背景色(深色模式适配) + if (@available(iOS 11.0, *)) { + self.backgroundColor = WhiteColor; + } else { + // Fallback on earlier versions + } + + self.sideColor = [UIColor colorWithRed:123/255.0 green:183/255.0 blue:196/255.0 alpha:1.0]; + + //中心背景的颜色 + self.bgView = [[UIView alloc] init]; + [self addSubview:self.bgView]; + [self.bgView mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self); + make.size.mas_equalTo(CGSizeMake(90, 90)); + }]; + //将其设置为原型 + self.bgView.layer.cornerRadius = 45; + self.bgView.layer.masksToBounds = 45 ? YES : NO; + + + self.imgView = [[UIImageView alloc] init]; + [self.bgView addSubview:self.imgView]; + [self.imgView mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self); + make.size.mas_equalTo(CGSizeMake(30, 30)); + }]; + + self.titleLbl = [[UILabel alloc] init]; + [self.bgView addSubview:self.titleLbl]; + [self.titleLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.imgView); + make.top.equalTo(self.imgView.mas_bottom); + make.size.mas_equalTo(CGSizeMake(70, 17)); + }]; + self.titleLbl.textAlignment = NSTextAlignmentCenter; + self.titleLbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + +} + +//让这个View可以添加目标,实现方法 +- (void)addTarget:(id)target select:(SEL)selectAction{ + _target = target; + _action = selectAction; +} + +//绘制长按时边缘的动画 +- (void)drawRoundView:(CGPoint)centerPoint withStartAngle:(CGFloat)startAngle withEndAngle:(CGFloat)endAngle withRadius:(CGFloat)radius { + + UIBezierPath *path = [UIBezierPath bezierPath]; + [path addArcWithCenter:centerPoint radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; + _arcLayer = [CAShapeLayer layer]; + _arcLayer.strokeColor = self.sideColor.CGColor; + _arcLayer.fillColor = [UIColor clearColor].CGColor; + _arcLayer.path = path.CGPath; + + _arcLayer.lineWidth = 6; + _arcLayer.frame = self.bounds; + [self.layer addSublayer:_arcLayer]; + + + CABasicAnimation *bas = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + bas.duration = 1; + bas.fromValue = [NSNumber numberWithInteger:0]; + bas.toValue = [NSNumber numberWithInteger:1]; + bas.removedOnCompletion = NO; + bas.delegate = self; + [_arcLayer addAnimation:bas forKey:@"key"]; +} + +// 核心动画结束 +- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { + if (flag) + { + [_target performSelector:_action withObject:nil afterDelay:0.0]; + } +} + +//开始绘制 +- (void)startDrawRound{ + [self drawRoundView:CGPointMake(self.frame.size.width/2, self.frame.size.height/2) withStartAngle:DEGREES_TO_RADOANS(-90) withEndAngle:DEGREES_TO_RADOANS(270) withRadius:self.frame.size.height/2-1]; + +} + +//结束绘制 +- (void)stopDraw{ + if (_arcLayer) { + [_arcLayer removeAllAnimations]; + [_arcLayer removeFromSuperlayer]; + _arcLayer = nil; + } +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ + [self startDrawRound]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ + [self stopDraw]; +} + + +@end diff --git a/MRRunning/MASmoothPathTool.h b/MRRunning/MASmoothPathTool.h new file mode 100644 index 0000000..1d3428d --- /dev/null +++ b/MRRunning/MASmoothPathTool.h @@ -0,0 +1,65 @@ +// +// MASmoothPathTool.h +// iOS-path-smooth +// +// Created by shaobin on 2017/10/12. +// Copyright © 2017年 autonavi. All rights reserved. +// + +#import +/* +为处理轨迹使轨迹平滑而用到的工具类 + +高斯去噪、卡尔曼滤波、抽稀算法 + 该ios demo 网址:https://github.com/amap-demo/iOS-path-smooth +*/ + +@interface MALonLatPoint : NSObject +@property (nonatomic, assign) double lat; +@property (nonatomic, assign) double lon; +@end + +@interface MASmoothPathTool : NSObject + +@property (nonatomic, assign) int intensity; +@property (nonatomic, assign) float threshHold; +@property (nonatomic, assign) int noiseThreshhold; + +/** + * 轨迹平滑优化 + * @param originlist 原始轨迹list,list.size大于2 + * @return 优化后轨迹list + */ +- (NSArray*)pathOptimize:(NSArray*)originlist; + +/** + * 轨迹线路滤波 + * @param originlist 原始轨迹list,list.size大于2 + * @return 滤波处理后的轨迹list + */ +- (NSArray*)kalmanFilterPath:(NSArray*)originlist; + + +/** + * 轨迹去噪,删除垂距大于20m的点 + * @param originlist 原始轨迹list,list.size大于2 + * @return 去燥后的list + */ +- (NSArray*)removeNoisePoint:(NSArray*)originlist; + +/** + * 单点滤波 + * @param lastLoc 上次定位点坐标 + * @param curLoc 本次定位点坐标 + * @return 滤波后本次定位点坐标值 + */ +- (MALonLatPoint*)kalmanFilterPoint:(MALonLatPoint*)lastLoc curLoc:(MALonLatPoint*)curLoc; + +/** + * 轨迹抽稀 + * @param inPoints 待抽稀的轨迹list,至少包含两个点,删除垂距小于mThreshhold的点 + * @return 抽稀后的轨迹list + */ +- (NSArray*)reducerVerticalThreshold:(NSArray*)inPoints; + +@end diff --git a/MRRunning/MASmoothPathTool.m b/MRRunning/MASmoothPathTool.m new file mode 100644 index 0000000..6430ea0 --- /dev/null +++ b/MRRunning/MASmoothPathTool.m @@ -0,0 +1,299 @@ +// +// MASmoothPathTool.m +// iOS-path-smooth +// +// Created by shaobin on 2017/10/12. +// Copyright © 2017年 autonavi. All rights reserved. +// + + +#import "MASmoothPathTool.h" +#import + + +@implementation MALonLatPoint +@end + +@implementation MASmoothPathTool +{ + double lastLocation_x; //上次位置 + double currentLocation_x;//这次位置 + double lastLocation_y; //上次位置 + double currentLocation_y;//这次位置 + double estimate_x; //修正后数据 + double estimate_y; //修正后数据 + double pdelt_x; //自预估偏差 + double pdelt_y; //自预估偏差 + double mdelt_x; //上次模型偏差 + double mdelt_y; //上次模型偏差 + double gauss_x; //高斯噪音偏差 + double gauss_y; //高斯噪音偏差 + double kalmanGain_x; //卡尔曼增益 + double kalmanGain_y; //卡尔曼增益 + + double m_R; + double m_Q; +} + +- (id)init { + self = [super init]; + + if(self) { + self.intensity = 3; + self.threshHold = 0.3f; + self.noiseThreshhold = 10; + } + + return self; +} +/** + * 轨迹平滑优化 + * @param originlist 原始轨迹list,list.size大于2 + * @return 优化后轨迹list + */ +- (NSArray*)pathOptimize:(NSArray*)originlist { + + NSArray* list = [self removeNoisePoint:originlist];//去噪 + NSArray* afterList = [self kalmanFilterPath:list intensity:self.intensity];//滤波 + NSArray* pathoptimizeList = [self reducerVerticalThreshold:afterList threshHold:self.threshHold];//抽稀 + return pathoptimizeList; +} + +/** + * 轨迹线路滤波 + * @param originlist 原始轨迹list,list.size大于2 + * @return 滤波处理后的轨迹list + */ +- (NSArray*)kalmanFilterPath:(NSArray*)originlist { + return [self kalmanFilterPath:originlist intensity:self.intensity]; +} + + +/** + * 轨迹去噪,删除垂距大于20m的点 + * @param originlist 原始轨迹list,list.size大于2 + * @return 去燥后的list + */ +- (NSArray*)removeNoisePoint:(NSArray*)originlist{ + return [self reduceNoisePoint:originlist threshHold:self.noiseThreshhold]; +} + +/** + * 单点滤波 + * @param lastLoc 上次定位点坐标 + * @param curLoc 本次定位点坐标 + * @return 滤波后本次定位点坐标值 + */ +- (MALonLatPoint*)kalmanFilterPoint:(MALonLatPoint*)lastLoc curLoc:(MALonLatPoint*)curLoc { + return [self kalmanFilterPoint:lastLoc curLoc:curLoc intensity:self.intensity]; +} + +/** + * 轨迹抽稀 + * @param inPoints 待抽稀的轨迹list,至少包含两个点,删除垂距小于mThreshhold的点 + * @return 抽稀后的轨迹list + */ +- (NSArray*)reducerVerticalThreshold:(NSArray*)inPoints { + return [self reducerVerticalThreshold:inPoints threshHold:self.threshHold]; +} + +/********************************************************************************************************/ +/** + * 轨迹线路滤波 + * @param originlist 原始轨迹list,list.size大于2 + * @param intensity 滤波强度(1—5) + * @return 滤波后的list + */ +- (NSArray*)kalmanFilterPath:(NSArray*)originlist intensity:(int)intensity { + if (!originlist || originlist.count <= 2) { + return nil; + } + + NSMutableArray* kalmanFilterList = [NSMutableArray array]; + + [self initial];//初始化滤波参数 + + MALonLatPoint* point = nil; + MALonLatPoint* lastLoc = [[MALonLatPoint alloc] init]; + lastLoc.lat = [originlist objectAtIndex:0].lat; + lastLoc.lon = [originlist objectAtIndex:0].lon; + [kalmanFilterList addObject:lastLoc]; + + for (int i = 1; i < originlist.count; i++) { + MALonLatPoint* curLoc = [originlist objectAtIndex:i]; + point = [self kalmanFilterPoint:lastLoc curLoc:curLoc intensity:intensity]; + if (point) { + [kalmanFilterList addObject:point]; + lastLoc = point; + } + } + return kalmanFilterList; +} + +/** + * 单点滤波 + * @param lastLoc 上次定位点坐标 + * @param curLoc 本次定位点坐标 + * @param intensity 滤波强度(1—5) + * @return 滤波后本次定位点坐标值 + */ +- (MALonLatPoint*)kalmanFilterPoint:(MALonLatPoint*)lastLoc curLoc:(MALonLatPoint*)curLoc intensity:(int)intensity { + if (!lastLoc || !curLoc){ + return nil; + } + + if (pdelt_x == 0 || pdelt_y == 0 ){ + [self initial]; + } + + MALonLatPoint* point = nil; + if (intensity < 1){ + intensity = 1; + } else if (intensity > 5){ + intensity = 5; + } + for (int j = 0; j < intensity; j++){ + point = [self kalmanFilter:lastLoc.lon value_x:curLoc.lon oldValue_y:lastLoc.lat value_y:curLoc.lat]; + curLoc = point; + } + return point; +} + + +/***************************卡尔曼滤波开始********************************/ + +//初始模型 +- (void)initial { + pdelt_x = 0.001; + pdelt_y = 0.001; + // mdelt_x = 0; + // mdelt_y = 0; + mdelt_x = 5.698402909980532E-4; + mdelt_y = 5.698402909980532E-4; +} + +- (MALonLatPoint*)kalmanFilter:(double)oldValue_x value_x:(double)value_x oldValue_y:(double)oldValue_y value_y:(double)value_y{ + lastLocation_x = oldValue_x; + currentLocation_x= value_x; + + gauss_x = sqrt(pdelt_x * pdelt_x + mdelt_x * mdelt_x)+m_Q; //计算高斯噪音偏差 + kalmanGain_x = sqrt((gauss_x * gauss_x)/(gauss_x * gauss_x + pdelt_x * pdelt_x)) +m_R; //计算卡尔曼增益 + estimate_x = kalmanGain_x * (currentLocation_x - lastLocation_x) + lastLocation_x; //修正定位点 + mdelt_x = sqrt((1-kalmanGain_x) * gauss_x *gauss_x); //修正模型偏差 + + lastLocation_y = oldValue_y; + currentLocation_y = value_y; + gauss_y = sqrt(pdelt_y * pdelt_y + mdelt_y * mdelt_y)+m_Q; //计算高斯噪音偏差 + kalmanGain_y = sqrt((gauss_y * gauss_y)/(gauss_y * gauss_y + pdelt_y * pdelt_y)) +m_R; //计算卡尔曼增益 + estimate_y = kalmanGain_y * (currentLocation_y - lastLocation_y) + lastLocation_y; //修正定位点 + mdelt_y = sqrt((1-kalmanGain_y) * gauss_y * gauss_y); //修正模型偏差 + + MALonLatPoint *point = [[MALonLatPoint alloc] init]; + point.lon = estimate_x; + point.lat = estimate_y; + + return point; +} +/***************************卡尔曼滤波结束**********************************/ + +/***************************抽稀算法*************************************/ +- (NSArray*)reducerVerticalThreshold:(NSArray*)inPoints threshHold:(float)threshHold { + if(inPoints.count < 2) { + return inPoints; + } + + NSMutableArray *ret = [NSMutableArray arrayWithCapacity:inPoints.count]; + + for(int i = 0; i < inPoints.count; ++i) { + MALonLatPoint *pre = ret.lastObject; + MALonLatPoint *cur = [inPoints objectAtIndex:i]; + + + if (!pre || i == inPoints.count - 1) { + [ret addObject:[inPoints objectAtIndex:i]]; + continue; + } + + MALonLatPoint *next = [inPoints objectAtIndex:(i + 1)]; + + MAMapPoint curP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(cur.lat, cur.lon)); + MAMapPoint prevP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(pre.lat, pre.lon)); + MAMapPoint nextP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(next.lat, next.lon)); + double distance = [self calculateDistanceFromPoint:curP lineBegin:prevP lineEnd:nextP]; + if (distance >= threshHold) { + [ret addObject:cur]; + } + } + + return ret; +} + +- (MALonLatPoint*)getLastLocation:(NSArray*)oneGraspList { + if (!oneGraspList || oneGraspList.count == 0) { + return nil; + } + NSInteger locListSize = oneGraspList.count; + MALonLatPoint* lastLocation = [oneGraspList objectAtIndex:(locListSize - 1)]; + return lastLocation; +} + +/** + * 计算当前点到线的垂线距离 + * @param pt 当前点 + * @param begin 线的起点 + * @param end 线的终点 + * + */ +- (double)calculateDistanceFromPoint:(MAMapPoint)pt + lineBegin:(MAMapPoint)begin + lineEnd:(MAMapPoint)end { + + MAMapPoint mappedPoint; + double dx = begin.x - end.x; + double dy = begin.y - end.y; + if(fabs(dx) < 0.00000001 && fabs(dy) < 0.00000001 ) { + mappedPoint = begin; + } else { + double u = (pt.x - begin.x)*(begin.x - end.x) + + (pt.y - begin.y)*(begin.y - end.y); + u = u/((dx*dx)+(dy*dy)); + + mappedPoint.x = begin.x + u*dx; + mappedPoint.y = begin.y + u*dy; + } + + return MAMetersBetweenMapPoints(pt, mappedPoint); +} +/***************************抽稀算法结束*********************************/ + +- (NSArray*)reduceNoisePoint:(NSArray*)inPoints threshHold:(float)threshHold { + if (!inPoints) { + return nil; + } + if (inPoints.count <= 2) { + return inPoints; + } + + NSMutableArray* ret = [NSMutableArray array]; + for (int i = 0; i < inPoints.count; i++) { + MALonLatPoint* pre = [self getLastLocation:ret]; + MALonLatPoint* cur = [inPoints objectAtIndex:i]; + if (!pre || i == inPoints.count - 1) { + [ret addObject:cur]; + continue; + } + MALonLatPoint* next = [inPoints objectAtIndex:(i + 1)]; + + MAMapPoint curP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(cur.lat, cur.lon)); + MAMapPoint prevP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(pre.lat, pre.lon)); + MAMapPoint nextP = MAMapPointForCoordinate(CLLocationCoordinate2DMake(next.lat, next.lon)); + double distance = [self calculateDistanceFromPoint:curP lineBegin:prevP lineEnd:nextP]; + if (distance < threshHold){ + [ret addObject:cur]; + } + } + return ret; +} + + +@end diff --git a/MRRunning/MGDButtonsView.h b/MRRunning/MGDButtonsView.h new file mode 100644 index 0000000..cdeab5e --- /dev/null +++ b/MRRunning/MGDButtonsView.h @@ -0,0 +1,22 @@ +// +// MGDButtonsView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDButtonsView : UIView +//背景view +@property (nonatomic, strong) UIView *backView; +//完成按钮 +@property (nonatomic, strong) UIButton *overBtn; +//分享按钮 +@property (nonatomic, strong) UIButton *shareBtn; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/MGDButtonsView.m b/MRRunning/MGDButtonsView.m new file mode 100644 index 0000000..c8b8239 --- /dev/null +++ b/MRRunning/MGDButtonsView.m @@ -0,0 +1,82 @@ +// +// MGDButtonsView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + +#import "MGDButtonsView.h" +#import + +//页面底部的buttonView,完成和分享按钮,两个按钮的点击事件在ViewController中来写 + +@implementation MGDButtonsView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + _backView = [[UIView alloc] init]; + _backView.backgroundColor = [UIColor clearColor]; + _backView.userInteractionEnabled = YES; + [self addSubview:_backView]; + + _overBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + _overBtn.layer.cornerRadius = 12; + //测试颜色 + [_overBtn setBackgroundColor:[UIColor colorWithRed:100/255.0 green:104/255.0 blue:111/255.0 alpha:1.0]]; + [_overBtn setTitle:@"完成" forState:UIControlStateNormal]; + [self.backView addSubview:_overBtn]; + + _shareBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + _shareBtn.layer.cornerRadius = 12; + //测试颜色 + [_shareBtn setBackgroundColor:[UIColor colorWithRed:85/255.0 green:213/255.0 blue:226/255.0 alpha:1.0]]; + [_shareBtn setTitle:@"分享" forState:UIControlStateNormal]; + [_shareBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [self.backView addSubview:_shareBtn]; + + + if (@available(iOS 11.0, *)) { + [self.overBtn setTitleColor:OverColor forState:UIControlStateNormal]; + [self.overBtn setBackgroundColor:OverBackColor]; + } else { + // Fallback on earlier versions + } + } + return self; +} + +- (void)layoutSubviews { + if (kIs_iPhoneX) { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.equalTo(@100); + }]; + }else { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.equalTo(@66); + }]; + } + + [_overBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(10); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(18); + make.width.equalTo(@164); + make.height.equalTo(@44); + }]; + + [_shareBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.overBtn); + make.right.mas_equalTo(self.mas_right).mas_offset(-18); + make.width.mas_equalTo(self.overBtn); + make.height.mas_equalTo(self.overBtn); + }]; +} + + + +@end diff --git a/MRRunning/MGDCellDataViewController.h b/MRRunning/MGDCellDataViewController.h new file mode 100644 index 0000000..d332061 --- /dev/null +++ b/MRRunning/MGDCellDataViewController.h @@ -0,0 +1,49 @@ +// +// MGDCellDataViewController.h +// MRMobileRun +// +// Created by 阿栋 on 2020/8/13. +// + +#import +#import "MGDOverView.h" +#import "MGDDataView.h" +#import "MGDButtonsView.h" +#import "MGDShareView.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDCellDataViewController : UIViewController + +@property (nonatomic, strong) NSString *distanceStr; //距离 +@property (nonatomic, strong) NSString *speedStr; //配速 +@property (nonatomic, strong) NSString *stepFrequencyStr; //步频 +@property (nonatomic, strong) NSString *timeStr; //跑步时间 +@property (nonatomic, strong) NSString *energyStr;//千卡 +@property (nonatomic, strong) NSString *date; //日期 +@property (nonatomic, strong) NSString *time; //时间 +@property (nonatomic, strong) NSString *MaxStepFrequency; //最大步频 +@property (nonatomic, strong) NSString *MaxSpeed; //最大速度 +@property (nonatomic, strong) NSString *degree; //温度 + + +@property (nonatomic, strong) NSArray *locationAry; //首页中采集到的所有定位点的数据 +@property (nonatomic, strong) NSArray *drawLineAry; //首页中采集到的所有用来绘制轨迹的数据 + +@property (nonatomic, strong) NSArray *speedArray; //速度数组 +@property (nonatomic, strong) NSArray *stepFrequencyArray; //步频数组 + + +@property (nonatomic ,strong) UIScrollView *backScrollView; + +@property (nonatomic ,strong) MGDOverView *overView; + +@property (nonatomic ,strong) MGDDataView *dataView; + +@property (nonatomic ,strong) MGDButtonsView *twoBtnView; + +@property (nonatomic ,strong) MGDShareView *shareView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/MGDCellDataViewController.m b/MRRunning/MGDCellDataViewController.m new file mode 100644 index 0000000..665888e --- /dev/null +++ b/MRRunning/MGDCellDataViewController.m @@ -0,0 +1,300 @@ +// +// MGDCellDataViewController.m +// MRMobileRun +// +// Created by 阿栋 on 2020/8/13. +// + +#import "MGDCellDataViewController.h" +#import +#import +#import +#import +#import +#import +#import +#import + +#import "MGDDataViewController.h" +#import "RunLocationModel.h" +#import "MASmoothPathTool.h" +#import "UIImageView+WebCache.h" +#import "ZYLMainViewController.h" +#import "MRTabBarController.h" + +@interface MGDCellDataViewController () +@property (nonatomic, strong) AMapLocationManager *ALocationManager; +@property (nonatomic, strong) NSArray *origTracePoints; //原始轨迹测绘坐标点 +@property (nonatomic, strong) NSArray *smoothedTracePoints; //平滑处理用的轨迹数组点 +@property (nonatomic, strong) MAPolyline *smoothedTrace; + +//大头针 +@property (nonatomic, strong) MAPointAnnotation *beginAnnotataion; +@property (nonatomic, strong) MAPointAnnotation *endAnnotataion; + +@property __block UIImage *shareImage; +@end + +@implementation MGDCellDataViewController + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"hideTabBar" object:nil]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self.navigationController setNavigationBarHidden:YES animated:YES]; //隐藏导航栏 + [self fit]; + [self initLocationManager]; + + self.overView.kmLab.text = self.distanceStr; //跑步距离赋值 + self.overView.speedLab.text = self.speedStr; //配速赋值 + /* + 步频未弄出来,暂时先空缺着 + */ + self.overView.timeLab.text = self.timeStr; //跑步时间赋值 + self.overView.calLab.text = self.energyStr; //燃烧千卡赋值 + self.overView.paceLab.text = self.stepFrequencyStr; //步频 + self.overView.date.text = self.date; //日期 + self.overView.currentTime.text = self.time; //时间 + self.overView.degree.text = self.degree; //温度 + self.dataView.speedLab.text = self.MaxSpeed; //最大速度 + self.dataView.paceLab.text = self.MaxStepFrequency; //最大步频 + self.overView.mapView.delegate = self; + +/* +绘制轨迹 + */ + [self loadTrancePoints]; + [self initSmoothedTrace]; + + /* + 自定义始终位置的大头针 + */ + //开始地点 + MAPointAnnotation *beginAnnotation = [[MAPointAnnotation alloc] init]; + RunLocationModel *beginLocation = self.locationAry.firstObject; + beginAnnotation.coordinate = beginLocation.location; + self.beginAnnotataion = beginAnnotation; + [self.overView.mapView addAnnotation:self.beginAnnotataion]; + //结束地点 + MAPointAnnotation *endAnnotation = [[MAPointAnnotation alloc] init]; + RunLocationModel *endLocation = self.locationAry.lastObject; + endAnnotation.coordinate = endLocation.location; + self.endAnnotataion = endAnnotation; + [self.overView.mapView addAnnotation:self.endAnnotataion]; + + // 给分享界面添加手势 + UITapGestureRecognizer *backGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(backevent:)]; + backGesture.delegate = self; + [self.shareView.backView addGestureRecognizer:backGesture]; + + + + +} + //适配各个View的深色模式以及页面布局 +- (void)fit{ + //适配深色模式 + _backScrollView = [[UIScrollView alloc] init]; + if (@available(iOS 11.0, *)) { + self.view.backgroundColor = bottomColor; + _backScrollView.contentInsetAdjustmentBehavior = UIApplicationBackgroundFetchIntervalNever; + } else { + // Fallback on earlier versions + } + + //根据机型进行控件布局 + if (kIs_iPhoneX) { + _backScrollView.frame = CGRectMake(0, 0, screenWidth, screenHeigth - 100); + _twoBtnView = [[MGDButtonsView alloc] initWithFrame:CGRectMake(0, screenHeigth - 100, screenWidth, 100)]; + _dataView = [[MGDDataView alloc] initWithFrame:CGRectMake(0, screenHeigth - 100 + 10, screenWidth, 710)]; + }else { + _backScrollView.frame = CGRectMake(0, 0, screenWidth, screenHeigth - 66); + _twoBtnView = [[MGDButtonsView alloc] initWithFrame:CGRectMake(0, screenHeigth - 66, screenWidth, 66)]; + _dataView = [[MGDDataView alloc] initWithFrame:CGRectMake(0, screenHeigth - 66 + 10, screenWidth, 710)]; + + } + + //两个butto的View + [_twoBtnView.overBtn addTarget:self action:@selector(Back) forControlEvents:UIControlEventTouchUpInside]; + [_twoBtnView.shareBtn addTarget:self action:@selector(share) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:_twoBtnView]; + _backScrollView.contentSize = CGSizeMake(screenWidth, 1432); + [self.view addSubview:_backScrollView]; + + //地图下,统计图上的View,配速、时间、燃烧千卡等label的数据 + _overView = [[MGDOverView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeigth)]; + [self.backScrollView addSubview:_overView]; + + //绘制统计图的View + [self.backScrollView addSubview:_dataView]; +} + +- (void)Back{ + // [self.navigationController ]; + + [self.navigationController popViewControllerAnimated:YES]; +} + +- (void)share { + _shareView = [[MGDShareView alloc] initWithShotImage:@"" logoImage:@"" QRcodeImage:@""]; + [self.view addSubview:_shareView]; + [_shareView.cancelBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; + [self shareAction]; + // 分享界面的地图截图 + CGRect inRect = self.overView.mapView.frame; + [self.overView.mapView takeSnapshotInRect:inRect withCompletionBlock:^(UIImage *resultImage, NSInteger state) { + state = 1; + self.shareImage = resultImage; + self.shareView.shotImage.image = self.shareImage; + }]; +} + +- (void)backevent:(UIGestureRecognizer *)sender { + NSLog(@"1111"); +} + + +- (void)back { + [UIView animateWithDuration:0.3 animations:^{ + [self.shareView removeFromSuperview]; + }]; +} + +#pragma mark- 位置管理者 +- (void)initLocationManager{ + self.ALocationManager = [[AMapLocationManager alloc] init]; + self.ALocationManager.delegate = self; + self.ALocationManager.allowsBackgroundLocationUpdates = YES; //开启后台定位 + self.ALocationManager.distanceFilter = 5; //设置移动精度 + self.ALocationManager.locationTimeout = 2; //定位超时时间 + [self.ALocationManager setLocatingWithReGeocode:YES]; + [self.ALocationManager startUpdatingLocation]; +} + +#pragma mark- 轨迹相关 + //因为CLLocationCoordinate2D为只读属性,无法用可变数组直接addobject储存,所以需要以下转化 +- (void)loadTrancePoints{ + NSMutableArray *muteableAry = [NSMutableArray array]; + // CLLocationCoordinate2D linePoints[self.drawLineAry.count]; + for (int i = 0; i < self.drawLineAry.count; i++) { + RunLocationModel *lineLocationModel = self.drawLineAry[i]; + // linePoints[i] = lineLocationModel.location; + MALonLatPoint *point = [[MALonLatPoint alloc] init]; + point.lat = lineLocationModel.location.latitude; + point.lon = lineLocationModel.location.longitude; + } + self.origTracePoints = muteableAry; +} + +//处理、绘制轨迹线 +- (void)initSmoothedTrace{ + MASmoothPathTool *tool = [[MASmoothPathTool alloc] init]; + tool.intensity = 3; + tool.threshHold = 0.3; + tool.noiseThreshhold = 10; + self.smoothedTracePoints = [tool pathOptimize:self.origTracePoints]; + + CLLocationCoordinate2D *pCoords = malloc(sizeof(CLLocationCoordinate2D) * self.smoothedTracePoints.count); + if(!pCoords) { + return; + } + + for(int i = 0; i < self.smoothedTracePoints.count; ++i) { + MALonLatPoint *p = [self.smoothedTracePoints objectAtIndex:i]; + CLLocationCoordinate2D *pCur = pCoords + i; + pCur->latitude = p.lat; + pCur->longitude = p.lon; + } + + self.smoothedTrace = [MAPolyline polylineWithCoordinates:pCoords count:self.smoothedTracePoints.count]; + [self.overView.mapView addOverlay:self.smoothedTrace]; + if(pCoords) { + free(pCoords); + } + +} + +//自定义轨迹线 +- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id)overlay{ + if ([overlay isKindOfClass:[MAPolyline class]]) { + MAPolylineRenderer *polyLineRender = [[MAPolylineRenderer alloc] initWithPolyline:overlay]; + polyLineRender.lineWidth = 8; + polyLineRender.strokeColor = [UIColor colorWithRed:123/255.0 green:183/255.0 blue:196/255.0 alpha:1.0]; //折线颜色 + } + return nil; +} + +#pragma mark- 自定义大头针 +- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation{ + if ([annotation isKindOfClass:[MAPointAnnotation class]]){ + if (annotation == self.beginAnnotataion) { + MAPinAnnotationView *annotationView = [[MAPinAnnotationView alloc] init]; + annotationView.image = [UIImage imageNamed:@"startPointImage"]; + annotationView.animatesDrop = NO; + return annotationView; + }else if (annotation == self.endAnnotataion){ + MAPinAnnotationView *annotationView = [[MAPinAnnotationView alloc] init]; + annotationView.image = [UIImage imageNamed:@"endPointImage"]; + annotationView.animatesDrop = NO; + return annotationView; + } + } + return nil; +} + +#pragma mark- 定位回调方法 +- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation{ + CGFloat signal = userLocation.location.horizontalAccuracy; + + if(!updatingLocation) + return ; + + if (signal < 0) + { + return ; + } +} + +- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode{ + CGFloat signal = location.horizontalAccuracy; + if (signal < 0) + { + return ; + } +} + +#pragma mark- 分享的五个按钮的方法 +- (void)shareAction{ + for (int i = 0; i < self.shareView.bootomBtns.count; i++) { + UIButton *btn = [self.shareView.bootomBtns objectAtIndex:i]; + switch (btn.tag) { + case 1: + [btn addTarget:self action:@selector(savePhotoAtLocalAlbum) forControlEvents:UIControlEventTouchUpInside]; + break; + + default: + break; + } + } +} + +//保存截图到本地 +- (void)savePhotoAtLocalAlbum{ + CGRect inRect = self.overView.mapView.frame; + [self.overView.mapView takeSnapshotInRect:inRect withCompletionBlock:^(UIImage *resultImage, NSInteger state) { + state = 1; + + }]; +} +#pragma mark-关于两个位置管理者的定位代理方法:实现后台定位 + +- (void)amapLocationManager:(AMapLocationManager *)manager doRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} +- (void)mapViewRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} +@end diff --git a/MRRunning/MGDDataView.h b/MRRunning/MGDDataView.h new file mode 100644 index 0000000..ea15b34 --- /dev/null +++ b/MRRunning/MGDDataView.h @@ -0,0 +1,37 @@ +// +// MGDDataView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDDataView : UIView +//这个文件是两个图表,速度和步频,大的UIView套上两个小的UIView + +//文字 +@property (nonatomic, strong) UILabel *pace; +@property (nonatomic, strong) UILabel *speed; +@property (nonatomic, strong) UILabel *paceLab; +@property (nonatomic, strong) UILabel *speedLab; +@property (nonatomic, strong) UILabel *descSpeed; +@property (nonatomic, strong) UILabel *descPace; +//圆点 +@property (nonatomic, strong) UIView *speedDotView; +@property (nonatomic, strong) UIView *paceDotView; + +//整体背景 +@property (nonatomic, strong) UIView *backView; + +//速度背景View +@property (nonatomic, strong) UIView *speedBackView; + +//步频背景View +@property (nonatomic, strong) UIView *paceBackView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/MGDDataView.m b/MRRunning/MGDDataView.m new file mode 100644 index 0000000..c8021f9 --- /dev/null +++ b/MRRunning/MGDDataView.m @@ -0,0 +1,188 @@ +// +// MGDDataView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + +#import "MGDDataView.h" +#import +#define DOTCOLOR [UIColor colorWithRed:123/255.0 green:183/255.0 blue:196/255.0 alpha:1.0] +#define DESCCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] + +@implementation MGDDataView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + + //整体View + _backView = [[UIView alloc] init]; + _backView.backgroundColor = [UIColor clearColor]; + [self addSubview:_backView]; + + //速度View + _speedBackView = [[UIView alloc] init]; + _speedBackView.backgroundColor = [UIColor clearColor]; + [self.backView addSubview:_speedBackView]; + + //速度View上的控件 + _speedDotView = [[UIView alloc] init]; + _speedDotView.backgroundColor = DOTCOLOR; + _speedDotView.layer.masksToBounds = YES; + _speedDotView.layer.cornerRadius = 4.0; + [self.speedBackView addSubview:_speedDotView]; + + _speed = [[UILabel alloc] init]; + _speed.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _speed.textAlignment = NSTextAlignmentLeft; + _speed.text = @"速度"; + [self.speedBackView addSubview:_speed]; + + _speedLab = [[UILabel alloc] init]; + _speedLab.font = [UIFont fontWithName:@"Impact" size: 28]; + _speedLab.textAlignment = NSTextAlignmentCenter; + [self.speedBackView addSubview:_speedLab]; + + _descSpeed = [[UILabel alloc] init]; + _descSpeed.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 11]; + _descSpeed.textAlignment = NSTextAlignmentCenter; + _descSpeed.tintColor = DESCCOLOR; + _descSpeed.text = @"最快速度"; + [self.speedBackView addSubview:_descSpeed]; + + //步频View + _paceBackView = [[UIView alloc] init]; + _paceBackView.backgroundColor = [UIColor clearColor]; + [self.backView addSubview:_paceBackView]; + + //步频View上的控件 + _paceDotView = [[UIView alloc] init]; + _paceDotView.backgroundColor = DOTCOLOR; + _paceDotView.layer.masksToBounds = YES; + _paceDotView.layer.cornerRadius = 4.0; + [self.paceBackView addSubview:_paceDotView]; + + _pace = [[UILabel alloc] init]; + _pace.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _pace.textAlignment = NSTextAlignmentLeft; + _pace.text = @"步频"; + [self.paceBackView addSubview:_pace]; + + _paceLab = [[UILabel alloc] init]; + _paceLab.font = [UIFont fontWithName:@"Impact" size: 28]; + _paceLab.textAlignment = NSTextAlignmentCenter; + [self.paceBackView addSubview:_paceLab]; + + _descPace = [[UILabel alloc] init]; + _descPace.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 11]; + _descPace.textAlignment = NSTextAlignmentCenter; + _descPace.text = @"最高步频"; + _descPace.tintColor = DESCCOLOR; + [self.paceBackView addSubview:_descPace]; + + //颜色适配 + if (@available(iOS 11.0, *)) { + self.speedLab.tintColor = bottomTitleColor; + self.paceLab.tintColor = bottomTitleColor; + self.pace.tintColor = bottomTitleColor; + self.speed.tintColor = bottomTitleColor; + } else { + // Fallback on earlier versions + } + + [self test]; + + } + return self; +} + +//位置约束 +- (void)layoutSubviews { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.equalTo(@699); + }]; + + + [_paceBackView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.equalTo(@308); + }]; + + [_speedBackView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.paceBackView.mas_bottom).offset(50); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.equalTo(@308); + }]; + + [_speedDotView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedBackView.mas_top).mas_offset(7); + make.left.mas_equalTo(self.speedBackView.mas_left).mas_offset(15); + make.width.equalTo(@8); + make.height.equalTo(@8); + }]; + + [_speed mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedBackView.mas_top); + make.left.mas_equalTo(self.speedBackView.mas_left).mas_offset(29); + make.width.equalTo(@32); + make.height.equalTo(@22); + }]; + + [_speedLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.mas_equalTo(self.speedBackView.mas_left).mas_offset(145); + make.right.mas_equalTo(self.speedBackView.mas_right).mas_offset(-140); + make.width.equalTo(@90); + make.height.equalTo(@34); + }]; + + [_descSpeed mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab.mas_bottom); + make.left.mas_equalTo(self.speedBackView.mas_left).mas_offset(166); + make.right.mas_equalTo(self.speedBackView.mas_right).mas_offset(-165); + make.height.equalTo(@16); + }]; + + + + [_paceDotView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.paceBackView.mas_top).mas_offset(7); + make.left.mas_equalTo(self.paceBackView.mas_left).mas_offset(15); + make.width.equalTo(@8); + make.height.equalTo(@8); + }]; + + [_pace mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.paceBackView.mas_top); + make.left.mas_equalTo(self.paceBackView.mas_left).mas_offset(29); + make.width.equalTo(@32); + make.height.equalTo(@22); + }]; + + [_paceLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.pace.mas_bottom); + make.left.mas_equalTo(self.paceBackView.mas_left).mas_offset(143); + make.right.mas_equalTo(self.paceBackView.mas_right).mas_offset(-142); + make.height.equalTo(@34); + }]; + + [_descPace mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.paceLab.mas_bottom); + make.left.mas_equalTo(self.paceBackView.mas_left).mas_offset(166); + make.right.mas_equalTo(self.paceBackView.mas_right).mas_offset(-165); + make.height.equalTo(@16); + }]; + +} + +- (void)test { + _paceLab.text = @"193"; + _speedLab.text = @"5.42"; +} + +@end diff --git a/MRRunning/MGDDataViewController.h b/MRRunning/MGDDataViewController.h new file mode 100644 index 0000000..22c7f06 --- /dev/null +++ b/MRRunning/MGDDataViewController.h @@ -0,0 +1,49 @@ +// +// MGDDataViewController.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + +#import +#import "MGDOverView.h" +#import "MGDDataView.h" +#import "MGDButtonsView.h" +#import "MGDShareView.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDDataViewController : UIViewController + +@property (nonatomic, strong) NSString *distanceStr; +@property (nonatomic, strong) NSString *speedStr; //配速 +@property (nonatomic, strong) NSString *stepFrequencyStr; //步频 +@property (nonatomic, strong) NSString *timeStr; //跑步时间 +@property (nonatomic, strong) NSString *energyStr;//千卡 + + +@property (nonatomic, strong) NSArray *locationAry; //首页中采集到的所有定位点的数据 +@property (nonatomic, strong) NSArray *drawLineAry; //首页中采集到的所有用来绘制轨迹的数据 + +@property (nonatomic, strong) NSArray *caculatedSpeedAry; //首页中处理后的速度数组 +@property (nonatomic, strong) NSArray *cacultedStepsAry; //首页中的处理后步频数组 +@property int averageStepFrequency; //平均步频 +@property int maxStepFrequency; //最大步频 +@property double averageSpeed; //平均速度 +@property double maxSpeed; //最大速度 + +@property (nonatomic, strong) NSArray *originStepsAry; //原始的获取到的步频数组; + +@property (nonatomic ,strong) UIScrollView *backScrollView; + +@property (nonatomic ,strong) MGDOverView *overView; + +@property (nonatomic ,strong) MGDDataView *dataView; + +@property (nonatomic ,strong) MGDButtonsView *twoBtnView; + +@property (nonatomic ,strong) MGDShareView *shareView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/MGDDataViewController.m b/MRRunning/MGDDataViewController.m new file mode 100644 index 0000000..fdaefa4 --- /dev/null +++ b/MRRunning/MGDDataViewController.m @@ -0,0 +1,420 @@ +// +// MGDDataViewController.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/27. +// + +#import +#import +#import +#import +#import +#import +#import +#import + +#import "ZYLMainViewController.h" //首页 +#import "ZYLRunningViewController.h" +#import "MRTabBarController.h" +#import "MGDDataViewController.h" +#import "RunLocationModel.h" +#import "MASmoothPathTool.h" +#import "UIImageView+WebCache.h" +#import "SZHChart.h"//速度图表的View +#import "SZHWaveChart.h"//步频的波浪图 +@interface MGDDataViewController () +@property (nonatomic, strong) AMapLocationManager *ALocationManager; +@property (nonatomic, strong) NSArray *origTracePoints; //原始轨迹测绘坐标点 +@property (nonatomic, strong) NSArray *smoothedTracePoints; //平滑处理用的轨迹数组点 +@property (nonatomic, strong) MAPolyline *smoothedTrace; + + + +//大头针 +@property (nonatomic, strong) MAPointAnnotation *beginAnnotataion; +@property (nonatomic, strong) MAPointAnnotation *endAnnotataion; + +@property __block UIImage *shareImage; +@end + +@implementation MGDDataViewController +- (void)viewWillAppear:(BOOL)animated{ + self.tabBarController.hidesBottomBarWhenPushed = YES; + self.navigationController.navigationBar.hidden = NO; +} + +- (void)viewDidAppear:(BOOL)animated{ + self.tabBarController.hidesBottomBarWhenPushed = NO; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self.navigationController setNavigationBarHidden:YES animated:YES];//隐藏导航栏 + + + [self fit]; + self.overView.mapView.delegate = self; + self.overView.mapView.showsUserLocation = NO; + self.overView.mapView.userInteractionEnabled = YES; + [self initLocationManager]; + + +/* +绘制轨迹 + */ + //初始化原始数据数组和处理后的数组 + self.origTracePoints = [NSArray array]; + self.smoothedTracePoints = [NSArray array]; + [self loadTrancePoints]; + [self initSmoothedTrace]; + + //绘制始终位置大头针 + [self initBeginAndEndAnnotations]; + + // 给分享界面添加手势 + UITapGestureRecognizer *backGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(backevent:)]; + backGesture.delegate = self; + [self.shareView.backView addGestureRecognizer:backGesture]; +} + //适配各个View的深色模式以及页面布局 +- (void)fit{ + //适配深色模式 + _backScrollView = [[UIScrollView alloc] init]; + if (@available(iOS 11.0, *)) { + self.view.backgroundColor = bottomColor; + _backScrollView.contentInsetAdjustmentBehavior = UIApplicationBackgroundFetchIntervalNever; + } else { + // Fallback on earlier versions + } + + //根据机型进行控件布局 + if (kIs_iPhoneX) { + _backScrollView.frame = CGRectMake(0, 0, screenWidth, screenHeigth - 100); + + _twoBtnView = [[MGDButtonsView alloc] initWithFrame:CGRectMake(0, screenHeigth - 100, screenWidth, 100)]; + + _dataView = [[MGDDataView alloc] initWithFrame:CGRectMake(0, screenHeigth - 100 + 10, screenWidth, 710 + 35)]; + }else { + _backScrollView.frame = CGRectMake(0, 0, screenWidth, screenHeigth - 66); + + _twoBtnView = [[MGDButtonsView alloc] initWithFrame:CGRectMake(0, screenHeigth - 66, screenWidth, 66)]; + + _dataView = [[MGDDataView alloc] initWithFrame:CGRectMake(0, screenHeigth - 66 + 10, screenWidth, 710 + 35)]; + + } + + //两个butto的View + [_twoBtnView.overBtn addTarget:self action:@selector(backRootCV) forControlEvents:UIControlEventTouchUpInside]; + [_twoBtnView.shareBtn addTarget:self action:@selector(share) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:_twoBtnView]; + _backScrollView.contentSize = CGSizeMake(screenWidth, 1432 + 35 + 40); + [self.view addSubview:_backScrollView]; + + //地图下,统计图上的View,配速、时间、燃烧千卡等label的数据 + _overView = [[MGDOverView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeigth)]; + [self.backScrollView addSubview:_overView]; + self.overView.mapView.delegate = self; + /* + 步频、速度两个图表 + */ + [self addTwoCharts]; + + //绘制统计图的View + [self.backScrollView addSubview:_dataView]; + + + //赋值 + self.overView.kmLab.text = self.distanceStr; //跑步距离赋值 + self.overView.speedLab.text = self.speedStr; //配速赋值 + if (self.averageStepFrequency >0 && self.averageStepFrequency < 300) { + self.overView.paceLab.text = [NSString stringWithFormat:@"%d",self.averageStepFrequency]; //平均步频赋值 + } + _overView.timeLab.text = self.timeStr; //跑步时间赋值 + self.overView.calLab.text = self.energyStr; //燃烧千卡赋值 + self.dataView.paceLab.text = [NSString stringWithFormat:@"%d",self.maxStepFrequency]; //最大步频 + self.dataView.speedLab.text = [NSString stringWithFormat:@"%.02f",self.maxSpeed]; //最大速度 + +} + +//添加两个图表 +- (void)addTwoCharts{ +// //处理步频的数组 +// NSMutableArray *stepsMuteAry = [NSMutableArray array]; +// int totleSteps = 0; +// for (int i = 0; i < self.originStepsAry.count; i +=5) { +// NSString *stepStr = self.originStepsAry[i]; +// int stepsValue = [stepStr intValue]; +// totleSteps = totleSteps + stepsValue; +// [stepsMuteAry addObject:stepStr]; +// } +// int averageStepFrequence = totleSteps/self.cacultedStepsAry.count; +// self.caculatedSpeedAry = stepsMuteAry; + + //画步频的波浪图 + if (self.cacultedStepsAry.count != 0) { + //步频的波浪图 +// NSArray *paceArray = @[@130,@140,@152,@180,@200,@148,@132,@98]; + SZHWaveChart *paceWaveChart = [[SZHWaveChart alloc] init]; + [paceWaveChart initWithViewsWithBooTomCount:self.cacultedStepsAry.count AndLineDataAry:self.cacultedStepsAry AndYMaxNumber:250]; + [self.dataView.paceBackView addSubview:paceWaveChart]; + [paceWaveChart mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.dataView.paceBackView); + make.height.mas_equalTo(245); + }]; + paceWaveChart.topYlabel.text = @"步/分"; + paceWaveChart.bottomXLabel.text = @"分钟"; + for (int i = 0; i < paceWaveChart.leftLblAry.count; i++) { + UILabel *label = paceWaveChart.leftLblAry[i]; + label.text = [NSString stringWithFormat:@"%d",(i+1) * 50]; + } + } + +// //处理画速度的折线图 +// NSMutableArray *speedMuteAry = [NSMutableArray array]; +// for (int i = 0; i < self.locationAry.count; i += 160) { +// RunLocationModel *Model = self.locationAry[i]; +// double speed = Model.speed; +// NSString *speedStr = [[NSNumber numberWithDouble:speed] stringValue]; +// [speedMuteAry addObject:speedStr]; +// } +// self.caculatedSpeedAry = speedMuteAry; + + if (self.caculatedSpeedAry.count != 0) { + //速度的折线图 + SZHChart *speedChart = [[SZHChart alloc] init]; + [speedChart initWithViewsWithBooTomCount:self.cacultedStepsAry.count AndLineDataAry:self.caculatedSpeedAry AndYMaxNumber:6]; + [self.dataView.speedBackView addSubview:speedChart]; + [speedChart mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.dataView.speedBackView); + make.height.mas_equalTo(245); + }]; + speedChart.topYlabel.text = @"米/秒"; + speedChart.bottomXLabel.text = @"分钟"; + for (int i = 0; i < speedChart.leftLblAry.count; i++) { + UILabel *label = speedChart.leftLblAry[i]; + label.text = [NSString stringWithFormat:@"%d", i + 2]; + } + } +} + +//跳转到首页界面 +- (void)backRootCV { + + MRTabBarController *cv = [[MRTabBarController alloc] init]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"showTabBar" object:nil]; + [self.navigationController pushViewController:cv animated:YES]; +} + +- (void)share { + _shareView = [[MGDShareView alloc] initWithShotImage:@"" logoImage:@"" QRcodeImage:@""]; + [self.view addSubview:_shareView]; + [_shareView.cancelBtn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside]; + + //分享界面下五个按钮的方法 + [self shareAction]; + + // 分享界面的地图截图 + CGRect inRect = self.overView.mapView.frame; + [self.overView.mapView takeSnapshotInRect:inRect withCompletionBlock:^(UIImage *resultImage, NSInteger state) { + state = 1; + self.shareImage = resultImage; + self.shareView.shotImage.image = self.shareImage; + }]; +} + +- (void)backevent:(UIGestureRecognizer *)sender { + NSLog(@"1111"); +} + + +- (void)back { + [UIView animateWithDuration:0.3 animations:^{ + [self.shareView removeFromSuperview]; + }]; +} + +#pragma mark- 位置管理者 +- (void)initLocationManager{ + self.ALocationManager = [[AMapLocationManager alloc] init]; + self.ALocationManager.delegate = self; + self.ALocationManager.allowsBackgroundLocationUpdates = YES; //开启后台定位 + self.ALocationManager.distanceFilter = 5; //设置移动精度 + self.ALocationManager.locationTimeout = 2; //定位超时时间 + [self.ALocationManager setLocatingWithReGeocode:YES]; + [self.ALocationManager startUpdatingLocation]; + // 延迟执行取消定位操作 + __weak typeof(self) weakSelf = self; + dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)); + dispatch_after(delayTime, dispatch_get_main_queue(), ^{ + [weakSelf.ALocationManager stopUpdatingLocation]; + }); +} + +#pragma mark- 轨迹相关 + //因为CLLocationCoordinate2D为只读属性,无法用可变数组直接addobject储存,所以需要以下转化 +- (void)loadTrancePoints{ + NSMutableArray *muteableAry = [NSMutableArray array]; + // CLLocationCoordinate2D linePoints[self.drawLineAry.count]; + for (int i = 0; i < self.drawLineAry.count; i++) { + RunLocationModel *lineLocationModel = self.drawLineAry[i]; + // linePoints[i] = lineLocationModel.location; + MALonLatPoint *point = [[MALonLatPoint alloc] init]; + point.lat = lineLocationModel.location.latitude; + point.lon = lineLocationModel.location.longitude; + [muteableAry addObject:point]; + } + self.origTracePoints = muteableAry; + NSLog(@"原始轨迹数据测绘点个数为%lu",(unsigned long)self.origTracePoints.count); +} + +//处理、绘制轨迹线 +- (void)initSmoothedTrace{ + MASmoothPathTool *tool = [[MASmoothPathTool alloc] init]; + tool.intensity = 3; + tool.threshHold = 0.3; + tool.noiseThreshhold = 10; + self.smoothedTracePoints = [tool pathOptimize:self.origTracePoints]; + NSLog(@"处理后的轨迹绘制数据点%lu",(unsigned long)self.smoothedTracePoints.count); + CLLocationCoordinate2D *pCoords = malloc(sizeof(CLLocationCoordinate2D) * self.smoothedTracePoints.count); + if(!pCoords) { + return; + } + + for(int i = 0; i < self.smoothedTracePoints.count; ++i) { + MALonLatPoint *p = [self.smoothedTracePoints objectAtIndex:i]; + CLLocationCoordinate2D *pCur = pCoords + i; +// CLLocationCoordinate2D *pCur = &pCoords[i]; + pCur->latitude = p.lat; + pCur->longitude = p.lon; + } + + self.smoothedTrace = [MAPolyline polylineWithCoordinates:pCoords count:self.smoothedTracePoints.count]; + [self.overView.mapView addOverlay:self.smoothedTrace]; + if(pCoords) { + free(pCoords); + } + +} + +//自定义轨迹线 +- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id)overlay{ + if ([overlay isKindOfClass:[MAPolyline class]]) { + MAPolylineRenderer *polyLineRender = [[MAPolylineRenderer alloc] initWithPolyline:overlay]; + polyLineRender.lineWidth = 8; + polyLineRender.strokeColor = [UIColor colorWithRed:123/255.0 green:183/255.0 blue:196/255.0 alpha:1.0]; //折线颜色 + return polyLineRender; + } + return nil; +} + +#pragma mark- 大头针相关 +//设置开始,结束位置的大头针 +- (void)initBeginAndEndAnnotations{ + //开始地点 + MAPointAnnotation *beginAnnotation = [[MAPointAnnotation alloc] init]; + // RunLocationModel *beginLocation = self.locationAry.firstObject; + MALonLatPoint *beginLocation = self.smoothedTracePoints.firstObject; + beginAnnotation.coordinate = CLLocationCoordinate2DMake(beginLocation.lat, beginLocation.lon); + self.beginAnnotataion = beginAnnotation; + [self.overView.mapView addAnnotation:self.beginAnnotataion]; + + //结束地点 + MAPointAnnotation *endAnnotation = [[MAPointAnnotation alloc] init]; + // RunLocationModel *endLocation = self.locationAry.lastObject; + MALonLatPoint *endLocation = self.smoothedTracePoints.lastObject; + endAnnotation.coordinate = CLLocationCoordinate2DMake(endLocation.lat, endLocation.lon); + self.endAnnotataion = endAnnotation; + [self.overView.mapView addAnnotation:self.endAnnotataion]; +} + +//自定义大头针样式 +- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation{ + if ([annotation isKindOfClass:[MAPointAnnotation class]]){ + if (annotation == self.beginAnnotataion) { + static NSString *pointReuseIndentifier = @"pointReuseIndentifier"; + MAPinAnnotationView*annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndentifier]; + if (annotationView == nil){ + annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndentifier]; + } + annotationView.image = [UIImage imageNamed:@"startPointImage"]; + annotationView.animatesDrop = NO; //设置标注动画显示,默认为NO + annotationView.canShowCallout= NO; //设置气泡可以弹出,默认为NO + annotationView.draggable = NO; //设置不可被拖动 + return annotationView; + }else if (annotation == self.endAnnotataion){ + static NSString *end = @"end"; + MAPinAnnotationView*annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:end]; + if (annotationView == nil){ + annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:end]; + } + annotationView.image = [UIImage imageNamed:@"endPointImage"]; + annotationView.animatesDrop = NO; //设置标注动画显示,默认为NO + annotationView.canShowCallout= NO; //设置气泡可以弹出,默认为NO + annotationView.draggable = NO; //设置不可被拖动 + return annotationView; + } + } + return nil; +} + +#pragma mark- 定位回调方法 +- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation{ + CGFloat signal = userLocation.location.horizontalAccuracy; + + if(!updatingLocation) + return ; + + if (signal < 0) + { + return ; + } +} + +- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode{ + CGFloat signal = location.horizontalAccuracy; + if (signal < 0) + { + return ; + } + [self.overView.mapView setCenterCoordinate:location.coordinate]; +} + +#pragma mark- 分享的五个按钮的方法 +- (void)shareAction{ + for (int i = 0; i < self.shareView.bootomBtns.count; i++) { + UIButton *btn = [self.shareView.bootomBtns objectAtIndex:i]; + switch (btn.tag) { + case 1: + [btn addTarget:self action:@selector(savePhotoAtLocalAlbum) forControlEvents:UIControlEventTouchUpInside]; + break; + + default: + break; + } + } +} + +//保存截图到本地 +- (void)savePhotoAtLocalAlbum{ + CGRect inRect = self.overView.mapView.frame; + [self.overView.mapView takeSnapshotInRect:inRect withCompletionBlock:^(UIImage *resultImage, NSInteger state) { + state = 1; + + }]; +} + + +#pragma mark-关于两个位置管理者的定位代理方法:实现后台定位 + +- (void)amapLocationManager:(AMapLocationManager *)manager doRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} +- (void)mapViewRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} + +//- (void)dealloc{ +// [[NSNotificationCenter defaultCenter]removeObserver:self]; +//} +@end diff --git a/MRRunning/MGDOverView.h b/MRRunning/MGDOverView.h new file mode 100644 index 0000000..349bf12 --- /dev/null +++ b/MRRunning/MGDOverView.h @@ -0,0 +1,57 @@ +// +// MGDOverView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/26. +// + +#import +#import +#import +#import +#import +NS_ASSUME_NONNULL_BEGIN + +//这个页面是点击结束跑步按钮后展示出的页面,上面的mapView用来放地图,下面的label,UIImageview等控件用来显示这次跑步的信息(缺少一个天气的UIImageView) + +@interface MGDOverView : UIView +//@property (nonatomic, strong) MAMapView *mapView2; +//温度 +@property (nonatomic, strong) UILabel *degree; +//地图 +@property (nonatomic, strong) MAMapView *mapView; +//下方背景 +@property (nonatomic, strong) UIView *backView; +//头像 +@property (nonatomic, strong) UIImageView *userIcon; +//用户名 +@property (nonatomic, strong) UILabel *userName; +//公里数 +@property (nonatomic, strong) UILabel *kmLab; +//公里单位 +@property (nonatomic, strong) UILabel *km; +//配速 +@property (nonatomic, strong) UILabel *speedLab; +//配速单位 +@property (nonatomic, strong) UILabel *speed; +//步频 +@property (nonatomic, strong) UILabel *paceLab; +//步频单位 +@property (nonatomic, strong) UILabel *pace; +//时间 +@property (nonatomic, strong) UILabel *timeLab; +//时间单位 +@property (nonatomic, strong) UILabel *time; +//千卡 +@property (nonatomic, strong) UILabel *calLab; +//千卡单位 +@property (nonatomic, strong) UILabel *cal; +//日期 +@property (nonatomic, strong) UILabel *date; +//时间 +@property (nonatomic, strong) UILabel *currentTime; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/MGDOverView.m b/MRRunning/MGDOverView.m new file mode 100644 index 0000000..52667eb --- /dev/null +++ b/MRRunning/MGDOverView.m @@ -0,0 +1,350 @@ +// +// MGDOverView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/26. +// + +#import "MGDOverView.h" +#import +#import +#import +#import +#import + +#import "UIImageView+WebCache.h" +#import "HttpClient.h" +#import +#define UNITCOLOR [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0] + +@implementation MGDOverView + +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + //地图的View + _mapView = [[MAMapView alloc] init]; + [self addSubview:_mapView]; + + //温度的label + _degree = [[UILabel alloc] init]; + _degree.font = [UIFont fontWithName:@"PingFangSC" size: 18]; + _degree.textAlignment = NSTextAlignmentCenter; + [self.mapView addSubview:_degree]; + + //下方显示跑步信息的View + _backView = [[UIView alloc] init]; + [self addSubview:_backView]; + + //用户头像 + _userIcon = [[UIImageView alloc] init]; + _userIcon.layer.masksToBounds = YES; + _userIcon.layer.cornerRadius = 36.0; + _userIcon.contentMode = UIViewContentModeScaleToFill; + [self.backView addSubview:_userIcon]; + + //用户姓名 + _userName = [[UILabel alloc] init]; + _userName.textAlignment = NSTextAlignmentLeft; + _userName.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + _userName.numberOfLines = 0; + [self.backView addSubview:_userName]; + + //展示跑步信息的一些Label + _kmLab = [[UILabel alloc] init]; + _kmLab.textAlignment = NSTextAlignmentCenter; + _kmLab.font = [UIFont fontWithName:@"Impact" size: 44]; + _kmLab.numberOfLines = 0; + [self.backView addSubview:_kmLab]; + + _km = [[UILabel alloc] init]; + _km.textAlignment = NSTextAlignmentCenter; + _km.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 18]; + _km.text = @"公里"; + [self.backView addSubview:_km]; + + _speedLab = [[UILabel alloc] init]; + _speedLab.textAlignment = NSTextAlignmentCenter; + _speedLab.font = [UIFont fontWithName:@"Impact" size: 24]; + [self.backView addSubview:_speedLab]; + + _speed = [[UILabel alloc] init]; + _speed.textAlignment = NSTextAlignmentCenter; + _speed.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 12]; + _speed.text = @"配速"; + _speed.tintColor = UNITCOLOR; + [self.backView addSubview:_speed]; + + _paceLab = [[UILabel alloc] init]; + _paceLab.textAlignment = NSTextAlignmentCenter; + _paceLab.font = self.speedLab.font; + [self.backView addSubview:_paceLab]; + + _pace = [[UILabel alloc] init]; + _pace.textAlignment = NSTextAlignmentCenter; + _pace.font = _speed.font; + _pace.text = @"步频"; + _pace.tintColor = UNITCOLOR; + [self.backView addSubview:_pace]; + + _timeLab = [[UILabel alloc] init]; + _timeLab.textAlignment = NSTextAlignmentCenter; + _timeLab.font = self.speedLab.font; + [self.backView addSubview:_timeLab]; + + _time = [[UILabel alloc] init]; + _time.textAlignment = NSTextAlignmentCenter; + _time.font = self.speed.font; + _time.text = @"时间"; + _time.tintColor = UNITCOLOR; + [self.backView addSubview:_time]; + + _calLab = [[UILabel alloc] init]; + _calLab.textAlignment = NSTextAlignmentCenter; + _calLab.font = self.speedLab.font; + [self.backView addSubview:_calLab]; + + _cal = [[UILabel alloc] init]; + _cal.textAlignment = NSTextAlignmentCenter; + _cal.font = self.speed.font; + _cal.text = @"千卡"; + _cal.tintColor = UNITCOLOR; + [self.backView addSubview:_cal]; + + _date = [[UILabel alloc] init]; + _date.textAlignment = NSTextAlignmentRight; + _date.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + [self.backView addSubview:_date]; + + _currentTime = [[UILabel alloc] init]; + _currentTime.textAlignment = NSTextAlignmentRight; + _currentTime.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + [self.backView addSubview:_currentTime]; + + + if (@available(iOS 11.0, *)) { + self.backView.backgroundColor = bottomColor; + self.kmLab.tintColor = bottomTitleColor; + self.speedLab.tintColor = bottomTitleColor; + self.paceLab.tintColor = bottomTitleColor; + self.timeLab.tintColor = bottomTitleColor; + self.calLab.tintColor = bottomTitleColor; + self.km.tintColor = kmColor; + self.currentTime.tintColor = MGDTextColor2; + self.date.tintColor = MGDColor2; + } else { + // Fallback on earlier versions + } + //数据测试 + [self test]; + } + return self; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + + if (kIs_iPhoneX) { + [_mapView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth * 0.6478); + }]; + + [_degree mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(58); + make.right.mas_equalTo(self.mas_right).mas_offset(-58); + make.width.equalTo(@44); + make.height.equalTo(@25); + }]; + + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mapView.mas_bottom); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth - 100 - screenHeigth * 0.6478); + }]; + + [_date mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(14); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(266); + make.width.equalTo(@54); + make.height.equalTo(@17); + }]; + + [_currentTime mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(14); + make.left.mas_equalTo(self.date.mas_right).mas_offset(5); + make.width.equalTo(@35); + make.height.equalTo(@17); + }]; + + }else { + [_mapView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.equalTo(@415); + }]; + + [_degree mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(36); + make.right.mas_equalTo(self.mas_right).mas_offset(-58); + make.width.equalTo(@44); + make.height.equalTo(@25); + }]; + + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(415); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.bottom.mas_equalTo(self.mas_bottom).mas_offset(-66); + }]; + } + + [_userIcon mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(17); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(19); + make.width.equalTo(@72); + make.height.equalTo(@72); + }]; + + [_userName mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(42); + make.bottom.equalTo(self.userIcon.mas_bottom); + make.left.mas_equalTo(self.userIcon.mas_right).mas_offset(14); + make.width.equalTo(@127); +// make.height.equalTo(@22); + }]; + + [_kmLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(31); + make.right.mas_equalTo(self.km.mas_left); + make.width.mas_greaterThanOrEqualTo(79); + make.height.equalTo(@53); + }]; + + [_km mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(54); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-15); + make.width.equalTo(@36); + make.height.equalTo(@25); + }]; + + [_speedLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.userIcon.mas_bottom).mas_offset(25); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(15); + make.width.equalTo(@78); + make.height.equalTo(@29); + }]; + + [_speed mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.speedLab.mas_bottom).mas_offset(4); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(24); + make.width.equalTo(@62); + make.height.equalTo(@24); + }]; + + [_paceLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.userIcon.mas_bottom).mas_offset(25); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(104); + make.width.equalTo(@78); + make.height.equalTo(@29); + }]; + + [_pace mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.paceLab.mas_bottom).mas_offset(4); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(125); + make.width.equalTo(@36); + make.height.equalTo(@24); + }]; + + [_timeLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.userIcon.mas_bottom).mas_offset(25); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-104); + make.width.equalTo(@90); //78 + make.height.equalTo(@29); + }]; + + [_time mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.timeLab.mas_bottom).mas_offset(4); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-125); + make.width.equalTo(@36); + make.height.equalTo(@24); + }]; + + [_calLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.userIcon.mas_bottom).mas_offset(25); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-15); + make.width.equalTo(@78); + make.height.equalTo(@29); + }]; + + [_cal mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.timeLab.mas_bottom).mas_offset(4); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-36); + make.width.equalTo(@36); + make.height.equalTo(@24); + }]; + + +} + +- (void)test { + + //设置地图相关属性 + self.mapView.zoomLevel = 18; + self.mapView.mapType = MAMapTypeStandard; //设置地图的样式 + self.mapView.showsUserLocation = NO; //不显示小蓝点 + self.mapView.userTrackingMode = MAUserTrackingModeFollow; + self.mapView.pausesLocationUpdatesAutomatically = NO; + self.mapView.showsCompass = NO; + self.mapView.showsScale = NO; +// self.mapView.userInteractionEnabled = YES; //是否禁止地图与用户的交互 + [self.mapView setAllowsBackgroundLocationUpdates:YES];//打开后台定位 + self.mapView.distanceFilter = 10; + //自定义用户小蓝点,不让其显示精度圈 + MAUserLocationRepresentation *r = [[MAUserLocationRepresentation alloc] init]; + r.showsAccuracyRing = NO;//不显示精度圈 + r.image = [UIImage imageNamed:@"userAnnotation"]; + [self.mapView updateUserLocationRepresentation:r]; + self.mapView.userInteractionEnabled = NO; + + + //测试温度 + _degree.text = @"23°C"; +// //测试头像 +// _userIcon.image = [UIImage imageNamed:@"avatar"]; +// //测试用户名 +// _userName.text = @"你的寒王"; + + [self getUserInfo]; +// [self getUserData]; + + //测试公里数 + _kmLab.text = @"37.26"; + //测试配速 + _speedLab.text = @"3'55''"; + //测试步频 + _paceLab.text = @"132"; + //测试时间 + _timeLab.text = @"6:16"; + //测试千卡 + _calLab.text = @"131"; + //测试日期 + _date.text = @"10月23日"; + //测试时间 + _currentTime.text = @"20:36"; +} +//网络请求 ,从网络上获取用户的头像、昵称 + +- (void)getUserInfo { + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *nickName = [user objectForKey:@"nickname"]; + NSString *imageUrl = [user objectForKey:@"avatar_url"]; + [self.userIcon sd_setImageWithURL:[NSURL URLWithString:imageUrl]]; + self.userName.text = nickName; +} + + +@end diff --git a/MRRunning/MGDShareModel.h b/MRRunning/MGDShareModel.h new file mode 100644 index 0000000..2c3a235 --- /dev/null +++ b/MRRunning/MGDShareModel.h @@ -0,0 +1,25 @@ +// +// MGDShareModel.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDShareModel : NSObject + +//分享标题 只分享文本是也用这个字段 +@property (nonatomic,copy) NSString *title; +//描述内容 +@property (nonatomic,copy) NSString *descr; +//缩略图 +@property (nonatomic,strong) id thumbImage; +//链接 +@property (nonatomic,copy) NSString *url; + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/MGDShareModel.m b/MRRunning/MGDShareModel.m new file mode 100644 index 0000000..471e0d7 --- /dev/null +++ b/MRRunning/MGDShareModel.m @@ -0,0 +1,12 @@ +// +// MGDShareModel.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +#import "MGDShareModel.h" + +@implementation MGDShareModel + +@end diff --git a/MRRunning/MGDSharePlatform.h b/MRRunning/MGDSharePlatform.h new file mode 100644 index 0000000..a5abbe7 --- /dev/null +++ b/MRRunning/MGDSharePlatform.h @@ -0,0 +1,19 @@ +// +// MGDSharePlatform.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +#import + + +NS_ASSUME_NONNULL_BEGIN + +@interface MGDSharePlatform : NSObject +@property (nonatomic,copy) NSString *iconStateNormal; +@property (nonatomic,copy) NSString *iconStateHighlighted; +@property (nonatomic,copy) NSString *name; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/MGDSharePlatform.m b/MRRunning/MGDSharePlatform.m new file mode 100644 index 0000000..dad793c --- /dev/null +++ b/MRRunning/MGDSharePlatform.m @@ -0,0 +1,12 @@ +// +// MGDSharePlatform.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +#import "MGDSharePlatform.h" + +@implementation MGDSharePlatform + +@end diff --git a/MRRunning/MGDShareView.h b/MRRunning/MGDShareView.h new file mode 100644 index 0000000..1c913bb --- /dev/null +++ b/MRRunning/MGDShareView.h @@ -0,0 +1,47 @@ +// +// MGDShareView.h +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +//这个View是跑完步后点击分享后弹出的View,是一个整体的大的透明的UIView,上面有一个占据部分的View,上方是一个大的UIImageView,用来展示截取的关于跑步信息的图片,下面是两个小的UIImageView和一个Label,两个小的UIImageView自己看逻辑来获取,最下面是取消按钮和一个放置五个按钮的view,按钮的具体逻辑自己实现就行了 +#import + +NS_ASSUME_NONNULL_BEGIN +@class MGDShareView; + +@protocol MGDShareViewDelegate + +- (NSArray *_Nullable)platformImageArray:(NSString *_Nullable)imageArray; + +- (NSArray *_Nullable)platformTitleArray:(NSString *_Nullable)titleArray; + +@end + +@interface MGDShareView : UIView + +- (instancetype)initWithShotImage:(NSString *)shotImage logoImage:(NSString *)logo QRcodeImage:(NSString *)QRcode; + +@property (nonatomic, strong)NSArray *bootomBtns; //保存着分享的五个按钮的数组 + +@property (nonatomic, strong) UIView *backView; + +@property (nonatomic, strong) UIView *popView; + +@property (nonatomic, strong) UIImageView *shotImage; + +@property (nonatomic, strong) UIImageView *logoImage; + +@property (nonatomic, strong) UIImageView *QRImage; + +@property (nonatomic, strong) UILabel *shareLab; + +@property (nonatomic, strong) UIButton *cancelBtn; + +@property (nonatomic, strong) UIView *bottomView; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/MGDShareView.m b/MRRunning/MGDShareView.m new file mode 100644 index 0000000..7820c80 --- /dev/null +++ b/MRRunning/MGDShareView.m @@ -0,0 +1,299 @@ +// +// MGDShareView.m +// MRMobileRun +// +// Created by 阿栋 on 2020/7/28. +// + +#import "MGDShareView.h" +#import +#import + +@interface MGDShareView() + + +@end + +@implementation MGDShareView + +- (instancetype)initWithShotImage:(NSString *)shotImage logoImage:(NSString *)logo QRcodeImage:(NSString *)QRcode { + if (self = [super init]) { + self.frame = [UIScreen mainScreen].bounds; + //整体的透明的背景 + _backView = [[UIView alloc] init]; + _backView.backgroundColor = [UIColor clearColor]; + [self addSubview:_backView]; + + //底部的按钮的View + _bottomView = [[UIView alloc] init]; + [self.backView addSubview:_bottomView]; +// + NSMutableArray *btnAry = [NSMutableArray array]; + //创建五个View,包括内部的Btn和Lable,后面约束一下内部的位置 + CGFloat gap = (screenWidth - 52 - 250) / 4; + for (int i = 1;i <= 5; i++) { + //View + UIView *view = [[UIView alloc] init]; +// view.backgroundColor = [UIColor redColor]; + [self.bottomView addSubview:view]; + CGFloat x = 26 + (gap + 50) * (i-1); + //View布局 + if (kIs_iPhoneX) { + [view mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.popView.mas_bottom).mas_offset(50); //(64) + make.left.mas_equalTo(self.mas_left).mas_offset(x); + make.bottom.mas_equalTo(self.cancelBtn.mas_top).mas_offset(-18); + make.width.equalTo(@50); + }]; + }else { + [view mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.popView.mas_bottom).mas_offset(90); //(69) + make.left.mas_equalTo(self.mas_left).mas_offset(x); + make.bottom.mas_equalTo(self.cancelBtn.mas_top).mas_offset(-15); + make.width.equalTo(@50); + }]; + } + + //Button + UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; + [btn setImage:[UIImage imageNamed:[NSString stringWithFormat:@"分享%d",i]] forState:UIControlStateNormal]; + [view addSubview:btn]; + [btn mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(30, 30)); + make.centerX.top.equalTo(view); + }]; + //为btn添加标记,等待在controller里为button添加逻辑操作 + btn.tag = i; + [btnAry addObject:btn]; + + //Lable + UILabel *label = [[UILabel alloc] init]; + label.tag = 5 + i; + label.textAlignment = NSTextAlignmentCenter; + label.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + label.textColor = [UIColor colorWithRed:136/255.0 green:141/255.0 blue:151/255.0 alpha:1.0]; + [view addSubview:label]; + [label mas_makeConstraints:^(MASConstraintMaker *make) { + make.size.mas_equalTo(CGSizeMake(50, 17)); + make.centerX.bottom.equalTo(view); + }]; + //设置五个label的内容 + switch (label.tag) { + case 6: + label.text = @"保存图片"; + break; + case 7: + label.text = @"QQ"; + break; + case 8: + label.text = @"QQ空间"; + break; + case 9: + label.text = @"微信"; + break; + case 10: + label.text = @"朋友圈"; + break; + default: + break; + } + } + self.bootomBtns = btnAry; //将循环创建的btn保存下来等待在coontrller里面进行逻辑操作 + + + //弹出的View + _popView = [[UIView alloc] init]; + _popView.layer.shadowOpacity = 1; + _popView.layer.shadowRadius = 6; + _popView.layer.shadowOffset = CGSizeMake(0, 2); + [self showView]; + [self.backView addSubview:_popView]; + + //截图 + _shotImage = [[UIImageView alloc] init]; + _shotImage.backgroundColor = [UIColor clearColor]; + //_shotImage.image = [UIImage imageNamed:@"约跑icon-1"]; + [self.popView addSubview:_shotImage]; + + //两个小的UIImageview + _logoImage = [[UIImageView alloc] init]; + _logoImage.backgroundColor = [UIColor lightGrayColor]; + _logoImage.layer.cornerRadius = 6; + [self.popView addSubview:_logoImage]; + + _QRImage = [[UIImageView alloc] init]; + _QRImage.backgroundColor = [UIColor lightGrayColor]; + _QRImage.layer.cornerRadius = 6; + [self.popView addSubview:_QRImage]; + + _shareLab = [[UILabel alloc] init]; + _shareLab.textAlignment = NSTextAlignmentLeft; + _shareLab.numberOfLines = 0; + _shareLab.text = @"长按识别二维码\n加入约跑和我一起跑步"; + [self.popView addSubview:_shareLab]; + + //取消按钮 + _cancelBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + [_cancelBtn setTitle:@"取消" forState:UIControlStateNormal]; + _cancelBtn.titleLabel.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 16]; + [self.backView addSubview:_cancelBtn]; + + if (@available(iOS 11.0, *)) { + self.bottomView.backgroundColor = bottomColor; + self.shareLab.tintColor = MGDTextColor2; + [self.cancelBtn setBackgroundColor:MGDColor1]; + self.popView.backgroundColor = bottomColor; + } else { + // Fallback on earlier versions + } + } + return self; +} + + + +- (void)layoutSubviews { + [super layoutSubviews]; + if (kIs_iPhoneX) { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(67); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth - 67); + }]; + + [_popView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top).mas_offset(67); + make.left.mas_equalTo(self.mas_left).mas_offset(15); + make.right.mas_equalTo(self.mas_right).mas_offset(-15); + make.height.mas_equalTo(566); + }]; + + [_shotImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.popView.mas_top); + make.left.mas_equalTo(self.popView.mas_left); + make.right.mas_equalTo(self.popView.mas_right); + make.height.equalTo(@489); + }]; + + [_logoImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.shotImage.mas_bottom).mas_offset(11); + make.left.mas_equalTo(self.popView.mas_left).mas_offset(12); + make.height.equalTo(@54); + make.width.equalTo(@54); + }]; + + [_QRImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.shotImage.mas_bottom).mas_offset(10); + make.right.mas_equalTo(self.popView.mas_right).mas_offset(-15); + make.width.equalTo(@54); + make.height.equalTo(@54); + }]; + + [_shareLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.shotImage.mas_bottom).mas_offset(23); + make.left.mas_equalTo(self.logoImage.mas_right).mas_offset(15); + make.width.equalTo(@125); + make.height.equalTo(@34); + }]; + _shareLab.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + + [_bottomView mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.mas_equalTo(self.cancelBtn.mas_top); + make.left.mas_equalTo(self.backView.mas_left); + make.right.mas_equalTo(self.backView.mas_right); + make.height.equalTo(@129); + }]; + + [_cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.mas_equalTo(self.mas_bottom); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.equalTo(@80); + }]; + + }else { + [_backView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.mas_top).mas_offset(40); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.mas_equalTo(screenHeigth - 40); + }]; + + [_popView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top); + make.left.mas_equalTo(self.mas_left).mas_offset(41); + make.right.mas_equalTo(self.mas_right).mas_offset(-42); + make.height.mas_equalTo(480); + }]; + + [_shotImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.backView.mas_top); + make.left.mas_equalTo(self.popView.mas_left); + make.right.mas_equalTo(self.popView.mas_right); + make.height.equalTo(@415); + }]; + + [_logoImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.shotImage.mas_bottom).mas_offset(9); + make.left.mas_equalTo(self.backView.mas_left).mas_offset(51); + make.height.equalTo(@46); + make.width.equalTo(@46); + }]; + + [_QRImage mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.shotImage.mas_bottom).mas_offset(8); + make.right.mas_equalTo(self.backView.mas_right).mas_offset(-54); + make.width.equalTo(@46); + make.height.equalTo(@46); + }]; + + [_shareLab mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.shotImage.mas_bottom).mas_offset(20); + make.left.mas_equalTo(self.logoImage.mas_right).mas_offset(12); + make.width.equalTo(@135); + make.height.equalTo(@28); + }]; + _shareLab.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 10]; + + [_bottomView mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.mas_equalTo(self.cancelBtn.mas_top); + make.left.mas_equalTo(self.backView.mas_left); + make.right.mas_equalTo(self.backView.mas_right); + make.height.equalTo(@162); + }]; + + [_cancelBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.bottom.mas_equalTo(self.mas_bottom); + make.left.mas_equalTo(self.mas_left); + make.right.mas_equalTo(self.mas_right); + make.height.equalTo(@46); + }]; + } +} + +//添加底部分享的按钮和label +- (void)addBootomBtnAndLbl{ + // +} + +-(void)showView{ + + [[UIApplication sharedApplication].keyWindow addSubview:self]; + + CGAffineTransform transform = CGAffineTransformScale(CGAffineTransformIdentity,1.0,1.0); + + self.popView.transform = CGAffineTransformScale(CGAffineTransformIdentity,0.2,0.2); + self.popView.alpha = 0; + [UIView animateWithDuration:0.2 delay:0.2 usingSpringWithDamping:0.5 initialSpringVelocity:10 options:UIViewAnimationOptionCurveLinear animations:^{ + self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:.4f]; + self.popView.transform = transform; + self.popView.alpha = 1; + } completion:^(BOOL finished) { + + }]; + +} + + +@end diff --git a/MRRunning/RecordtimeString.h b/MRRunning/RecordtimeString.h new file mode 100644 index 0000000..a348dcb --- /dev/null +++ b/MRRunning/RecordtimeString.h @@ -0,0 +1,16 @@ +// +// RecordtimeString.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/29. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RecordtimeString : NSObject ++ (NSString *)getTimeStringWithSeconds:(int )second; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/RecordtimeString.m b/MRRunning/RecordtimeString.m new file mode 100644 index 0000000..ae43f92 --- /dev/null +++ b/MRRunning/RecordtimeString.m @@ -0,0 +1,50 @@ +// +// RecordtimeString.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/29. +// + +#import "RecordtimeString.h" + +@implementation RecordtimeString +//将秒数转化为HH:MM:SS格式数据的一个方法 ++ (NSString *)getTimeStringWithSeconds:(int)second{ + NSString *timeString = [[NSString alloc] init]; + + NSString *secondString = [[NSString alloc] init]; + NSString *minuteString = [[NSString alloc] init]; + NSString *hourString = [[NSString alloc] init]; + + NSString *secondStr = [NSString stringWithFormat:@"%d",second%3600%60]; + + if (second%3600%60 <10 ) { + secondString = [NSString stringWithFormat:@"%@%@",@"0",secondStr]; + } + else{ + secondString = [NSString stringWithFormat:@"%@",secondStr]; + } + + NSString * minuteStr = [NSString stringWithFormat:@"%d",second%3600/60]; + + if (second%3600/60<10) { + minuteString = [NSString stringWithFormat:@"%@%@",@"0",minuteStr]; + } + else{ + minuteString = [NSString stringWithFormat:@"%@",minuteStr]; + + } + NSString * hourStr = [NSString stringWithFormat:@"%d",second/3600]; + if (second/3600 <10) { + hourString = [NSString stringWithFormat:@"%@%@",@"0",hourStr]; + } + else{ + hourString = [NSString stringWithFormat:@"%@",hourStr]; + + } + timeString = [NSString stringWithFormat:@"%@%@%@%@%@",hourString,@":",minuteString,@":",secondString]; + NSLog(@"%@",timeString); + + return timeString; +} +@end diff --git a/MRRunning/RunLocationModel.h b/MRRunning/RunLocationModel.h new file mode 100644 index 0000000..855cb39 --- /dev/null +++ b/MRRunning/RunLocationModel.h @@ -0,0 +1,21 @@ +// +// RunLocationModel.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/22. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RunLocationModel : NSObject +@property (nonatomic, strong) CLLocation *LOCATION; +@property (nonatomic, assign) CLLocationCoordinate2D location; +@property (nonatomic, assign) CLLocationSpeed speed; +@property (nonatomic, strong) NSDate *time; //记录每个定位点的时间 + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/RunLocationModel.m b/MRRunning/RunLocationModel.m new file mode 100644 index 0000000..d7b6580 --- /dev/null +++ b/MRRunning/RunLocationModel.m @@ -0,0 +1,12 @@ +// +// RunLocationModel.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/22. +// + +#import "RunLocationModel.h" + +@implementation RunLocationModel + +@end diff --git a/MRRunning/RunMainBtn.h b/MRRunning/RunMainBtn.h new file mode 100644 index 0000000..82baade --- /dev/null +++ b/MRRunning/RunMainBtn.h @@ -0,0 +1,19 @@ +// +// RunMainBtn.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/24. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RunMainBtn : UIButton +@property (nonatomic, strong) UIImageView *logoImg; +@property (nonatomic, strong) UILabel *descLbl; + +- (void)initRunBtn;; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/RunMainBtn.m b/MRRunning/RunMainBtn.m new file mode 100644 index 0000000..ff1fbdf --- /dev/null +++ b/MRRunning/RunMainBtn.m @@ -0,0 +1,33 @@ +// +// RunMainBtn.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/24. +// + +#import "RunMainBtn.h" +#import +@implementation RunMainBtn +- (void)initRunBtn{ + + self.logoImg = [[UIImageView alloc] init]; + [self addSubview:self.logoImg]; + [self.logoImg mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self); + make.size.mas_equalTo(CGSizeMake(30, 30)); + }]; + + self.descLbl = [[UILabel alloc] init]; + [self addSubview:self.descLbl]; + [self.descLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.logoImg); + make.top.equalTo(self.logoImg.mas_bottom); + make.size.mas_equalTo(CGSizeMake(48, 17)); + }]; + self.descLbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 12]; + self.descLbl.textAlignment = NSTextAlignmentCenter; + +} + + +@end diff --git a/MRRunning/RunMainPageCV.h b/MRRunning/RunMainPageCV.h new file mode 100644 index 0000000..d437eea --- /dev/null +++ b/MRRunning/RunMainPageCV.h @@ -0,0 +1,21 @@ +// +// RunMainPageCV.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/10. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RunMainPageCV : UIViewController + + // 当前跑步距离 +@property(nonatomic,assign)double distance; + + + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/RunMainPageCV.m b/MRRunning/RunMainPageCV.m new file mode 100644 index 0000000..41f9d0b --- /dev/null +++ b/MRRunning/RunMainPageCV.m @@ -0,0 +1,696 @@ +// +// RunMainPageCV.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/10. +// + + +#import +#import +#import +#import +#import +#import +#import +#import + +#import "ZYLTimeStamp.h" //获取开始、结束的时间 +#import "GYYHealthManager.h" //读取健康数据,获取跑步时间段的步数来计算步频 +#import "MRTabBarController.h" +#import "MRMainTabBarController.h" +#import "RunMainPageCV.h" +#import "RunningMainPageView.h" +#import "RunLocationModel.h" +#import "MGDDataViewController.h" +#import "SZHAlertView.h" //跑步距离过短时结束的提示弹窗 +#import "RecordtimeString.h" +@interface RunMainPageCV () +{ + CGFloat _yyy; +} +@property (nonatomic, strong) RunningMainPageView *Mainview; + +//关于时间 +@property (nonatomic, strong) NSTimer *runTimer; +@property (nonatomic, strong) NSString *beginTime; //开始的时间(系统时间) +@property (nonatomic, strong) NSString *endTime; //结束时间(系统时间) +@property (nonatomic, strong) NSString *timeString; //跑步的时间(经历过格式转换后的) +@property (nonatomic) int hour; +@property (nonatomic) int minute; +@property (nonatomic) int second; + +//数组 +@property (nonatomic, strong) NSMutableArray *stepsAry; //每分钟的步数 +@property (nonatomic, strong) NSArray *caculateStepsAry; //处理后的步频数组 +@property int averageStepFrequency; //平均步频 +@property int maxStepFrequency; //最大步频 +@property (nonatomic, strong) NSMutableArray *mintesAry; //跑步过程中的分钟数的数组 + +@property (nonatomic, strong) NSMutableArray *speedAry; //速度的数组 +@property double averageSpeed; //平均速度 +@property double maxSpeed; //最大速度 +@property (nonatomic, strong) NSArray *caculateSpeedAry; //处理后的速度数组 + +@property double mileage; //总路程 +@property double duration; //总时间 +@property (nonatomic, strong) NSString *finishDate;//完成的日期 + +@property double kcal; //燃烧千卡; + +//关于模型 +//@property (nonatomic, strong) RunningModel *model; +@property (nonatomic, strong) RunLocationModel *locationModel; + +/* + 关于定位以及绘制轨迹 + */ +@property (nonatomic, strong) AMapLocationManager *locationManager; +@property (nonatomic, strong) CLLocationManager *CLlocationManager; +@property (nonatomic, strong)MAAnnotationView *myAnnotationView;//我的当前位置的大头针 +@property (nonatomic, strong)MAPolyline *polyline;//当前绘制的轨迹曲线 + +@property (nonatomic, strong)NSMutableArray *drawLineArray;//待绘制定位轨迹线数据 +@property (nonatomic, strong)NSMutableArray *locationArray; + +@property (nonatomic, assign)NSInteger locationNumber;//定位次数 +@property (nonatomic, assign)BOOL isFirstLocation;//是否是第一次定位 +@property (nonatomic, assign)BOOL isEndLocation; //是否是最后一次定位 + +@property (nonatomic, assign) CGFloat signal; //信号强度 +//跑步结束时的AlertView +@property (nonatomic, strong) SZHAlertView *shortAlert; +@property (nonatomic, strong) SZHAlertView *normalAlert; +@end + +@implementation RunMainPageCV + +- (void)viewWillAppear:(BOOL)animated{ + +} +- (void)viewDidAppear:(BOOL)animated{ +// self.sportsState = SportsStateStart; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + //关于一些初始化设置 + self.locationArray = [NSMutableArray array]; + self.drawLineArray = [NSMutableArray array]; + self.beginTime = [ZYLTimeStamp getTimeStamp]; //跑步开始的时间 + self.distance = 0; + self.mintesAry = [NSMutableArray array]; + self.stepsAry = [NSMutableArray array]; + + + + //跑步首页UI + self.Mainview = [[RunningMainPageView alloc] initWithFrame:self.view.frame]; + [self.view addSubview:self.Mainview]; + [self.Mainview mainRunView]; + //给拖拽的label添加手势 + UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(dragAction:)]; + [self.Mainview.dragLabel addGestureRecognizer:pan]; + self.Mainview.dragLabel.userInteractionEnabled = YES; + + self.Mainview.mapView.delegate = self; //设置地图代理 + [self initAMapLocation]; //初始化位置管理者 + + self.Mainview.numberLabel.text = [NSString stringWithFormat:@"%0.2f",self.distance]; + + [self btnFunction]; //跑步首页关于继续暂停等按钮的方法 + self.Mainview.mapView.delegate = self; + + //跑步时间初始化 + self.runTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(startTimer) userInfo:nil repeats:YES]; + self.second = self.minute = self.hour = 0; + +} + +// //拖动label来动态改变底部bottomView的高度 +- (void)dragAction:(UIPanGestureRecognizer *)pan{ + if ((pan.state == UIGestureRecognizerStateBegan)) { + if (_yyy == 0) { + _yyy = CGRectGetMaxY(self.Mainview.dragLabel.frame); + } + }else if (pan.state == UIGestureRecognizerStateChanged){ + //获取手势的偏移量 + + CGPoint point = [pan translationInView:self.Mainview.dragLabel]; + // NSLog(@"%f",point.y); + + CGFloat y = _yyy + point.y; //手势偏移量+初始量为改变量 + if (point.y < -screenHeigth * 0.05) { + self.Mainview.topView.alpha = 0.6; + self.Mainview.dragimageView.image = [UIImage imageNamed:@"初始位置"]; + [self.Mainview.bottomView mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.view); + make.top.equalTo(self.Mainview.mas_top).offset(screenHeigth * 0.5369); + }]; + //更换numberLabel的位置和显示公里的位置 + //公里数 + [self.Mainview.numberLabel mas_remakeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.Mainview); + make.top.equalTo(self.Mainview.GPSImgView.mas_bottom).offset(screenHeigth * 0.1589); + make.height.mas_equalTo(100); + make.width.mas_equalTo(self.Mainview.frame.size.width); + }]; + self.Mainview.numberLabel.font = [UIFont fontWithName:@"Impact" size: 82]; + + //显示公里的label + [self.Mainview.milesLabel mas_remakeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.Mainview.numberLabel.mas_bottom); + make.centerX.equalTo(self.Mainview.numberLabel.mas_centerX); + make.size.mas_equalTo(CGSizeMake(44, 30)); + }]; + self.Mainview.milesLabel.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 22]; + + } + if(y > screenHeigth * 0.15) { + y = screenHeigth * 0.3; + self.Mainview.topView.alpha = 0; + self.Mainview.dragimageView.image = [UIImage imageNamed:@"底部位置"]; + //更新对bottomView的约束,使得它的高度变化 + [self.Mainview.bottomView mas_remakeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.view); + make.top.equalTo(self.Mainview.mas_top).offset(screenHeigth * 0.4869 + y); + }]; + //更换numberLabel的位置和显示公里的位置 + //显示公里的lable + [self.Mainview.milesLabel mas_remakeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.Mainview.mapView).offset(screenHeigth * 0.0572); + make.right.equalTo(self.Mainview.mapView.mas_right).offset(screenWidth * -0.04); + make.size.mas_equalTo(CGSizeMake(36, 25)); + }]; + self.Mainview.milesLabel.font = [UIFont fontWithName:@"PingFangSC-Semibold" size:18]; + + [self.Mainview.numberLabel mas_remakeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.Mainview.milesLabel.mas_top).offset(5); + make.right.equalTo(self.Mainview.milesLabel.mas_left); + make.size.mas_equalTo(CGSizeMake(84, 53)); + }]; + self.Mainview.numberLabel.font = [UIFont fontWithName:@"Impact" size:44]; + } + + } +} + + +#pragma mark- 加载位置管理者 +- (void)initAMapLocation{ + _locationManager = [[AMapLocationManager alloc] init]; + _locationManager.delegate = self; + _locationManager.distanceFilter = 5;//设置移动精度(单位:米) + _locationManager.locationTimeout = 3;//定位时间 + _locationManager.allowsBackgroundLocationUpdates = YES;//开启后台定位 + [_locationManager startUpdatingLocation]; + [_locationManager setLocatingWithReGeocode:YES]; +} +//CLLocationManager +- (void)initlocation{ + //判断是否打开了位置服务 + if ([CLLocationManager locationServicesEnabled]) { + self.CLlocationManager = [[CLLocationManager alloc] init]; + self.CLlocationManager.delegate = self; + self.CLlocationManager.distanceFilter = 5; //每隔五米定位一次 + self.CLlocationManager.desiredAccuracy = kCLDistanceFilterNone; //设置定位精度 + [self.CLlocationManager requestAlwaysAuthorization]; + [self.CLlocationManager requestWhenInUseAuthorization]; + [self.CLlocationManager startUpdatingLocation]; + + } +} +#pragma mark- 定位数据 +//疑似无用的 +- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation{ + + if(!updatingLocation) + return ; + + if (userLocation.location.horizontalAccuracy < 0) + { + return ; + } +} +// +- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode{ + self.signal = location.horizontalAccuracy; + //根据信号强度设置信号强度的照片 + if (self.signal < 20 ) { + //信号强 + self.Mainview.GPSSignal.image = [UIImage imageNamed:@"信号三格"]; + }else if(self.signal < 70){ + //信号中等 + self.Mainview.GPSSignal.image = [UIImage imageNamed:@"信号二格"]; + }else{ + //信号差 + self.Mainview.GPSSignal.image = [UIImage imageNamed:@"信号一格"]; + } + //GPS信号大于0。小于80的时候进来 + if (self.signal < 80 && self.signal >0){ + if (self.locationArray.count == 0) { + + RunLocationModel *StartPointModel = [[RunLocationModel alloc] init]; + StartPointModel.location = location.coordinate; + StartPointModel.speed = location.speed; + self.maxSpeed = location.speed; + StartPointModel.time = location.timestamp; + [self.locationArray addObject:StartPointModel];//向位置数组里面添加第一个定位点 + [self.drawLineArray addObject:StartPointModel];//向绘制轨迹点的数组里添加第一个定位点 + //展示配速 + int speedMinutes = (int)(1000/StartPointModel.speed)/60; + int speedSeconds = (int)(1000/StartPointModel.speed)%60; + if (speedMinutes > 99) { + self.Mainview.speedNumberLbl.text = @"--'--''"; + }else{ + self.Mainview.speedNumberLbl.text = [NSString stringWithFormat:@"%d'%d''",speedMinutes,speedSeconds]; + } + }else if (self.locationArray.count != 0) { + RunLocationModel *LastlocationModel = self.locationArray.lastObject; + //当前定位的位置信息model + RunLocationModel *currentModel = [[RunLocationModel alloc] init]; + currentModel.location = location.coordinate; + currentModel.time = location.timestamp; + currentModel.speed = location.speed; + //比较此处定位点的速度是否比最大速度大,是的话将其赋值给最大速度 + if (self.maxSpeed < currentModel.speed) { + self.maxSpeed = currentModel.speed; + } + double meters = [self distanceWithLocation:LastlocationModel andLastButOneModel:currentModel]; + //过滤偏移 + if (currentModel.speed < 13) { + self.locationModel = currentModel; + [self.locationArray addObject:self.locationModel]; //向位置数组里添加跑步过程中每次定位的定位点 + double KMeters = meters/1000; + self.distance = self.distance + KMeters; + self.Mainview.numberLabel.text = [NSString stringWithFormat:@"%.02f",self.distance]; + + //计算配速 + int speedMinutes = (int)(1000/self.locationModel.speed)/60; + int speedSeconds = (int)(1000/self.locationModel.speed)%60; + if (speedMinutes > 99) { + self.Mainview.speedNumberLbl.text = @"--'--''"; + }else{ + self.Mainview.speedNumberLbl.text = [NSString stringWithFormat:@"%d'%d''",speedMinutes,speedSeconds]; + } + //计算燃烧千卡 + self.kcal = 60 * KMeters * 1.036; + self.Mainview.energyNumberLbl.text = [NSString stringWithFormat:@"%d",(int)self.kcal]; + } + +#pragma mark- 绘制轨迹 + //为了美化移动的轨迹,移动的位置超过10米,才添加进绘制轨迹的的数组 + if (meters >= 5) { + RunLocationModel *lineLastPointLocation = [self.drawLineArray lastObject]; + //开始绘制轨迹 + CLLocationCoordinate2D linePoints[2]; + linePoints[0] = lineLastPointLocation.location; + linePoints[1] = self.locationModel.location; + //调用addOverlay方法后回进入 renderForOverlay 方法,完成对轨迹的绘制 + MAPolyline *lineSection = [MAPolyline polylineWithCoordinates:linePoints count:2]; + [self.Mainview.mapView addOverlay:lineSection]; + [self.drawLineArray addObject:self.locationModel]; //为绘制轨迹的位置数组添加新的元素 + NSLog(@"绘制轨迹的数组内的元素个数为%lu-----位置数组内的元素个数为%lu",(unsigned long)self.drawLineArray.count,(unsigned long)self.locationArray.count); + } + } + } +} +//疑似无用的 +- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ + if (self.locationArray.count == 0) { + self.locationModel = [[RunLocationModel alloc] init]; + CLLocation *location = [locations firstObject]; + self.locationModel.LOCATION = location; + self.locationModel.location = location.coordinate; + [self.locationArray addObject:self.locationModel]; + }else if (self.locationArray.count != 0){ + RunLocationModel *currentModel = [[RunLocationModel alloc] init]; + currentModel.LOCATION = [locations firstObject]; + + + } +} + //计算距离 +-(CLLocationDistance )distanceWithLocation:(RunLocationModel *)lastModel andLastButOneModel:(RunLocationModel *)lastButOneModel{ + CLLocationDistance Meters = 0; + MAMapPoint point1 = MAMapPointForCoordinate(lastModel.location); + MAMapPoint point2 = MAMapPointForCoordinate(lastButOneModel.location); + //2.计算距离 + CLLocationDistance newdistance = MAMetersBetweenMapPoints(point1,point2); + Meters = newdistance; + return Meters; +} + +#pragma mark- 绘制定位大头针 + //自定义大头针 +- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation{ + + // 自定义userlocation的大头针 + if ([annotation isKindOfClass:[MAUserLocation class]]) { + static NSString *userLocationReuseIndetifier = @"userLocation"; + self.myAnnotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:userLocationReuseIndetifier]; + if (self.myAnnotationView == nil) { + self.myAnnotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:userLocationReuseIndetifier]; + } + self.myAnnotationView.image = [UIImage imageNamed:@"userAnnotation"]; + return self.myAnnotationView; + } + return nil; +} + +#pragma mark- 轨迹线的设置 +- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id )overlay{ + if ([overlay isKindOfClass:[MAPolyline class]]) { + MAPolylineRenderer *polyLineRender = [[MAPolylineRenderer alloc] initWithPolyline:overlay]; + polyLineRender.lineWidth = 8; + polyLineRender.strokeColor = [UIColor colorWithRed:123/255.0 green:183/255.0 blue:196/255.0 alpha:1.0]; //折线颜色 + return polyLineRender; + } + return nil; +} + +#pragma mark- 关于时间 +//跑步时间开始 +- (void)startTimer{ + self.second++; + if (self.second == 86400) { + self.second = 0; + } + NSLog(@"%d",self.second); + //将秒数转化为HH:MM:SS格式 + NSString *timeString = [RecordtimeString getTimeStringWithSeconds:self.second]; + //获取跑步时间 + self.Mainview.timeNumberLbl.text = timeString; + self.timeString = timeString; + + //如果有一分钟了执行一下操作 + if (self.second%60 == 0) { + self.endTime = [ZYLTimeStamp getTimeStamp]; + [self caculatePace]; //获取这一分钟内的步数 + self.beginTime = self.endTime; + } + +} + +#pragma mark- 按钮的方法 +//按钮方法 +- (void)btnFunction{ + //暂停按钮 + [self.Mainview.pauseBtn addTarget:self action:@selector(pauseMethod) forControlEvents:UIControlEventTouchUpInside]; + + //锁屏按钮 + [self.Mainview.lockBtn addTarget:self action:@selector(lockMethod) forControlEvents:UIControlEventTouchUpInside]; + + //解锁按钮 + [self.Mainview.unlockLongPressView addTarget:self select:@selector(unlockMethod)]; + + + //继续按钮 + [self.Mainview.continueBtn addTarget:self action:@selector(continueMethod) forControlEvents:UIControlEventTouchUpInside]; + + //结束按钮 + [self.Mainview.endLongPressView addTarget:self select:@selector(endMethod)]; +} + +//点击暂停按钮的方法 +- (void)pauseMethod{ + //计时器暂停 + [self.runTimer setFireDate:[NSDate distantFuture]]; + //定位暂停 + [self.locationManager stopUpdatingLocation]; + + //按钮的变化 + self.Mainview.pauseBtn.hidden = YES; + self.Mainview.lockBtn.hidden = YES; + self.Mainview.unlockLongPressView.hidden = YES; + + self.Mainview.endLongPressView.hidden = NO; + self.Mainview.continueBtn.hidden = NO; +} + +//点击继续按钮方法 +- (void)continueMethod{ + //计时器继续 + [self.runTimer setFireDate:[NSDate distantPast]]; + //定位继续 + [self.locationManager startUpdatingHeading]; + + //按钮的变换 + self.Mainview.unlockLongPressView.hidden = YES; + self.Mainview.endLongPressView.hidden = YES; + self.Mainview.continueBtn.hidden = YES; + + self.Mainview.pauseBtn.hidden = NO; + self.Mainview.lockBtn.hidden = NO; + +} + +//点击锁屏按钮方法 +- (void)lockMethod{ + self.Mainview.topView.userInteractionEnabled = NO; +#pragma mark- 按钮的变换 + self.Mainview.pauseBtn.hidden = YES; + self.Mainview.lockBtn.hidden = YES; + self.Mainview.endLongPressView.hidden = YES; + self.Mainview.continueBtn.hidden = YES; + self.Mainview.unlockLongPressView.hidden = NO; +} + +//长按解锁按钮方法 +- (void)unlockMethod{ + self.Mainview.topView.userInteractionEnabled = YES; +#pragma mark- 按钮的变换 + self.Mainview.unlockLongPressView.hidden = YES; + self.Mainview.endLongPressView.hidden = YES; + self.Mainview.continueBtn.hidden = YES; + self.Mainview.lockBtn.hidden = NO; + self.Mainview.pauseBtn.hidden = NO; +} + +//长按结束按钮方法 +- (void)endMethod{ + //计时器停止 +// [self.runTimer setFireDate:[NSDate distantFuture]]; + //处理步频、速度数组 + [self caculateSpeedAndStepsArys]; + self.mileage = self.distance; //总路程 + self.duration = self.second; //总时间 +// //获取当前日期 + NSDate *date = [NSDate date]; + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + [formatter setDateFormat:@"yyyy-MM-dd"]; + self.finishDate = [formatter stringFromDate:date]; + + //弹出提示框 + if (self.second < 60 || self.distance < 0.1) { + SZHAlertView *shortAlert = [[SZHAlertView alloc] initWithTitle:@"本次跑步距离过短,无法保存记录,确定结束吗?"]; + [self.view addSubview:shortAlert]; + shortAlert.frame = self.view.frame; + [shortAlert.endBtn addTarget:self action:@selector(shortEndRun) forControlEvents:UIControlEventTouchUpInside]; + [shortAlert.ContinueRunBtn addTarget:self action:@selector(continueRun1) forControlEvents:UIControlEventTouchUpInside]; + self.shortAlert = shortAlert; + }else{ + SZHAlertView *endAlert = [[SZHAlertView alloc] initWithTitle:@"您确定要结束跑步吗?"]; + [self.view addSubview:endAlert]; + endAlert.frame = self.view.frame; + [endAlert.endBtn addTarget:self action:@selector(endRun) forControlEvents:UIControlEventTouchUpInside]; + [endAlert.ContinueRunBtn addTarget:self action:@selector(continueRun2) forControlEvents:UIControlEventTouchUpInside]; + self.normalAlert = endAlert; + } +} + +//距离过短时的按钮 + //结束 +/** + 此处应当是直接跳转到首页,不会跳转到跑步结束页,也不会上传跑步数据,最后进行处理 + */ +- (void)shortEndRun{ +// MRTabBarController *cv = [[MRTabBarController alloc] init]; +//// MRMainTabBarController *cv = [[MRMainTabBarController alloc] init]; +// [[NSNotificationCenter defaultCenter] postNotificationName:@"showTabBar" object:nil]; +// [self.navigationController pushViewController:cv animated:YES]; +//// [self.navigationController popToRootViewControllerAnimated:YES]; + + MGDDataViewController *overVC = [[MGDDataViewController alloc] init]; + //属性传值 + overVC.distanceStr = self.Mainview.numberLabel.text; //跑步距离 + overVC.speedStr = self.Mainview.speedNumberLbl.text; //配速 + overVC.cacultedStepsAry = self.caculateStepsAry; //处理后的步频数组 + overVC.caculatedSpeedAry = self.caculateSpeedAry; //处理后的速度数组 + overVC.averageSpeed = self.averageStepFrequency; //平均速度 + overVC.maxSpeed = self.maxSpeed; //最大速度 + overVC.averageStepFrequency = self.averageStepFrequency; //平均步频 + overVC.maxStepFrequency = self.maxStepFrequency; //最大步频 + overVC.timeStr = self.timeString; //时间 + overVC.energyStr = self.Mainview.energyNumberLbl.text; //千卡 + overVC.drawLineAry = self.drawLineArray; + overVC.locationAry = self.locationArray; + self.hidesBottomBarWhenPushed = YES; + [self.navigationController pushViewController:overVC animated:YES]; + [[NSNotificationCenter defaultCenter]postNotificationName:@"hideTabBar" object:nil]; +} + +- (void)continueRun1{ + + [self.shortAlert removeFromSuperview]; +} + +//正常结束 + //结束 +- (void)endRun{ + //异步执行网络请求,上传跑步数据 + dispatch_async(dispatch_get_global_queue(0, 0), ^{ + [self handUpData]; + }); + //回到主线程去执行界面跳转以及属性传值 + dispatch_async(dispatch_get_main_queue(), ^{ + //跳转到下一个页面 + MGDDataViewController *overVC = [[MGDDataViewController alloc] init]; + //属性传值 + overVC.distanceStr = self.Mainview.numberLabel.text; //跑步距离 + overVC.speedStr = self.Mainview.speedNumberLbl.text; //配速 + overVC.cacultedStepsAry = self.caculateStepsAry; //处理后的步频数组 + overVC.caculatedSpeedAry = self.caculateSpeedAry; //处理后的速度数组 + overVC.averageSpeed = self.averageStepFrequency; //平均速度 + overVC.maxSpeed = self.maxSpeed; //最大速度 + overVC.averageStepFrequency = self.averageStepFrequency; //平均步频 + overVC.maxStepFrequency = self.maxStepFrequency; //最大步频 + overVC.timeStr = self.timeString; //时间 + overVC.energyStr = self.Mainview.energyNumberLbl.text; //千卡 + overVC.drawLineAry = self.drawLineArray; + overVC.locationAry = self.locationArray; + self.hidesBottomBarWhenPushed = YES; + [self.navigationController pushViewController:overVC animated:YES]; + [[NSNotificationCenter defaultCenter]postNotificationName:@"hideTabBar" object:nil]; + }); +} + //继续跑步 +- (void)continueRun2{ + [self.normalAlert removeFromSuperview]; +} + +#pragma mark-步频和配速 +//步频 +- (void)caculatePace{ + GYYHealthManager *healthManager = [GYYHealthManager shareInstance]; + [healthManager authorizeHealthKit:^(BOOL success, NSError * _Nonnull error){ + __weak typeof(self) weakSelf = self; //block里避免循环引用,要用__weak 弱引用self 避免循环引用 + __block NSString *steps; //不是属性的基本类型,要用__block修饰 + //异步去读取跑步时的步数 + dispatch_async(dispatch_get_global_queue(0, 0), ^{ + [healthManager getStepCountFromBeginTime:[ZYLTimeStamp getDateFromTimeStamp:self.beginTime] ToEndTime:[ZYLTimeStamp getDateFromTimeStamp:self.endTime] completion:^(double stepValue, NSError * _Nonnull error) { + //找出最大的步频 + if (weakSelf.stepsAry.count == 0) { + self.maxStepFrequency = (int)stepValue; + }else if(weakSelf.stepsAry.count != 0){ + if (self.maxStepFrequency < (int)stepValue) { + self.maxStepFrequency = (int)stepValue; + } + } + steps = [[NSNumber numberWithDouble:stepValue] stringValue]; + }]; + //回到主线程 + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf.stepsAry addObject:steps]; + }); + }); + }]; +} + +//处理步频和速度的数组 +- (void)caculateSpeedAndStepsArys{ + //处理步频数组 + if (self.stepsAry != 0) { + NSMutableArray *stepsMuteAry = [NSMutableArray array]; + double totleSteps = 0; + for (int i = 0; i < self.stepsAry.count; i += 5) { + NSString *stepStr = self.stepsAry[i]; + int stepsValue = [stepStr intValue]; + // int stepsValue = [self.stepsAry[i] intValue]; + totleSteps = totleSteps + stepsValue; //求总步数 + [stepsMuteAry addObject:stepStr]; + } + self.caculateStepsAry = stepsMuteAry; + self.averageStepFrequency = totleSteps/self.caculateStepsAry.count; //平均步频 + } + NSLog(@"----平均步频为%d",self.averageStepFrequency); + + //处理速度数组 + if (self.locationArray.count != 0) { + NSMutableArray *speedMuteAry = [NSMutableArray array]; + double totleSpeeds = 0; + for (int i = 0; i < self.locationArray.count; i += 160) { + RunLocationModel *Model = self.locationArray[i]; + double speed = Model.speed; + totleSpeeds = totleSpeeds + speed; + NSString *speedStr = [[NSNumber numberWithDouble:speed] stringValue]; + [speedMuteAry addObject:speedStr]; + } + self.caculateSpeedAry = speedMuteAry; + self.averageSpeed = totleSpeeds/self.caculateSpeedAry.count; + } +#warning 如果用下面的排序,程序会崩溃 +// //排序找出最大速度 +// RunLocationModel *Model = self.caculateSpeedAry[0]; +// self.maxSpeed = Model.speed; +// for (int i = 1; i < self.caculateSpeedAry.count; i++) { +// RunLocationModel *model = self.caculateSpeedAry[i]; +// double speed = model.speed; +// if (self.maxSpeed < speed) { +// self.maxSpeed = speed; +// } +// } +} + +#pragma mark- 网络请求上传跑步数据 +- (void)handUpData{ + + //创建要穿上去的数据字典 + NSMutableDictionary *paramDic = [NSMutableDictionary new]; + [paramDic setObject:self.locationArray forKey:@"path"]; //跑步沿途路径 + NSString *duration = [[NSNumber numberWithDouble:self.duration] stringValue]; + [paramDic setObject:duration forKey:@"duration"]; //跑步总时间 + [paramDic setObject:self.Mainview.numberLabel.text forKey:@"mileage"]; //跑步总距离 + [paramDic setObject:self.Mainview.energyNumberLbl.text forKey:@"kcal"]; + NSString *averageSpeedStr = [[NSNumber numberWithDouble:self.averageSpeed] stringValue]; + [paramDic setObject:averageSpeedStr forKey:@"averageSpeed"]; //平均速度 + NSString *averageStepFrequencyStr = [[NSNumber numberWithInt:self.averageStepFrequency] stringValue]; + [paramDic setObject:averageStepFrequencyStr forKey:@"averageStepFrequency"]; //平均步频 + NSString *maxSpeedStr = [[NSNumber numberWithDouble:self.maxSpeed] stringValue]; + [paramDic setObject:maxSpeedStr forKey:@"maxSpeed"]; //最大速度 + NSString *maxStepFrequencyStr = [[NSNumber numberWithInt:self.maxStepFrequency] stringValue]; + [paramDic setObject:maxStepFrequencyStr forKey:@"maxStepFrequency"]; //最大步频 + [paramDic setObject:self.finishDate forKey:@"finishDate"]; //完成日期 + [paramDic setObject:self.caculateStepsAry forKey:@"stepFrequency"]; //处理后的步频数组 + [paramDic setObject:self.caculateSpeedAry forKey:@"speed"]; //处理后的速度数组 + + AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + NSString *token = [user objectForKey:@"token"]; + // 请求 TCP/IP http + AFHTTPRequestSerializer *requestSerializer = [AFHTTPRequestSerializer serializer]; + //添加请求头 + [requestSerializer setValue:token forHTTPHeaderField:@"token"]; + [manager setRequestSerializer:requestSerializer]; + // 响应 + AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer]; + [responseSerializer setRemovesKeysWithNullValues:YES]; //去除空值 + responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObjectsFromSet:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html", @"text/plain",@"application/atom+xml",@"application/xml",@"text/xml",nil]]; //设置接收内容的格式 + [manager setResponseSerializer:responseSerializer]; + [manager POST:HandUpRunData parameters:paramDic success:^(NSURLSessionDataTask *task, id responseObject) { + NSLog(@"-----------上传数据成功,得到的结果为%@",responseObject); + NSLog(@"---------···上传的数据为%@",paramDic); + } failure:^(NSURLSessionDataTask *task, NSError *error) { + NSLog(@"上传跑步数据失败,结果为%@",error); + }]; + +} + +#pragma mark- 关于后台定位需要调用的代理方法 +- (void)amapLocationManager:(AMapLocationManager *)manager doRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} +- (void)mapViewRequireLocationAuth:(CLLocationManager *)locationManager{ + [locationManager requestAlwaysAuthorization]; +} +@end diff --git a/MRRunning/RunningMainPageView.h b/MRRunning/RunningMainPageView.h new file mode 100644 index 0000000..0acf0f2 --- /dev/null +++ b/MRRunning/RunningMainPageView.h @@ -0,0 +1,59 @@ +// +// RunningMainPageView.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/10. +// +#import +#import +#import +#import +#import "LongPressView.h" +#import "RunMainBtn.h" +NS_ASSUME_NONNULL_BEGIN + +@interface RunningMainPageView : UIView +@property (nonatomic, strong) MAMapView *mapView; +@property (nonatomic, strong) UIImageView *GPSImgView; +@property (nonatomic, strong) UIImageView *GPSSignal; +@property (nonatomic, strong) UILabel *numberLabel; +@property (nonatomic, strong) UILabel *milesLabel; +@property (nonatomic, strong) UIView *bottomView; +@property (nonatomic, strong) UIView *topView; + +@property (nonatomic, strong) UILabel *dragLabel; +@property (nonatomic, strong) UIImageView *speedImgView; +@property (nonatomic, strong) UIImageView *timeImgView; +@property (nonatomic, strong) UIImageView *energyImgView; +@property (nonatomic, strong) UILabel *speedNumberLbl; +@property (nonatomic, strong) UILabel *timeNumberLbl; +@property (nonatomic, strong) UILabel *energyNumberLbl; +@property (nonatomic, strong) UILabel *timeLbl; +@property (nonatomic, strong) UILabel *speedLbl; +@property (nonatomic, strong) UILabel *energyLbl; + +//关于button +@property (nonatomic, strong) UIButton *lockBtn; +@property (nonatomic, strong) RunMainBtn *pauseBtn; +@property (nonatomic, strong) RunMainBtn *continueBtn; +@property (nonatomic, strong) LongPressView *endLongPressView; +@property (nonatomic, strong) LongPressView *unlockLongPressView; + +@property (nonatomic, strong) UIImageView *pauseImgView; +@property (nonatomic, strong) UIImageView *continueImgView; +@property (nonatomic, strong) UIImageView *endImgView; +@property (nonatomic, strong) UILabel *pauseLabel; +@property (nonatomic, strong) UILabel *continueLabel; +@property (nonatomic, strong) UILabel *endLabel; +@property (nonatomic, strong) UIImageView *unlockImgView; +@property (nonatomic, strong) UILabel *unlockLabel; + +@property (nonatomic, strong) UILabel *dragLable; +@property (nonatomic, strong) UIImageView *dragimageView; +- (void)mainRunView; +- (void)addMapView; +- (void)addViewOnMap; +- (void)addViewOnBottomView; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/RunningMainPageView.m b/MRRunning/RunningMainPageView.m new file mode 100644 index 0000000..9534f94 --- /dev/null +++ b/MRRunning/RunningMainPageView.m @@ -0,0 +1,426 @@ +// +// RunningMainPageView.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/10. +// + +#import "RunningMainPageView.h" + +#import +#import +#import +#import +//屏幕的宽和高 +#define kScreenWidth [UIScreen mainScreen].bounds.size.width +#define kScreenHight [UIScreen mainScreen].bounds.size.height + +@implementation RunningMainPageView + +//初始化View +- (void)mainRunView{ + [self addMapView]; + [self addViewOnMap]; + [self addViewOnBottomView]; + [self addViewOnTopView]; + + + + +} + +//添加地图视图 +- (void)addMapView{ + //添加地图 + self.mapView = [[MAMapView alloc] init]; + self.mapView.mapType = MAMapTypeStandard; //设置地图类型 + //定位以后改变地图的图层显示 + [self.mapView setUserTrackingMode:MAUserTrackingModeFollow animated:YES]; + [self addSubview:self.mapView]; + + //设置地图位置: + [self.mapView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self); + make.left.right.equalTo(self); + make.bottom.equalTo(self); + }]; + //设置地图相关属性 + self.mapView.zoomLevel = 18; + self.mapView.showsUserLocation = YES; + self.mapView.pausesLocationUpdatesAutomatically = NO; + self.mapView.showsCompass = NO; + self.mapView.showsScale = NO; + self.mapView.userInteractionEnabled = YES; + [self.mapView setAllowsBackgroundLocationUpdates:YES];//打开后台定位 + self.mapView.customizeUserLocationAccuracyCircleRepresentation = YES; + + //自定义用户位置小蓝点 + MAUserLocationRepresentation *r = [[MAUserLocationRepresentation alloc] init]; + r.showsAccuracyRing = NO;//不显示精度圈 +// r.image = [UIImage imageNamed:@"userAnnotation"]; + [self.mapView updateUserLocationRepresentation:r]; +// UIAlertController + // +} + +//在地图上添加控件 +- (void)addViewOnMap{ + //设置一个未显示地图时白色的蒙板 + self.topView = [[UIView alloc] init]; + [self.mapView addSubview:self.topView]; + [self.topView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.top.right.bottom.equalTo(self.mapView); +// make.bottom.equalTo(self.bottomView.mas_top); + }]; + //适配深色模式 + if (@available(iOS 11.0, *)) { + self.topView.backgroundColor = WhiteColor; + } else { + // Fallback on earlier versions + } + self.topView.alpha = 0.6; + + + //下面的白色View + self.bottomView = [[UIView alloc] init]; + [self.mapView addSubview:self.bottomView]; + [self.bottomView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.mas_top).offset(kScreenHight * 0.5369); + make.bottom.equalTo(self.mapView.mas_bottom); +// make.height.mas_equalTo(kScreenHight * 0.4631); + make.width.mas_equalTo(kScreenWidth); + }]; + //适配深色模式 + if (@available(iOS 11.0, *)) { + self.bottomView.backgroundColor = WhiteColor; + } else { + // Fallback on earlier versions + } + self.bottomView.layer.cornerRadius = 22; + self.bottomView.layer.shadowColor = [UIColor colorWithRed:73/255.0 green:80/255.0 blue:90/255.0 alpha:0.1].CGColor; + self.bottomView.layer.shadowOpacity = 1; + self.bottomView.layer.shadowRadius = 6; + + //左上角的GPS图标 + self.GPSImgView = [[UIImageView alloc] init]; + [self.mapView addSubview:self.GPSImgView]; + [self.GPSImgView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.mapView.mas_left).offset(kScreenWidth * 0.04); + make.top.equalTo(self.mapView.mas_top).offset(kScreenHight * 0.0739); + make.size.mas_equalTo(CGSizeMake(28, 28)); + }]; + self.GPSImgView.backgroundColor = [UIColor clearColor]; +// self.GPSImgView.alpha = 0.05; + self.GPSImgView.image = [UIImage imageNamed:@"GPS"]; + + //左上角的GPS信号 + self.GPSSignal = [[UIImageView alloc] init]; + [self.mapView addSubview:self.GPSSignal]; + [self.GPSSignal mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.GPSImgView.mas_right).offset(screenWidth * 0.0213); + make.centerY.equalTo(_GPSImgView); + make.size.mas_equalTo(CGSizeMake(34, 18)); + }]; + self.GPSSignal.backgroundColor = [UIColor clearColor]; +} + +//在底部视图上添加控件 +- (void)addViewOnBottomView{ +#pragma mark- 配速相关 + //图片框 + self.speedImgView = [[UIImageView alloc] init]; + [self.bottomView addSubview:self.speedImgView]; + [self.speedImgView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.mas_left).offset(kScreenWidth * 0.1707); + make.top.equalTo(self.bottomView.mas_top).offset(kScreenHight * 0.0435); + make.size.mas_equalTo(CGSizeMake(30, 30)); + }]; + self.speedImgView.image = [UIImage imageNamed:@"配速灰"]; + + //显示数字的lable + self.speedNumberLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.speedNumberLbl]; + [self.speedNumberLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.speedImgView); + make.top.equalTo(self.speedImgView.mas_bottom).offset(kScreenHight * 0.0224); + make.size.mas_equalTo(CGSizeMake(90, 34)); + }]; + self.speedNumberLbl.font = [UIFont fontWithName:@"Impact" size:28]; + +// [UIFont fontWithName:@"Impact" size: 82]; + if (@available(iOS 11.0, *)) { + self.speedNumberLbl.textColor = SpeedTextColor; + } else { + // Fallback on earlier versions + } + self.speedNumberLbl.textAlignment = NSTextAlignmentCenter; + self.speedNumberLbl.text = @"3'55''"; + + //显示“配速”的label + self.speedLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.speedLbl]; + [self.speedLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.speedImgView.mas_centerX); + make.top.equalTo(self.speedNumberLbl.mas_bottom).offset(kScreenHight * 0.0074); + make.size.mas_equalTo(CGSizeMake(54, 24)); + }]; + self.speedLbl.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 14]; + self.speedLbl.textColor = [UIColor colorWithRed:178/255.0 green:178/255.0 blue:178/255.0 alpha:1.0]; + self.speedLbl.textAlignment = NSTextAlignmentCenter; + self.speedLbl.text = @"配速"; + + +#pragma mark- 时间相关 + //时间的图片 + self.timeImgView = [[UIImageView alloc] init]; + [self.bottomView addSubview:self.timeImgView]; + [self.timeImgView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.speedImgView.mas_centerY); +// make.left.equalTo(self.speedImgView.mas_right).offset(kScreenWidth * 0.256); + make.centerX.equalTo(self.mas_centerX); + make.size.mas_equalTo(CGSizeMake(30, 30)); + }]; + self.timeImgView.image = [UIImage imageNamed:@"时间灰"]; + + //显示时间的数字的lable + self.timeNumberLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.timeNumberLbl]; + [self.timeNumberLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.timeImgView); + make.centerY.equalTo(self.speedNumberLbl); + make.size.mas_equalTo(CGSizeMake(108, 34)); + }]; + self.timeNumberLbl.font = self.speedNumberLbl.font; + self.timeNumberLbl.textColor = self.speedNumberLbl.textColor; + self.timeNumberLbl.textAlignment = self.speedNumberLbl.textAlignment; + self.timeNumberLbl.text = @"00:00:00"; + + //显示“时间”的label + self.timeLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.timeLbl]; + [self.timeLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.timeImgView.mas_centerX); + make.centerY.equalTo(self.speedLbl.mas_centerY); + make.size.mas_equalTo(CGSizeMake(54, 24)); + }]; + self.timeLbl.font = self.speedLbl.font; + self.timeLbl.textColor = self.speedLbl.textColor; + self.timeLbl.textAlignment = NSTextAlignmentCenter; + self.timeLbl.text = @"时间"; + + +#pragma mark- 燃烧卡路里 + //燃烧卡路里的图标 + self.energyImgView = [[UIImageView alloc] init]; + [self.bottomView addSubview:self.energyImgView]; + [self.energyImgView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.speedImgView); + make.right.equalTo(self.mas_right).offset(-kScreenWidth * 0.1707); + make.size.mas_equalTo(CGSizeMake(30, 30)); + }]; + self.energyImgView.image = [UIImage imageNamed:@"千卡灰色"]; + + //燃烧多少卡路里的数字 + self.energyNumberLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.energyNumberLbl]; + [self.energyNumberLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.energyImgView); + make.centerY.equalTo(self.speedNumberLbl); + make.size.mas_equalTo(CGSizeMake(90, 34)); + }]; + self.energyNumberLbl.font = self.speedNumberLbl.font; + self.energyNumberLbl.textColor = self.speedNumberLbl.textColor; + self.energyNumberLbl.textAlignment = NSTextAlignmentCenter; + self.energyNumberLbl.text = @"71"; + + //显示“卡路里”的lable + self.energyLbl = [[UILabel alloc] init]; + [self.bottomView addSubview:self.energyLbl]; + [_energyLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.energyImgView); + make.centerY.equalTo(self.speedLbl); + make.size.mas_equalTo(CGSizeMake(46, 24)); + }]; + self.energyLbl.font = self.speedLbl.font; + self.energyLbl.textColor = self.speedLbl.textColor; + self.energyLbl.text = @"千卡"; + self.energyLbl.textAlignment = NSTextAlignmentCenter; + + + #pragma mark- 可拖拽使得View高度变化的label + self.dragLabel = [[UILabel alloc] init]; +// _dragLabel.backgroundColor = [UIColor redColor]; + [self.bottomView addSubview:self.dragLabel]; + [self.dragLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.speedLbl.mas_left); + make.right.equalTo(self.energyLbl.mas_right); + make.top.equalTo(self.bottomView.mas_top); + make.bottom.equalTo(self.timeImgView.mas_top); + }]; + + #pragma mark- 关于按钮 + +#pragma mark- 锁屏按钮 + self.lockBtn = [[UIButton alloc] init]; + [self.bottomView addSubview:self.lockBtn]; + [self.lockBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.speedImgView); + make.top.equalTo(self.speedLbl.mas_bottom).offset(kScreenHight * 0.0843); + make.size.mas_equalTo(CGSizeMake(24, 26)); + }]; + //图片 + UIImageView *lockImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"smallLockImage"]]; + [self.lockBtn addSubview:lockImageView]; + [lockImageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.top.bottom.equalTo(self.lockBtn); + }]; + + #pragma mark- 暂停按钮 + self.pauseBtn = [[RunMainBtn alloc] init]; + [self.pauseBtn initRunBtn]; + [self.bottomView addSubview:self.pauseBtn]; + [self.pauseBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.timeImgView); + make.centerY.equalTo(self.lockBtn); + make.size.mas_equalTo(CGSizeMake(90, 90)); + }]; + self.pauseBtn.layer.cornerRadius = 45; +// self.pauseBtn.clipsToBounds = YES; + self.pauseBtn.layer.masksToBounds = 45 ? YES : NO; + if (@available(iOS 11.0, *)) { + self.pauseBtn.backgroundColor = GrayColor; + } else { + // Fallback on earlier versions + } + //图片 + self.pauseBtn.logoImg.image = [UIImage imageNamed:@"pauseBtnImage"]; + + self.pauseBtn.descLbl.text = @"暂停"; + self.pauseBtn.hidden = NO; + + + #pragma mark- 结束的View (相当于button) + self.endLongPressView = [[LongPressView alloc] init]; + [self.endLongPressView initLongPressView]; + [self.bottomView addSubview:self.endLongPressView]; + [self.endLongPressView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.mas_left).offset(kScreenWidth * 0.2213); + make.top.equalTo(self.bottomView.mas_top).offset(kScreenHight * 0.2153); + make.size.mas_equalTo(CGSizeMake(102, 102)); + }]; + self.endLongPressView.bgView.backgroundColor = [UIColor colorWithRed:255/255.0 green:92/255.0 blue:119/255.0 alpha:1.0]; + + //设置titlelabel + self.endLongPressView.titleLbl.textColor = self.pauseLabel.textColor; + self.endLongPressView.titleLbl.text = @"长按结束"; + //图片框的图片 + self.endLongPressView.imgView.image = [UIImage imageNamed:@"endBtnImage"]; + + self.endLongPressView.layer.cornerRadius = 51; + self.endLongPressView.layer.masksToBounds = YES; + + self.endLongPressView.hidden = YES; + + + #pragma mark- 继续按钮 + self.continueBtn = [[RunMainBtn alloc] init]; + [self.continueBtn initRunBtn]; + [self.bottomView addSubview:self.continueBtn]; + [self.continueBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.endLongPressView); + make.left.equalTo(self.endLongPressView.mas_right).offset(kScreenWidth * 0.08); + make.size.mas_equalTo(CGSizeMake(90, 90)); + }]; + //图片 + self.continueBtn.logoImg.image = [UIImage imageNamed:@"continueBtnImage"]; + self.continueBtn.descLbl.text = @"继续"; + + self.continueBtn.backgroundColor = [UIColor colorWithRed:85/255.0 green:213/255.0 blue:226/255.0 alpha:1.0]; + self.continueBtn.layer.cornerRadius = 45; + self.continueBtn.layer.masksToBounds = YES; + self.continueBtn.hidden = YES; + + #pragma mark- 解锁的View(相当于按钮) + self.unlockLongPressView = [[LongPressView alloc] init]; + [self.unlockLongPressView initLongPressView]; + [self.bottomView addSubview:self.unlockLongPressView]; + [self.unlockLongPressView mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self.pauseBtn); + make.size.mas_equalTo(CGSizeMake(102, 102)); + }]; + + self.unlockLongPressView.titleLbl.text = @"长按解锁"; + + self.unlockLongPressView.bgView.backgroundColor = self.pauseBtn.backgroundColor; + self.unlockLongPressView.titleLbl.textColor = self.pauseLabel.textColor; + + //图片 + self.unlockLongPressView.imgView.image = [UIImage imageNamed:@"BigLockBtnImage"]; + self.unlockLongPressView.layer.cornerRadius = 51; + self.unlockLongPressView.layer.masksToBounds = YES; + + + self.unlockLongPressView.hidden = YES; +#pragma mark- 拖动的labl和图片框 + self.dragLabel = [[UILabel alloc] init]; + [self.bottomView addSubview:self.dragLabel]; + [self.dragLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.timeImgView); + make.top.equalTo(self.bottomView.mas_top); + make.bottom.equalTo(self.timeImgView.mas_top); +// make.height.mas_equalTo(@25); + make.width.mas_equalTo(screenWidth * 0.6666); + }]; + + self.dragimageView = [[UIImageView alloc] init]; + [self.dragLabel addSubview:self.dragimageView]; +// self.dragimageView.backgroundColor = [UIColor greenColor]; + self.dragimageView.image = [UIImage imageNamed:@"初始位置"]; + [self.dragimageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self.dragLabel); + make.height.mas_equalTo(15); + make.width.mas_equalTo(screenWidth * 0.2666); + }]; +} + +//在顶部视图上添加控件 +- (void)addViewOnTopView{ + //中心显示跑了多少公里数字的label + self.numberLabel = [[UILabel alloc] init]; + [self addSubview:self.numberLabel]; + [self.numberLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.mas_centerX); + make.top.equalTo(self.GPSImgView.mas_bottom).offset(kScreenHight * 0.1589); + make.height.mas_equalTo(100); + make.width.mas_equalTo(self.frame.size.width); + }]; + self.numberLabel.font = [UIFont fontWithName:@"Impact" size: 82]; + if (@available(iOS 11.0, *)) { + self.numberLabel.textColor = MilesColor; + } else { + // Fallback on earlier versions + } + self.numberLabel.textAlignment = NSTextAlignmentCenter; + self.numberLabel.text = @"4.26"; + + //显示“公里”的label + self.milesLabel = [[UILabel alloc] init]; + [self addSubview:self.milesLabel]; + [self.milesLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.numberLabel.mas_bottom); + make.centerX.equalTo(self.numberLabel.mas_centerX); + make.size.mas_equalTo(CGSizeMake(44, 30)); + }]; + self.milesLabel.font = [UIFont fontWithName:@"PingFangSC-Semibold" size: 22]; + if (@available(iOS 11.0, *)) { + self.milesLabel.textColor = MilesTxetColor; + } else { + // Fallback on earlier versions + } + self.milesLabel.textAlignment = NSTextAlignmentCenter; + self.milesLabel.text = @"公里"; + +} + + +@end diff --git a/MRRunning/SZHAlertView.h b/MRRunning/SZHAlertView.h new file mode 100644 index 0000000..d6cff3f --- /dev/null +++ b/MRRunning/SZHAlertView.h @@ -0,0 +1,21 @@ +// +// SZHAlertView.h +// MRMobileRun +// +// Created by 石子涵 on 2020/7/29. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SZHAlertView : UIView +@property (nonatomic, strong) UIView *AlertView; +@property (nonatomic, strong) UILabel *messageLbl; //信息框 +@property (nonatomic, strong) UIButton *endBtn; //结束按钮 +@property (nonatomic, strong) UIButton *ContinueRunBtn; //继续跑步按钮 + +- (instancetype)initWithTitle:(NSString *)title; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/SZHAlertView.m b/MRRunning/SZHAlertView.m new file mode 100644 index 0000000..06ae273 --- /dev/null +++ b/MRRunning/SZHAlertView.m @@ -0,0 +1,194 @@ +// +// SZHAlertView.m +// MRMobileRun +// +// Created by 石子涵 on 2020/7/29. +// +#import +#import "SZHAlertView.h" + +#define Width self.bounds.size.width +#define Height self.bounds.size.height +@implementation SZHAlertView + +- (instancetype)initWithTitle:(NSString *)title{ + if (self = [super init]) { +/** +分享的那个小界面 +*/ + UIView *AlertView = [[UIView alloc] init]; + if (@available(iOS 11.0, *)) { + AlertView.backgroundColor = SZHAlertColor; + } else { + // Fallback on earlier versions + } + [self addSubview:AlertView]; + [AlertView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.mas_left).offset(screenWidth * 0.0906); + make.top.equalTo(self.mas_top).offset(screenHeigth * 0.335); + make.size.mas_equalTo(CGSizeMake(306, 200)); + }]; + AlertView.layer.cornerRadius = 16; + AlertView.layer.shadowRadius = 6; +/* +结束按钮 + */ + self.endBtn = [[UIButton alloc] init]; + [AlertView addSubview:_endBtn]; + [self.endBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(AlertView.mas_left).offset(18); + make.top.equalTo(AlertView.mas_top).offset(136); + make.size.mas_equalTo(CGSizeMake(130, 44)); + }]; + if (@available(iOS 11.0, *)) { + self.endBtn.backgroundColor = GrayColor; + } else { + // Fallback on earlier versions + } + self.endBtn.layer.cornerRadius = 12; + + //给endBtn添加label + UILabel *endBtnTitleLel = [[UILabel alloc] init]; + if (@available(iOS 11.0, *)) { + endBtnTitleLel.textColor = SZHAlertTextColor; + } else { + // Fallback on earlier versions + } + + endBtnTitleLel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + endBtnTitleLel.text = @"结束"; + endBtnTitleLel.textAlignment = NSTextAlignmentCenter; + if (@available(iOS 11.0, *)) { + endBtnTitleLel.textColor = SZHAlertEndBtnTexteColor; + } else { + // Fallback on earlier versions + } + [self.endBtn addSubview:endBtnTitleLel]; + [endBtnTitleLel mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.mas_equalTo(self.endBtn.center); + make.height.mas_equalTo(22); + make.width.mas_equalTo(self.endBtn.mas_width); + }]; + + + /* + 继续跑步按钮 + */ + self.ContinueRunBtn = [[UIButton alloc] init]; + [AlertView addSubview:self.ContinueRunBtn]; + [self.ContinueRunBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.endBtn.mas_right).offset(11); + make.size.centerY.equalTo(self.endBtn); + }]; + self.ContinueRunBtn.titleLabel.backgroundColor = [UIColor redColor]; + //给继续跑步按钮添加lable + UILabel *continueBtnTitleLbl = [[UILabel alloc] init]; + continueBtnTitleLbl.textColor = [UIColor whiteColor]; + continueBtnTitleLbl.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + continueBtnTitleLbl.textAlignment = NSTextAlignmentCenter; + continueBtnTitleLbl.text = @"继续跑步"; + [self.ContinueRunBtn addSubview:continueBtnTitleLbl]; + [continueBtnTitleLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.mas_equalTo(self.ContinueRunBtn.center); + make.height.mas_equalTo(22); + make.width.equalTo(self.ContinueRunBtn.mas_width); + }]; + + self.ContinueRunBtn.backgroundColor = [UIColor colorWithRed:0/255.0 green:197/255.0 blue:217/255.0 alpha:1.0]; + self.ContinueRunBtn.layer.cornerRadius = 12; + + /* + 中间的label文本 + */ + self.messageLbl = [[UILabel alloc] init]; + [AlertView addSubview:self.messageLbl]; + [self.messageLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self); + make.width.mas_equalTo(216); + make.top.equalTo(AlertView.mas_top).offset(47); + make.bottom.equalTo(self.endBtn.mas_top); + }]; + self.messageLbl.numberOfLines = 0; + self.messageLbl.textAlignment = NSTextAlignmentCenter; + if (@available(iOS 11.0, *)) { + self.messageLbl.textColor = bottomTitleColor; + } else { + // Fallback on earlier versions + } + self.messageLbl.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 16]; + + self.messageLbl.text = title; + + self.AlertView = AlertView; + + [self addUnabledViews]; + } + return self; +} + +//添加四周的蒙板 +- (void)addUnabledViews{ + //顶部蒙板 + UIView *topView = [[UIView alloc] init]; + [self addSubview:topView]; + [topView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.top.right.equalTo(self); + make.bottom.equalTo(self.AlertView.mas_top); + }]; + if (@available(iOS 11.0, *)) { + topView.backgroundColor = SZHAlertViewColor; + } else { + // Fallback on earlier versions + } + topView.alpha = 0.05; + topView.userInteractionEnabled = NO; + + //左边蒙板 + UIView *leftView = [[UIView alloc] init]; + [self addSubview:leftView]; + [leftView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self); + make.right.equalTo(self.AlertView.mas_left); + make.top.bottom.equalTo(self.AlertView); + }]; + if (@available(iOS 11.0, *)) { + leftView.backgroundColor = SZHAlertViewColor; + } else { + // Fallback on earlier versions + } + leftView.alpha = 0.05; + leftView.userInteractionEnabled = NO; + + //右边的蒙板 + UIView *rightView = [[UIView alloc] init]; + if (@available(iOS 11.0, *)) { + rightView.backgroundColor = SZHAlertViewColor; + } else { + // Fallback on earlier versions + } + [self addSubview:rightView]; + [rightView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.bottom.equalTo(self.AlertView); + make.right.equalTo(self); + make.left.equalTo(self.AlertView.mas_right); + }]; + rightView.alpha = 0.05; + rightView.userInteractionEnabled = NO; + + + //下面的蒙板 + UIView *bottomView = [[UIView alloc] init]; + [self addSubview:bottomView]; + [bottomView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self); + make.top.equalTo(self.AlertView.mas_bottom); + }]; + if (@available(iOS 11.0, *)) { + rightView.backgroundColor = SZHAlertViewColor; + } else { + // Fallback on earlier versions + } + bottomView.alpha = 0.05; + bottomView.userInteractionEnabled = NO; +} +@end diff --git a/MRRunning/SZHChart.h b/MRRunning/SZHChart.h new file mode 100644 index 0000000..554bab5 --- /dev/null +++ b/MRRunning/SZHChart.h @@ -0,0 +1,44 @@ +// +// SZHChart.h +// SZHChart +// +// Created by 石子涵 on 2020/8/6. +// Copyright © 2020 石子涵. All rights reserved. +// + +#import +/****** + 显示速度的折线图 +*/ +NS_ASSUME_NONNULL_BEGIN + +@interface SZHChart : UIView +@property double YmaxNumber; //Y轴上的最大数值,默认为6 + +@property (nonatomic, strong) UILabel *topYlabel; //纵轴顶部显示单位的label +@property (nonatomic, strong) UILabel *bottomXLabel; //X轴底部显示单位的label + +@property (nonatomic, strong) NSArray*leftLblAry; //左边的文本label数组 +@property (nonatomic, strong) NSArray *lineDataAry; //在折线图上显示的数据的数组 + +@property unsigned long bottomXCount; //底部X轴的刻度点,默认为6 + +#pragma mark- 分割线 +/** 折线颜色(默认为设计图的颜色) */ +@property (nonatomic, strong) UIColor *lineColor; +/** 折线宽(默认1) */ +@property (nonatomic, assign) CGFloat lineWidth; + +/** 渐变颜色集合 */ +@property (nonatomic, strong) NSArray *colorArr; +/** 是否填充颜色渐变(默认YES) */ +@property (nonatomic, assign) BOOL showColorGradient; + + +- (void)initWithViewsWithBooTomCount:(unsigned long )bottomCout AndLineDataAry:(NSArray *)lineDataAry AndYMaxNumber:(double )YmaxNumber; +@end + + + + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/SZHChart.m b/MRRunning/SZHChart.m new file mode 100644 index 0000000..d7674c4 --- /dev/null +++ b/MRRunning/SZHChart.m @@ -0,0 +1,215 @@ +// +// SZHChart.m +// SZHChart +// +// Created by 石子涵 on 2020/8/6. +// Copyright © 2020 石子涵. All rights reserved. +// + + +#import "SZHChart.h" +#import +#import + +#define screenWidth [UIScreen mainScreen].bounds.size.width +#define screenHeight [UIScreen mainScreen].bounds.size.height +@interface SZHChart() +@property int maxY; //最高的Y轴分割线的位置 +@property double spaceY; //Y轴各刻度间的间距; +@property double spaceX; //X轴各刻度间的间距 +@property (nonatomic, strong) UIScrollView *chartScroll; + +@property (nonatomic, assign) NSArray *pointAry; + +@property (nonatomic, strong) UIColor *textColor; +@end + + + +@implementation SZHChart +//初始化视图以及一些属性的封装 +- (void)initWithViewsWithBooTomCount:(unsigned long )bottomCout AndLineDataAry:(NSArray *)lineDataAry AndYMaxNumber:(double )YmaxNumber{ + self.spaceY = screenHeight *0.0449; + self.spaceX = screenWidth * 0.0933; + self.lineColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0]; + self.lineWidth = 6; + self.lineColor = [UIColor redColor]; + self.bottomXCount = bottomCout - 1; + self.lineDataAry = lineDataAry; + self.YmaxNumber = YmaxNumber; +// self.colorArr = [NSArray arrayWithObjects:(id)[[[UIColor redColor] colorWithAlphaComponent:0.4] CGColor],(id)[[[UIColor whiteColor] colorWithAlphaComponent:0.1] CGColor], nil]; + + + //x轴单位、y轴文本、x轴文本的字体颜色 + self.textColor = [UIColor colorWithRed:136/255.0 green:136/255.0 blue:136/255.0 alpha:1.0]; + + + //显示图形的ScroolView + self.chartScroll = [[UIScrollView alloc] init]; + self.chartScroll.bounces = NO; //不回弹 + self.chartScroll.showsHorizontalScrollIndicator = YES; //不显示X轴的小滑条 + self.chartScroll.backgroundColor = [UIColor clearColor]; + self.chartScroll.contentSize = CGSizeMake( self.bottomXCount * (screenWidth * 0.1333 + 1) , self.chartScroll.bounds.size.height); //self.bottomXCount * (screenWidth * 0.1333) + [self addSubview:self.chartScroll]; + [self.chartScroll mas_makeConstraints:^(MASConstraintMaker *make) { +// make.left.equalTo(self.topYlabel.mas_right).offset(-10); + make.left.equalTo(self).offset(screenWidth * 0.04 + 28 - 10); + make.bottom.equalTo(self.mas_bottom); + // make.top.equalTo(self.topYlabel.mas_bottom); + make.height.mas_equalTo(_spaceY * 6 + 20); + make.width.mas_equalTo(screenWidth * 0.824); + }]; + + //Y轴单位label + self.topYlabel = [[UILabel alloc] init]; + [self addSubview:self.topYlabel]; + [self.topYlabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self); +// make.bottom.equalTo(self.chartScroll.mas_top); + make.left.equalTo(self.mas_left).offset(screenWidth * 0.04); + make.size.mas_equalTo(CGSizeMake(28, 16)); + }]; + self.topYlabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size:11]; + self.topYlabel.textColor = [UIColor colorWithRed:65/255.0 green:68/255.0 blue:72/255.0 alpha:1.0]; + + //X轴单位Label + self.bottomXLabel = [[UILabel alloc] init]; + [self addSubview:self.bottomXLabel]; + [self.bottomXLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.chartScroll.mas_right); + make.bottom.equalTo(self.chartScroll.mas_bottom); + make.size.mas_equalTo(CGSizeMake(16, 11)); + }]; + self.bottomXLabel.textColor = self.textColor; + self.bottomXLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 8]; + + //最左边的0 + UILabel *left0 = [[UILabel alloc] init]; + [self addSubview:left0]; + [left0 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.topYlabel); + make.bottom.equalTo(self); + make.size.mas_equalTo(CGSizeMake(15, 11)); + }]; + left0.text = @"0"; + left0.textAlignment = NSTextAlignmentRight; + left0.textColor = self.textColor; + left0.font = [UIFont fontWithName:@"PingFangSC-Regular" size:8]; + + [self drawLineChart]; + +} + +//渲染折线图 +- (void)drawLineChart{ + + NSMutableArray *muteableAry = [NSMutableArray array]; //用来存储左边label的数组 + + //绘制纵轴文本和纵轴分割线 + for (int i = 1; i < 6; i++) { + //绘制纵轴文本的label + UILabel *leftLbl = [[UILabel alloc] init]; + leftLbl.textColor = self.textColor; + leftLbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 8]; + leftLbl.textAlignment = NSTextAlignmentRight; + [self addSubview:leftLbl]; + [leftLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.topYlabel); + make.bottom.equalTo(self.mas_bottom).offset(- _spaceY*i - 20 + 7.5); + make.size.mas_equalTo(CGSizeMake(15, 11)); + }]; + + //纵轴的分割线 + CALayer *line = [[CALayer alloc] init]; + line.frame = CGRectMake(0,0 + i * _spaceY,self.chartScroll.contentSize.width, 1); + line.backgroundColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0].CGColor; + if (i == 5) { + CGFloat maxY = CGRectGetMaxY(line.frame); + self.maxY = maxY; + NSLog(@"--------------%d",self.maxY); + } + [self.chartScroll.layer addSublayer:line]; + [muteableAry addObject:leftLbl]; + } + self.leftLblAry = muteableAry; + + //绘制X轴 + CALayer *bottomline = [[CALayer alloc] init]; + bottomline.backgroundColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0].CGColor; + bottomline.frame = CGRectMake(0,6 * _spaceY,self.chartScroll.contentSize.width, 1); + [self.chartScroll.layer addSublayer:bottomline]; + + //X轴文字 + for (int i = 1; i < self.bottomXCount + 1; i++) { + UILabel *bottomlbl = [[UILabel alloc] init]; + bottomlbl.frame = CGRectMake(0 + i*_spaceX + (i-1)*15, 6 * _spaceY + 10, 15, 11); + [self.chartScroll addSubview:bottomlbl]; + bottomlbl.text = [NSString stringWithFormat:@"%d", i * 5]; + bottomlbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size:8]; + bottomlbl.textColor = self.textColor; + bottomlbl.textAlignment = NSTextAlignmentCenter; + } + //绘制折线 + [self drawLine]; + +} + +/** + * 绘制折线 + */ +- (void)drawLine{ + NSMutableArray *pointAry = [NSMutableArray array]; //用来存储关键点的数组 + for (int i = 0; i < self.lineDataAry.count; i++) { + //绘制关键点 + NSNumber * tempNum = self.lineDataAry[i]; + CGFloat ratio = tempNum.floatValue/self.YmaxNumber; + // NSLog(@"%f",ratio); + CGFloat Y = (6 * _spaceY ) * ratio; //关键点的竖直位置 + // NSLog(@"%f",Y); + CGFloat X = 8 + i*_spaceX + (i-1)*15; //关键点的横向位置 + //绘制折线 + if (pointAry.count == 0) { + NSValue *firstvalue = [NSValue valueWithCGPoint:CGPointMake(X, _spaceY * 6 - Y + _spaceY)]; + [pointAry addObject:firstvalue]; + NSLog(@"添加了一个元素%lu",(unsigned long)pointAry.count); + }else if(pointAry.count >= 0){ + //上一个坐标点 + NSValue *lastValue = pointAry.lastObject; + CGPoint lastPoint = [lastValue CGPointValue]; + //现在的坐标点 + NSValue *currentValue = [NSValue valueWithCGPoint:CGPointMake(X, _spaceY * 6 - Y + _spaceY)]; + CGPoint currentpoint = [currentValue CGPointValue]; + //设置两个控制点 + CGFloat controlX = (lastPoint.x + currentpoint.x)/2; + NSLog(@"%f",controlX); + CGPoint controlPoint1 = CGPointMake(controlX, lastPoint.y); + NSLog(@"控制点1的横纵坐标为---%f,------%f",controlPoint1.x,controlPoint1.y); + CGPoint controlPoint2 = CGPointMake(controlX, currentpoint.y); + NSLog(@"控制点2的横纵坐标为---%f,------%f",controlPoint2.x,controlPoint2.y); + UIBezierPath *linePath = [UIBezierPath bezierPath]; + linePath.lineCapStyle = kCGLineCapRound; + linePath.lineJoinStyle = kCGLineJoinMiter; + linePath.lineWidth = 6; + [linePath moveToPoint:lastPoint]; + [linePath addCurveToPoint:currentpoint controlPoint1:controlPoint1 controlPoint2:controlPoint2]; + + CAShapeLayer *lineLayer = [CAShapeLayer layer]; + lineLayer.path = linePath.CGPath; + lineLayer.strokeColor = self.lineColor.CGColor; + lineLayer.fillColor = [UIColor clearColor].CGColor; + lineLayer.lineWidth = self.lineWidth; + lineLayer.lineCap = kCALineCapRound; + lineLayer.lineJoin = kCALineJoinRound; + lineLayer.contentsScale = [UIScreen mainScreen].scale; + [self.chartScroll.layer addSublayer:lineLayer]; + + [pointAry addObject:currentValue]; + NSLog(@"元素个数为%lu",(unsigned long)pointAry.count); + } + + } +} + + +@end + diff --git a/MRRunning/SZHWaveChart.h b/MRRunning/SZHWaveChart.h new file mode 100644 index 0000000..2353bcb --- /dev/null +++ b/MRRunning/SZHWaveChart.h @@ -0,0 +1,42 @@ +// +// SZHWaveChart.h +// SZHChart +// +// Created by 石子涵 on 2020/8/8. +// Copyright © 2020 石子涵. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN +/*** + 显示步频的波浪图 + */ +@interface SZHWaveChart : UIView +@property double YmaxNumber; //Y轴上的最大数值,默认为6 + +@property (nonatomic, strong) UILabel *topYlabel; //纵轴顶部显示单位的label +@property (nonatomic, strong) UILabel *bottomXLabel; //X轴底部显示单位的label + +@property (nonatomic, strong) NSArray*leftLblAry; //左边的文本label数组 +@property (nonatomic, strong) NSArray *lineDataAry; //在折线图上显示的数据的数组 + +@property unsigned long bottomXCount; //底部X轴的刻度点,默认为6 + +#pragma mark- 分割线 +/** 折线颜色(默认为设计图的颜色) */ +@property (nonatomic, strong) UIColor *lineColor; +/** 折线宽(默认1) */ +@property (nonatomic, assign) CGFloat lineWidth; + +/** 渐变颜色集合 */ +@property (nonatomic, strong) NSArray *colorArr; +/** 是否填充颜色渐变(默认YES) */ +@property (nonatomic, assign) BOOL showColorGradient; + + +- (void)initWithViewsWithBooTomCount:(unsigned long)bottomCout AndLineDataAry:(NSArray *)lineDataAry AndYMaxNumber:(double )YmaxNumber; +@end + + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/SZHWaveChart.m b/MRRunning/SZHWaveChart.m new file mode 100644 index 0000000..13f96d1 --- /dev/null +++ b/MRRunning/SZHWaveChart.m @@ -0,0 +1,348 @@ +// +// SZHWaveChart.m +// SZHChart +// +// Created by 石子涵 on 2020/8/8. +// Copyright © 2020 石子涵. All rights reserved. +// + +#import "SZHWaveChart.h" +#import +#import + +#define screenWidth [UIScreen mainScreen].bounds.size.width +#define screenHeight [UIScreen mainScreen].bounds.size.height +@interface SZHWaveChart() +@property CGPoint lastestPoint; //最后一个坐标点 +@property CGPoint startPoint; //最开始的一个坐标点 +@property int maxY; //最高的Y轴分割线的位置 +@property double spaceY; //Y轴各刻度间的间距; +@property double spaceX; //X轴各刻度间的间距 +@property (nonatomic, strong) UIScrollView *chartScroll; + +@property (nonatomic, assign) NSArray *pointAry; + +@property (nonatomic, strong) UIColor *textColor; + +@property (strong,nonatomic) UIBezierPath *circlePath; +@end + +@implementation SZHWaveChart + +//初始化视图以及一些属性的封装 +- (void)initWithViewsWithBooTomCount:(unsigned long)bottomCout AndLineDataAry:(NSArray *)lineDataAry AndYMaxNumber:(double )YmaxNumber{ + self.spaceY = screenHeight *0.0449; + self.spaceX = screenWidth * 0.0933; + self.lineColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0]; + self.lineWidth = 6; + self.lineColor = [UIColor redColor]; + self.bottomXCount = bottomCout - 1; + self.lineDataAry = lineDataAry; + self.YmaxNumber = YmaxNumber; + self.colorArr = [NSArray arrayWithObjects:(id)[[[UIColor redColor] colorWithAlphaComponent:0.4] CGColor],(id)[[[UIColor whiteColor] colorWithAlphaComponent:0.1] CGColor], nil]; + + + //x轴单位、y轴文本、x轴文本的字体颜色 + self.textColor = [UIColor colorWithRed:136/255.0 green:136/255.0 blue:136/255.0 alpha:1.0]; + + + + //显示图形的ScroolView + self.chartScroll = [[UIScrollView alloc] init]; + self.chartScroll.bounces = NO; //不回弹 + self.chartScroll.showsHorizontalScrollIndicator = YES; //不显示X轴的小滑条 + self.chartScroll.backgroundColor = [UIColor clearColor]; + self.chartScroll.contentSize = CGSizeMake( self.bottomXCount * (screenWidth * 0.1333 + 1) , self.chartScroll.bounds.size.height); //self.bottomXCount * (screenWidth * 0.1333) + [self addSubview:self.chartScroll]; + [self.chartScroll mas_makeConstraints:^(MASConstraintMaker *make) { +// make.left.equalTo(self.topYlabel.mas_right).offset(-10); + make.left.equalTo(self).offset(screenWidth * 0.04 + 28 - 10); + make.bottom.equalTo(self.mas_bottom); +// make.top.equalTo(self.topYlabel.mas_bottom); + make.height.mas_equalTo(_spaceY * 6 + 20); + make.width.mas_equalTo(screenWidth * 0.824); + }]; + + //Y轴单位label + self.topYlabel = [[UILabel alloc] init]; + [self addSubview:self.topYlabel]; + [self.topYlabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self); +// make.bottom.equalTo(self.chartScroll.mas_top); + make.left.equalTo(self.mas_left).offset(screenWidth * 0.04); + make.size.mas_equalTo(CGSizeMake(28, 16)); + }]; + self.topYlabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 11]; + self.topYlabel.textColor = [UIColor colorWithRed:65/255.0 green:68/255.0 blue:72/255.0 alpha:1.0]; + + //X轴单位Label + self.bottomXLabel = [[UILabel alloc] init]; + [self addSubview:self.bottomXLabel]; + [self.bottomXLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.chartScroll.mas_right); + make.bottom.equalTo(self.chartScroll.mas_bottom); + make.size.mas_equalTo(CGSizeMake(16, 11)); + }]; + self.bottomXLabel.textColor = self.textColor; + self.bottomXLabel.font = [UIFont fontWithName:@"PingFangSC-Medium" size: 8]; + + //最左边的0 + UILabel *left0 = [[UILabel alloc] init]; + [self addSubview:left0]; + [left0 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.topYlabel); + make.bottom.equalTo(self); + make.size.mas_equalTo(CGSizeMake(15, 11)); + }]; + left0.text = @"0"; + left0.textAlignment = NSTextAlignmentRight; + left0.textColor = self.textColor; + left0.font = [UIFont fontWithName:@"PingFangSC-Regular" size:8]; + + [self drawLineChart]; + +} + +//渲染折线图 +- (void)drawLineChart{ + + NSMutableArray *muteableAry = [NSMutableArray array]; //用来存储左边label的数组 + + //绘制纵轴文本和纵轴分割线 + for (int i = 1; i < 6; i++) { + //绘制纵轴文本的label + UILabel *leftLbl = [[UILabel alloc] init]; + leftLbl.textColor = self.textColor; + leftLbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size: 8]; + leftLbl.textAlignment = NSTextAlignmentRight; + [self addSubview:leftLbl]; + [leftLbl mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.topYlabel); + make.bottom.equalTo(self.mas_bottom).offset(- _spaceY*i - 20 + 7.5); + make.size.mas_equalTo(CGSizeMake(15, 11)); + }]; + + //纵轴的分割线 + CALayer *line = [[CALayer alloc] init]; + line.frame = CGRectMake(0,0 + i * _spaceY,self.chartScroll.contentSize.width, 1); + line.backgroundColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0].CGColor; + if (i == 5) { + CGFloat maxY = CGRectGetMaxY(line.frame); + self.maxY = maxY; + } + [self.chartScroll.layer addSublayer:line]; + [muteableAry addObject:leftLbl]; + } + self.leftLblAry = muteableAry; + + //绘制X轴 + CALayer *bottomline = [[CALayer alloc] init]; + bottomline.backgroundColor = [UIColor colorWithRed:237/255.0 green:237/255.0 blue:237/255.0 alpha:1.0].CGColor; + bottomline.frame = CGRectMake(0,6 * _spaceY,self.chartScroll.contentSize.width, 1); + [self.chartScroll.layer addSublayer:bottomline]; + + //X轴文字 + for (int i = 1; i < self.bottomXCount + 1; i++) { + UILabel *bottomlbl = [[UILabel alloc] init]; + bottomlbl.frame = CGRectMake(0 + i*_spaceX + (i-1)*15, 6 * _spaceY + 10, 15, 11); + [self.chartScroll addSubview:bottomlbl]; + bottomlbl.text = [NSString stringWithFormat:@"%d", i * 5]; + bottomlbl.font = [UIFont fontWithName:@"PingFangSC-Regular" size:8]; + bottomlbl.textColor = self.textColor; + bottomlbl.textAlignment = NSTextAlignmentCenter; + } + //绘制折线 + [self drawLine]; + +} + +/** + * 绘制折线 + */ +- (void)drawLine{ + NSMutableArray *pointAry = [NSMutableArray array]; //用来存储关键点的数组 + //遮罩图层轨迹 + UIBezierPath *shelterBezier = [UIBezierPath bezierPath]; + shelterBezier.lineCapStyle = kCGLineCapRound; + shelterBezier.lineJoinStyle = kCGLineJoinMiter; + //折线轨迹 + UIBezierPath *linePath = [UIBezierPath bezierPath]; + linePath.lineCapStyle = kCGLineCapRound; + linePath.lineJoinStyle = kCGLineJoinMiter; + linePath.lineWidth = 1; + + CGFloat X = 0; + for (int i = 0; i < self.lineDataAry.count; i++) { + //绘制关键点 + NSNumber * tempNum = self.lineDataAry[i]; + CGFloat ratio = tempNum.floatValue/self.YmaxNumber; + // NSLog(@"%f",ratio); + CGFloat Y = (5 * _spaceY ) * ratio; //关键点的竖直位置 + // NSLog(@"%f",Y); + if (i == 0) { + X = 0; + }else{ + X = 8 + i*_spaceX + (i-1)*15; //关键点的横向位置 + } + + //绘制折线 和 遮罩层 + + if (pointAry.count == 0) { + NSValue *firstvalue = [NSValue valueWithCGPoint:CGPointMake(X, _spaceY * 6 - Y )]; + self.startPoint = [firstvalue CGPointValue]; + + NSLog(@"开始点的坐标%f,%f",self.startPoint.x,self.startPoint.y); + [pointAry addObject:firstvalue]; + NSLog(@"添加了一个元素%lu",(unsigned long)pointAry.count); + [linePath moveToPoint:self.startPoint]; + [shelterBezier moveToPoint:self.startPoint]; + }else if(pointAry.count >= 0){ + //上一个坐标点 + NSValue *lastValue = pointAry.lastObject; + CGPoint lastPoint = [lastValue CGPointValue]; + NSLog(@"上一个坐标点的坐标%f,%f",lastPoint.x,lastPoint.y); + //现在的坐标点 + NSValue *currentValue = [NSValue valueWithCGPoint:CGPointMake(X, _spaceY * 6 - Y )]; + CGPoint currentpoint = [currentValue CGPointValue]; + NSLog(@"现在的坐标点的坐标%f,%f",currentpoint.x,currentpoint.y); + + //设置两个控制点 + CGFloat controlX = (lastPoint.x + currentpoint.x)/2; +// NSLog(@"%f",controlX); + CGPoint controlPoint1 = CGPointMake(controlX, lastPoint.y); +// NSLog(@"控制点1的横纵坐标为---%f,------%f",controlPoint1.x,controlPoint1.y); + CGPoint controlPoint2 = CGPointMake(controlX, currentpoint.y); +// NSLog(@"控制点2的横纵坐标为---%f,------%f",controlPoint2.x,controlPoint2.y); + + //绘制折线 + [linePath addCurveToPoint:currentpoint controlPoint1:controlPoint1 controlPoint2:controlPoint2]; + //将折线添加到scroll上 + CAShapeLayer *lineLayer = [CAShapeLayer layer]; + lineLayer.path = linePath.CGPath; + lineLayer.strokeColor = [UIColor clearColor].CGColor; + lineLayer.fillColor = [UIColor clearColor].CGColor; + lineLayer.lineWidth = 1; + lineLayer.lineCap = kCALineCapRound; + lineLayer.lineJoin = kCALineJoinRound; + lineLayer.contentsScale = [UIScreen mainScreen].scale; + [self.chartScroll.layer addSublayer:lineLayer]; + + //绘制遮罩层 + [shelterBezier addCurveToPoint:currentpoint controlPoint1:controlPoint1 controlPoint2:controlPoint2]; + [pointAry addObject:currentValue]; + if (i == self.lineDataAry.count - 1) { + self.lastestPoint = currentpoint; + NSLog(@"最后一个坐标点的坐标为%f,%f",self.lastestPoint.x,self.lastestPoint.y); + + [self dralineWithShelterVezier:shelterBezier AndSTartP:self.startPoint]; + } +// NSLog(@"元素个数为%lu",(unsigned long)pointAry.count); + } + } + + self.pointAry = pointAry; + //图表颜色填充 +} + +/** + * 设置颜色渐变 + */ +//绘制遮罩层轨迹 + + +- (void)dralineWithShelterVezier:(UIBezierPath *)shelterBezier AndSTartP:(CGPoint )startP{ + CGFloat bgHeight = 6 * _spaceY; //得到在X轴上 + //获取最后一个点的X值 + CGFloat lastPointX = self.lastestPoint.x; + //最后一个点对应的x轴的位置 + CGPoint lastPointX1 = CGPointMake(lastPointX, bgHeight); + [shelterBezier addLineToPoint:lastPointX1]; //遮罩层轨迹绘制 + //回到原点 + [shelterBezier addLineToPoint:CGPointMake(startP.x, bgHeight)]; + + [shelterBezier addLineToPoint:startP]; //密闭 +// CAShapeLayer *shelterlineLayer = [CAShapeLayer layer]; +// shelterlineLayer.path = shelterBezier.CGPath; +// shelterlineLayer.strokeColor = [UIColor greenColor].CGColor; +// shelterlineLayer.fillColor = [UIColor clearColor].CGColor; +// shelterlineLayer.lineWidth = 8; +// shelterlineLayer.lineCap = kCALineCapRound; +// shelterlineLayer.lineJoin = kCALineJoinRound; +// shelterlineLayer.contentsScale = [UIScreen mainScreen].scale; +// [self.chartScroll.layer addSublayer:shelterlineLayer]; + [self addGradientWithBezierPath:shelterBezier]; +} + +//渐变图层 +-(void)addGradientWithBezierPath:(UIBezierPath *)beizer{ + //遮罩层 + CAShapeLayer *shadeLayer = [CAShapeLayer layer]; + shadeLayer.path = beizer.CGPath; + shadeLayer.fillColor = [UIColor greenColor].CGColor; + CAGradientLayer *gradientLayer = [CAGradientLayer layer]; + gradientLayer.frame = CGRectMake(CGRectGetMinX(self.chartScroll.frame), CGRectGetMinY(self.chartScroll.frame), self.chartScroll.contentSize.width, 6 * _spaceY); + gradientLayer.startPoint = CGPointMake(0, 0); + gradientLayer.endPoint = CGPointMake(0, 1); + gradientLayer.cornerRadius = 5; + gradientLayer.masksToBounds = YES; + gradientLayer.colors = @[(__bridge id)[UIColor colorWithRed:56/255.0 green:190/255.0 blue:216/255.0 alpha:0.8].CGColor,(__bridge id)[UIColor colorWithRed:106/255.0 green:207/255.0 blue:191/255.0 alpha:0.1].CGColor]; +// + gradientLayer.locations = @[@(0.5)]; + CALayer *baseLayer = [CALayer layer]; + [baseLayer addSublayer:gradientLayer]; + [baseLayer setMask:shadeLayer]; + [self.chartScroll.layer addSublayer:baseLayer]; +} + + + + + + + + + + + + + + + + + + + + + +//-(void)addBezierPoint:(NSArray *)pointArray andColor:(UIColor *)color andColors:(NSArray *)colors{ +// CGPoint startP = CGPointMake(0, 0); +// startP = [[pointArray objectAtIndex:0] CGPointValue]; +// //直线的连线 +// UIBezierPath *lineBeizer = [UIBezierPath bezierPath]; +// [lineBeizer moveToPoint:startP]; +// _circlePath = lineBeizer; +// //遮罩层的形状 +// UIBezierPath *shelterBezier = [UIBezierPath bezierPath]; +// shelterBezier.lineCapStyle = kCGLineCapRound; +// shelterBezier.lineJoinStyle = kCGLineJoinMiter; +// +// [shelterBezier moveToPoint:startP]; +// +// for (int i = 0;i 0) { +// CGPoint prePoint = [[pointArray objectAtIndex:i-1] CGPointValue]; +// CGPoint nowPoint = [[pointArray objectAtIndex:i] CGPointValue]; +// [lineBeizer addCurveToPoint:nowPoint controlPoint1:CGPointMake((nowPoint.x+prePoint.x)/2, prePoint.y) controlPoint2:CGPointMake((nowPoint.x+prePoint.x)/2, nowPoint.y)]; +// [lineBeizer addLineToPoint:nowPoint]; +// [shelterBezier addCurveToPoint:nowPoint controlPoint1:CGPointMake((nowPoint.x+prePoint.x)/2, prePoint.y) controlPoint2:CGPointMake((nowPoint.x+prePoint.x)/2, nowPoint.y)]; +// if (i == pointArray.count-1) { +// [lineBeizer moveToPoint:nowPoint];//添加连线 +// lastPoint = nowPoint; +// } +// } +// +// } +//} +@end + + diff --git a/MRRunning/ZYLBackBtn.h b/MRRunning/ZYLBackBtn.h new file mode 100644 index 0000000..d726719 --- /dev/null +++ b/MRRunning/ZYLBackBtn.h @@ -0,0 +1,16 @@ +// +// ZYLBackBtn.h +// MRMobileRun +// +// Created by 丁磊 on 2019/5/6. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ZYLBackBtn : UIButton + +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/ZYLBackBtn.m b/MRRunning/ZYLBackBtn.m new file mode 100644 index 0000000..db53ead --- /dev/null +++ b/MRRunning/ZYLBackBtn.m @@ -0,0 +1,39 @@ +// +// ZYLBackBtn.m +// MRMobileRun +// +// Created by 丁磊 on 2019/5/6. +// + +#import "ZYLBackBtn.h" +#import + +@interface ZYLBackBtn () +@property (strong, nonatomic) UIImageView *img; +@end + + +@implementation ZYLBackBtn + +- (instancetype)init{ + if (self =[super init]) { + [self initStopBtu]; + return self; + } + return self; + +} + +- (void)initStopBtu{ + self.frame = CGRectMake(0, 0, 15, 15); + self.img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 5, 10, 20)]; + self.img.image = [UIImage imageNamed:@"返回箭头4"]; + [self addSubview: self.img]; + [self.img mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.mas_top).mas_offset(5); + make.left.equalTo(self.mas_left); + make.height.mas_equalTo(20); + make.width.mas_equalTo(10); + }]; +} +@end diff --git a/MRRunning/ZYLRunningViewController.h b/MRRunning/ZYLRunningViewController.h new file mode 100644 index 0000000..be2fe5f --- /dev/null +++ b/MRRunning/ZYLRunningViewController.h @@ -0,0 +1,18 @@ +// +// ZYLRunningViewController.h +// MRMobileRun +// +// Created by 丁磊 on 2019/5/2. +// + +#import "MRBaseViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ZYLRunningViewController :UIViewController //MRBaseViewController +////获取时间戳 +//+(NSString *)currentDateInterval; +//+(NSString *)MD5:(NSString *)input; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/ZYLRunningViewController.m b/MRRunning/ZYLRunningViewController.m new file mode 100644 index 0000000..a32b42a --- /dev/null +++ b/MRRunning/ZYLRunningViewController.m @@ -0,0 +1,131 @@ +// +// ZYLRunningViewController.m +// MRMobileRun +// +// Created by 丁磊 on 2019/5/2. +// + +/* + *定位不是很准 + *后面再改个sdk + */ + +#import "RunMainPageCV.h" +#import "ZYLRunningViewController.h" +#import "MRTabBarController.h" + +#import +#import +#import +#import "HttpClient.h" +@interface ZYLRunningViewController () +{ NSTimer *timer; + NSInteger totalSeconds; +} +@property (nonatomic, strong) UILabel *NumberLabel; //数字倒数框 +@property (nonatomic, strong) UIButton *BeginBtn; //直接开始 +@property (nonatomic, strong) UIView *btnView; +@end + +@implementation ZYLRunningViewController +- (void)viewWillAppear:(BOOL)animated{ + [[NSNotificationCenter defaultCenter]postNotificationName:@"hideTabBar" object:nil]; + self.tabBarController.tabBar.hidden = YES; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + self.view.backgroundColor = [UIColor colorWithRed:100/255.0 green:104/255.0 blue:111/255.0 alpha:1.0]; + [self Add]; + + //定时器 + totalSeconds = 3; +if (!timer) { + timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(changeLabelStr) userInfo:nil repeats:YES]; + [timer fire]; + } +} + +//添加控件 +- (void)Add{ + //数字倒数框 + self.NumberLabel = [[UILabel alloc] init]; + [self.view addSubview:self.NumberLabel]; + [self.NumberLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(self.view); +// make.size.mas_equalTo(CGSizeMake(92, 195)); + make.left.right.equalTo(self.view); + make.height.mas_equalTo(195); + + }]; + + self.NumberLabel.font = [UIFont fontWithName:@"Impact" size: 160]; + self.NumberLabel.textColor = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0]; + self.NumberLabel.textAlignment = NSTextAlignmentCenter; + self.NumberLabel.text = @"0"; + + + + //直接开始那一块儿不同颜色的view + UIView *view = [[UIView alloc] init]; + view.backgroundColor = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:0.2]; + [self.view addSubview:view]; + [view mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.NumberLabel); + make.top.equalTo(self.NumberLabel.mas_bottom).offset(91); + make.size.mas_equalTo(CGSizeMake(168, 52)); + }]; + self.btnView = view; + self.btnView.layer.cornerRadius = 12; + + self.BeginBtn = [[UIButton alloc] init]; + [self.view addSubview:self.BeginBtn]; + [self.BeginBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.center.equalTo(view); + make.size.equalTo(view); + }]; + [self.BeginBtn setTintColor:[UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0]]; + self.BeginBtn.titleLabel.font = [UIFont fontWithName:@"PingFangSC" size: 16]; + [self.BeginBtn setTitle:@"直接开始" forState:UIControlStateNormal]; + [self.BeginBtn addTarget:self action:@selector(Begin) forControlEvents:UIControlEventTouchUpInside]; + self.BeginBtn.layer.cornerRadius = 12; + +} +//随计时器改变label里面的数字 +-(void)changeLabelStr +{ // int seconds = totalSeconds - 1; + self.NumberLabel.text =[NSString stringWithFormat:@"%ld",(long)totalSeconds--]; +// totalSeconds --; + if (totalSeconds == -1) { + [timer invalidate]; + self.NumberLabel.text = @"Go"; +// [self.BeginBtn removeFromSuperview]; +// [self.btnView removeFromSuperview]; + RunMainPageCV *cv = [[RunMainPageCV alloc] init]; + [self.navigationController pushViewController:cv animated:YES]; + } + CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; + NSValue *value1 = [NSNumber numberWithFloat:3.0f]; + NSValue *value2 = [NSNumber numberWithFloat:2.0f]; + NSValue *value3 = [NSNumber numberWithFloat:0.7f]; + NSValue *value4 = [NSNumber numberWithFloat:1.0f]; + anima.values = @[value1,value2,value3,value4]; + anima.duration = 0.5; + [self.NumberLabel.layer addAnimation:anima forKey:@"scalsTime"]; + +} + +//直接开始功能 +- (void)Begin{ + //切换到Go图片,并且跳转到基础界面 + [timer invalidate]; + self.NumberLabel.text = @"Go"; + [[NSNotificationCenter defaultCenter]postNotificationName:@"hideTabBar" object:nil]; + RunMainPageCV *cv = [[RunMainPageCV alloc] init]; + [self.navigationController pushViewController:cv animated:YES]; + +} +//- (void)dealloc{ +// [[NSNotificationCenter defaultCenter]removeObserver:self]; +//} +@end diff --git a/MRRunning/ZYLTimeStamp.h b/MRRunning/ZYLTimeStamp.h new file mode 100644 index 0000000..d1ba081 --- /dev/null +++ b/MRRunning/ZYLTimeStamp.h @@ -0,0 +1,19 @@ +// +// ZYLTimeStamp.h +// MRMobileRun +// +// Created by 丁磊 on 2019/5/3. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ZYLTimeStamp : NSObject + ++ (NSString *)getTimeStamp; ++ (NSString *)getCodeTimeStamp; ++ (NSDate *)getDateFromTimeStamp:(NSString *)timeStamp; +@end + +NS_ASSUME_NONNULL_END diff --git a/MRRunning/ZYLTimeStamp.m b/MRRunning/ZYLTimeStamp.m new file mode 100644 index 0000000..557d248 --- /dev/null +++ b/MRRunning/ZYLTimeStamp.m @@ -0,0 +1,30 @@ +// +// ZYLTimeStamp.m +// MRMobileRun +// +// Created by 丁磊 on 2019/5/3. +// + +#import "ZYLTimeStamp.h" + +@implementation ZYLTimeStamp ++ (NSString *)getTimeStamp{ + NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0]; + NSTimeInterval a=[dat timeIntervalSince1970]; + NSString *timeString = [NSString stringWithFormat:@"%d", (int)a]; + NSLog(@"%@",timeString); + return timeString; +} ++ (NSString *)getCodeTimeStamp{ + UInt64 recordTime = [[NSDate date] timeIntervalSince1970]*1000; + NSString *timeString = [NSString stringWithFormat:@"%llu", recordTime]; + NSLog(@"%@",timeString); + return timeString; +} + ++ (NSDate *)getDateFromTimeStamp:(NSString *)timeStamp{ + NSTimeInterval time=[timeStamp doubleValue];//如果是美国则因为时差问题要加8小时 == 28800 sec,这里不需要加 + NSDate *detaildate = [NSDate dateWithTimeIntervalSince1970:time]; + return detaildate; +} +@end diff --git a/Podfile b/Podfile index 4f87e42..4189620 100644 --- a/Podfile +++ b/Podfile @@ -8,7 +8,11 @@ pod 'MGJRouter', '0.10.0' pod 'MBProgressHUD','1.1.0' pod 'MJRefresh', '~> 3.1.0' pod 'JZLocationConverter' -pod 'AMap2DMap' +pod 'AMap3DMap' pod 'AMapLocation' pod 'Bugly' +pod 'SVGKit' +pod 'CocoaLumberjack' +pod 'MJExtension' +pod 'AMapSearch' end diff --git a/Podfile.lock b/Podfile.lock index 010e427..731f993 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -20,66 +20,86 @@ PODS: - AFNetworking/UIKit (2.5.4): - AFNetworking/NSURLConnection - AFNetworking/NSURLSession - - AMap2DMap (5.6.1): - - AMapFoundation (~> 1.4) - - AMapFoundation (1.5.6) - - AMapLocation (2.6.2): - - AMapFoundation (~> 1.4) - - Bugly (2.5.0) + - AMap3DMap (7.6.0): + - AMapFoundation (~> 1.6.3) + - AMapFoundation (1.6.4) + - AMapLocation (2.6.7): + - AMapFoundation (~> 1.6.4) + - AMapSearch (7.6.0): + - AMapFoundation (~> 1.6.3) + - Bugly (2.5.71) + - CocoaLumberjack (3.7.0): + - CocoaLumberjack/Core (= 3.7.0) + - CocoaLumberjack/Core (3.7.0) - JZLocationConverter (1.0.0) - Masonry (1.1.0) - MBProgressHUD (1.1.0) - MGJRouter (0.10.0) - - MJRefresh (3.1.16) - - SDWebImage (3.8.2): - - SDWebImage/Core (= 3.8.2) - - SDWebImage/Core (3.8.2) + - MJExtension (3.2.2) + - MJRefresh (3.1.17) + - SDWebImage (3.8.3): + - SDWebImage/Core (= 3.8.3) + - SDWebImage/Core (3.8.3) + - SVGKit (2.1.1): + - CocoaLumberjack (~> 3.0) - YYKit (1.0.9): - YYKit/no-arc (= 1.0.9) - YYKit/no-arc (1.0.9) DEPENDENCIES: - AFNetworking (= 2.5.4) - - AMap2DMap + - AMap3DMap - AMapLocation + - AMapSearch - Bugly + - CocoaLumberjack - JZLocationConverter - Masonry (= 1.1.0) - MBProgressHUD (= 1.1.0) - MGJRouter (= 0.10.0) + - MJExtension - MJRefresh (~> 3.1.0) - SDWebImage (~> 3.8) + - SVGKit - YYKit SPEC REPOS: - https://github.com/cocoapods/specs.git: + trunk: - AFNetworking - - AMap2DMap + - AMap3DMap - AMapFoundation - AMapLocation + - AMapSearch - Bugly + - CocoaLumberjack - JZLocationConverter - Masonry - MBProgressHUD - MGJRouter + - MJExtension - MJRefresh - SDWebImage + - SVGKit - YYKit SPEC CHECKSUMS: AFNetworking: 05edc0ac4c4c8cf57bcf4b84be5b0744b6d8e71e - AMap2DMap: cac76bc057de18a1641f34df6b50bf5bc6b23571 - AMapFoundation: 20fce2a12cd152e1092afdd04379cdac21932185 - AMapLocation: 89a7e4eb6040d32ba73c77a4966ecc66e46aa7c3 - Bugly: 3ca9f255c01025582df26f9222893b383c7e4b4e + AMap3DMap: fddccc76459c63e955f637812c8ba5e1e6024277 + AMapFoundation: 3638198dfa40be54648570c3520edefad288286b + AMapLocation: a46c30d9930d0f3a3bd21139d8f845d10ac3f01d + AMapSearch: ea3151e626c91b1ef99ec0ec72afdbdb577e16b2 + Bugly: fd066c75c4a0eca1440f9b6a84bd37d51bfc85ac + CocoaLumberjack: e8955b9d337ac307103b0a34fd141c32f27e53c5 JZLocationConverter: 3d816bee6484aed9c155a6045a02ce444833e2f0 Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 MBProgressHUD: e7baa36a220447d8aeb12769bf0585582f3866d9 MGJRouter: 15d94541eb2cc81eff7d577337288feb7ae9575f - MJRefresh: 7798e16e53a5ef7f332dd05b27664db4e29530fd - SDWebImage: 098e97e6176540799c27e804c96653ee0833d13c + MJExtension: d9b9c74cbdeb724c1e9ecbb157b318276e62e876 + MJRefresh: ee5b68f639775462faba4db0fd243baf4d42c2cf + SDWebImage: a72e880a8fe0f7fc31efe15aaed443c074d2a80c + SVGKit: 652cdf7bef8bec8564d04a8511d3ab50c7595fac YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7 -PODFILE CHECKSUM: bbee3637d5c922bde18dd89809bc5ac290e962b3 +PODFILE CHECKSUM: 7e2aaef8d8d5a36b6bb8375f7f1c2632239f61e3 -COCOAPODS: 1.5.3 +COCOAPODS: 1.9.3 diff --git a/Pods/.DS_Store b/Pods/.DS_Store index e2fc161..ac23449 100644 Binary files a/Pods/.DS_Store and b/Pods/.DS_Store differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin.png deleted file mode 100755 index 20d0424..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin@2x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin@2x.png deleted file mode 100755 index 54d0460..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin@2x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin@3x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin@3x.png deleted file mode 100755 index da2fbf0..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin@3x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin_lift.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin_lift.png deleted file mode 100755 index b9bbe58..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin_lift.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin_lift@2x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin_lift@2x.png deleted file mode 100755 index 9b7e052..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin_lift@2x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin_lift@3x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin_lift@3x.png deleted file mode 100755 index 69a5810..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/greenPin_lift@3x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/pin_shadow.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/pin_shadow.png deleted file mode 100755 index 4f85ff1..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/pin_shadow.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/pin_shadow@2x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/pin_shadow@2x.png deleted file mode 100755 index 8acfc67..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/pin_shadow@2x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/pin_shadow@3x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/pin_shadow@3x.png deleted file mode 100755 index fc16658..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/pin_shadow@3x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin.png deleted file mode 100755 index ffe3892..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin@2x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin@2x.png deleted file mode 100755 index 4a08cf2..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin@2x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin@3x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin@3x.png deleted file mode 100755 index 605de36..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin@3x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin_lift.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin_lift.png deleted file mode 100755 index d269981..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin_lift.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin_lift@2x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin_lift@2x.png deleted file mode 100755 index 1ff181c..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin_lift@2x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin_lift@3x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin_lift@3x.png deleted file mode 100755 index 10fd539..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/purplePin_lift@3x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin.png deleted file mode 100755 index b7c701e..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin@2x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin@2x.png deleted file mode 100755 index 0882272..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin@2x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin@3x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin@3x.png deleted file mode 100755 index ed85e11..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin@3x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin_lift.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin_lift.png deleted file mode 100755 index 2ce7563..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin_lift.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin_lift@2x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin_lift@2x.png deleted file mode 100755 index 105070b..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin_lift@2x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin_lift@3x.png b/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin_lift@3x.png deleted file mode 100755 index 04e9e34..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/AMap.bundle/images/redPin_lift@3x.png and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAAnnotation.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAAnnotation.h deleted file mode 100644 index 4a92fc7..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAAnnotation.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// MAAnnotation.h -// MAMapKit -// -// Created by AutoNavi on 13-12-13. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import -#import -#import - -///该类为标注点的protocol,提供了标注类的基本信息函数 -@protocol MAAnnotation - -///标注view中心坐标 -@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; - -@optional - -///获取annotation标题 -@property (nonatomic, readonly, copy) NSString *title; - -///获取annotation副标题 -@property (nonatomic, readonly, copy) NSString *subtitle; - -/** - * @brief 设置标注的坐标,在拖拽时会被调用 - * @param newCoordinate 新的坐标值 - */ -- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAAnnotationView.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAAnnotationView.h deleted file mode 100644 index c5ffaa1..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAAnnotationView.h +++ /dev/null @@ -1,94 +0,0 @@ -// -// MAAnnotationView.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import - -///annotationView拖动状态 -typedef NS_ENUM(NSInteger, MAAnnotationViewDragState) { - MAAnnotationViewDragStateNone = 0, ///< 静止状态 - MAAnnotationViewDragStateStarting, ///< 开始拖动 - MAAnnotationViewDragStateDragging, ///< 拖动中 - MAAnnotationViewDragStateCanceling, ///< 取消拖动 - MAAnnotationViewDragStateEnding ///< 拖动结束 -}; - -@protocol MAAnnotation; - -///标注view -@interface MAAnnotationView : UIView - -///复用标识 -@property (nonatomic, readonly) NSString *reuseIdentifier; - -///z值,大值在上,默认为0 -@property (nonatomic, assign) NSInteger zIndex; - -///关联的annotation -@property (nonatomic, strong) id annotation; - -///显示的image -@property (nonatomic, strong) UIImage *image; - -///默认情况下,annotation view的中心位于annotation的坐标位置,可以设置centerOffset改变view的位置,正的偏移使view朝右下方移动,负的朝左上方,单位是像素 -@property (nonatomic) CGPoint centerOffset; - -///默认情况下,弹出的气泡位于view正中上方,可以设置calloutOffset改变view的位置,正的偏移使view朝右下方移动,负的朝左上方,单位是像素 -@property (nonatomic) CGPoint calloutOffset; - -///默认为YES,当为NO时view忽略触摸事件 -@property (nonatomic, getter=isEnabled) BOOL enabled; - -///annotationView是否突出显示(一般不需要手动设置) -@property (nonatomic, getter=isHighlighted) BOOL highlighted; - -///设置是否处于选中状态, 外部如果要选中请使用mapView的selectAnnotation方法 -@property (nonatomic, getter=isSelected) BOOL selected; - -///设置是否可以显示callout,默认为NO -@property (nonatomic) BOOL canShowCallout; - -///显示在气泡左侧的view -@property (nonatomic, strong) UIView *leftCalloutAccessoryView; - -///显示在气泡右侧的view -@property (nonatomic, strong) UIView *rightCalloutAccessoryView; - -///是否支持拖动,默认为NO -@property (nonatomic, getter=isDraggable) BOOL draggable; - -///当前view的拖动状态 -@property (nonatomic) MAAnnotationViewDragState dragState; - -/** - * @brief 初始化并返回一个annotation view - * @param annotation 关联的annotation对象 - * @param reuseIdentifier 如果要复用view,传入一个字符串,否则设为nil,建议重用view - * @return 初始化成功则返回annotation view,否则返回nil - */ -- (id)initWithAnnotation:(id )annotation reuseIdentifier:(NSString *)reuseIdentifier; - -/** - * @brief 当从reuse队列里取出时被调用 - */ -- (void)prepareForReuse; - -/** - * @brief 设置是否处于选中状态, 外部如果要选中请使用mapView的selectAnnotation方法 - * @param selected 是否选中 - * @param animated 是否动画设置 - */ -- (void)setSelected:(BOOL)selected animated:(BOOL)animated; - -/** - * @brief 当前view的拖动状态 - * @param newDragState 要设置的拖放状态 - * @param animated 是否动画设置 - */ -- (void)setDragState:(MAAnnotationViewDragState)newDragState animated:(BOOL)animated; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MACircle.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MACircle.h deleted file mode 100644 index ad19136..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MACircle.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// MACircle.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import "MAShape.h" -#import "MAOverlay.h" -#import "MAGeometry.h" - -///该类用于定义一个圆, 通常MACircle是MACircleRenderer的model -@interface MACircle : MAShape - -///中心点经纬度坐标 -@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; - -///半径,单位:米 -@property (nonatomic, readonly) CLLocationDistance radius; - -///该圆的外接map rect -@property (nonatomic, readonly) MAMapRect boundingMapRect; - -/** - * @brief 根据中心点和半径生成圆 - * @param coord 中心点的经纬度坐标 - * @param radius 半径,单位:米 - * @return 新生成的圆 - */ -+ (instancetype)circleWithCenterCoordinate:(CLLocationCoordinate2D)coord - radius:(CLLocationDistance)radius; - -/** - * @brief 根据map rect生成圆 - * @param mapRect 生成的圆的直径为MAX(width, height) - * @return 新生成的圆 - */ -+ (instancetype)circleWithMapRect:(MAMapRect)mapRect; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MACircleRenderer.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MACircleRenderer.h deleted file mode 100644 index a1b2fc6..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MACircleRenderer.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// MACircleRenderer.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import "MACircle.h" -#import "MAOverlayPathRenderer.h" - -/** - * @brief 该类是MACircle的显示圆renderer,可以通过MAOverlayPathRenderer修改其fill和stroke attributes - */ -@interface MACircleRenderer : MAOverlayPathRenderer - -///关联的MAcirlce model -@property (nonatomic, readonly) MACircle *circle; - -/** - * @brief 根据指定圆生成对应的Renderer - * @param circle 指定的MACircle model - * @return 生成的Renderer - */ -- (instancetype)initWithCircle:(MACircle *)circle; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MACircleView.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MACircleView.h deleted file mode 100644 index ebe269f..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MACircleView.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// MACircleView.h -// MAMapKitNew -// -// Created by AutoNavi. -// Copyright (c) 2014年 Amap. All rights reserved. -// - -#import "MAOverlayPathView.h" -#import "MACircle.h" - -/*! - @brief 该类是MACircle的显示圆View,可以通过MAOverlayPathView修改其fill和stroke attributes - */ -@interface MACircleView : MAOverlayPathView - -/*! - @brief 根据指定圆生成对应的View - @param circle 指定的MACircle model - @return 生成的View - */ -- (id)initWithCircle:(MACircle *)circle; - -/*! - @brief 关联的MAcirlce model - */ -@property (nonatomic, readonly) MACircle *circle; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGeodesicPolyline.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGeodesicPolyline.h deleted file mode 100644 index 19b0974..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGeodesicPolyline.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// MAGeodesicPolyline.h -// MapKit_static -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import "MAPolyline.h" - -///大地曲线 -@interface MAGeodesicPolyline : MAPolyline - -/** - * @brief 根据map point数据生成Geodesic - * @param points mapPoint数据,points对应的内存会拷贝,调用者负责该内存的释放 - * @param count mapPoint个数 - * @return 生成的Geodesic - */ -+ (instancetype)polylineWithPoints:(MAMapPoint *)points count:(NSUInteger)count; - -/** - * @brief 根据经纬度坐标数据生成Geodesic - * @param coords 经纬度坐标数据,coords对应的内存会拷贝,调用者负责该内存的释放 - * @param count 经纬度坐标个数 - * @return 生成的Geodesic - */ -+ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGeometry.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGeometry.h deleted file mode 100644 index ec30b7d..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGeometry.h +++ /dev/null @@ -1,442 +0,0 @@ -// -// MAGeometry.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// -#import -#import -#import - -#ifdef __cplusplus -extern "C" { -#endif - - ///东北、西南两个点定义的四边形经纬度范围 - struct MACoordinateBounds{ - CLLocationCoordinate2D northEast; ///< 东北角经纬度 - CLLocationCoordinate2D southWest; ///< 西南角经纬度 - }; - typedef struct MACoordinateBounds MACoordinateBounds; - - ///经度、纬度定义的经纬度跨度范围 - struct MACoordinateSpan{ - CLLocationDegrees latitudeDelta; ///< 纬度跨度 - CLLocationDegrees longitudeDelta; ///< 经度跨度 - }; - typedef struct MACoordinateSpan MACoordinateSpan; - - ///中心点、跨度范围定义的四边形经纬度范围 - struct MACoordinateRegion{ - CLLocationCoordinate2D center; ///< 中心点经纬度 - MACoordinateSpan span; ///< 跨度范围 - }; - typedef struct MACoordinateRegion MACoordinateRegion; - - ///平面投影坐标结构定义 - struct MAMapPoint{ - double x; /// - - -///绘制在地图上的覆盖图片 -@property (nonatomic, readonly) UIImage *icon; - -///覆盖图片在地图尺寸等同于其像素的zoom值 -@property (nonatomic, readonly) CGFloat zoomLevel; - -///图片在地图中的覆盖范围 -@property (nonatomic, readonly) MACoordinateBounds bounds; - -/** - * @brief 根据bounds值和icon生成GroundOverlay - * @param bounds 图片的在地图的覆盖范围 - * @param icon 覆盖图片 - * @return 以bounds和icon 新生成GroundOverlay - */ -+ (instancetype)groundOverlayWithBounds:(MACoordinateBounds)bounds - icon:(UIImage *)icon; - -/** - * @brief 根据coordinate,icon,zoomLevel生成GroundOverlay - * @param coordinate 图片的在地图上的中心点 - * @param zoomLevel 图片在地图尺寸等同于像素的zoom值 - * @param icon 覆盖图片 - * @return 以coordinate,icon,zoomLevel 新生成GroundOverlay - */ -+ (instancetype)groundOverlayWithCoordinate:(CLLocationCoordinate2D)coordinate - zoomLevel:(CGFloat)zoomLevel - icon:(UIImage *)icon; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGroundOverlayRenderer.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGroundOverlayRenderer.h deleted file mode 100644 index 546a77a..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGroundOverlayRenderer.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// MAGroundOverlayRenderer.h -// DevDemo2D -// -// Created by AutoNavi. -// Copyright (c) 2014年 Amap. All rights reserved. -// - -#import "MAOverlayRenderer.h" -#import "MAGroundOverlay.h" - -///此类是将MAGroundOverlay中的覆盖图片显示在地图上的renderer -@interface MAGroundOverlayRenderer : MAOverlayRenderer - -///groundOverlay 具有覆盖图片,以及图片覆盖的区域 -@property (nonatomic ,readonly) MAGroundOverlay *groundOverlay; - -/** - * @brief 根据指定的GroundOverlay生成将图片显示在地图上Renderer - * @param groundOverlay 制定了覆盖图片,以及图片的覆盖区域的groundOverlay - * @return 以GroundOverlay新生成Renderer - */ -- (instancetype)initWithGroundOverlay:(MAGroundOverlay *)groundOverlay; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGroundOverlayView.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGroundOverlayView.h deleted file mode 100644 index 9c88aff..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAGroundOverlayView.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// MAGroundOverlayView.h -// MAMapKitNew -// -// Created by AutoNavi. -// Copyright (c) 2014年 Amap. All rights reserved. -// - -#import "MAOverlayView.h" -#import "MAGroundOverlay.h" - -/*! - @brief 此类是将MAGroundOverlay中的覆盖图片显示在地图上的View; - */ -@interface MAGroundOverlayView : MAOverlayView - -/*! - @brief groundOverlay 具有覆盖图片,以及图片覆盖的区域 - */ -@property (nonatomic ,readonly) MAGroundOverlay *groundOverlay; - -/*! - @brief 根据指定的GroundOverlay生成将图片显示在地图上View - @param groundOverlay 制定了覆盖图片,以及图片的覆盖区域的groundOverlay - @return 以GroundOverlay新生成View - */ -- (id)initWithGroundOverlay:(MAGroundOverlay *)groundOverlay; - - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAHeatMapTileOverlay.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAHeatMapTileOverlay.h deleted file mode 100644 index 4e477b8..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAHeatMapTileOverlay.h +++ /dev/null @@ -1,62 +0,0 @@ -// -// MAHeatMapTileOverlay.h -// test2D -// -// Created by xiaoming han on 15/4/21. -// Copyright (c) 2015年 Amap. All rights reserved. -// - -#import "MATileOverlay.h" - -///热力图节点 -@interface MAHeatMapNode : NSObject - -///经纬度 -@property (nonatomic, assign) CLLocationCoordinate2D coordinate; - -///强度 -@property (nonatomic, assign) float intensity; - -@end - -///热力图渐变属性 -@interface MAHeatMapGradient : NSObject - -///颜色 default [blue,green,red] -@property (nonatomic, readonly) NSArray *colors; - -///default [@(0.2),@(0.5),@(0,9)] -@property (nonatomic, readonly) NSArray *startPoints; - -/** - * @brief 重新设置gradient的时候,需要执行 MATileOverlayView 中的 reloadData 方法 - * @param colors 颜色 - * @param startPoints startPoints - * @return instance - */ -- (instancetype)initWithColor:(NSArray *)colors andWithStartPoints:(NSArray *)startPoints; - -@end - -///热力图tileOverlay -@interface MAHeatMapTileOverlay : MATileOverlay - -///热力图节点Array -@property (nonatomic, strong) NSArray *data; - -///热力图半径,默认为12,范围:0-100 screen point -@property (nonatomic, assign) NSInteger radius; - -///透明度,默认为0.6,范围:0-1 -@property (nonatomic, assign) CGFloat opacity; - -///热力图梯度 -@property (nonatomic, strong) MAHeatMapGradient *gradient; - -///是否开启高清热力图,默认关闭 -@property (nonatomic, assign) BOOL allowRetinaAdapting; - -@end - - - diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMapKit.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMapKit.h deleted file mode 100644 index 2cec456..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMapKit.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// MAMapKit.h -// MAMapKit -// -// Created by xiaoming han on 15/12/7. -// Copyright © 2015年 Amap. All rights reserved. -// - -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - -#pragma mark - deprecated - -#import -#import -#import -#import -#import -#import -#import - diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMapVersion.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMapVersion.h deleted file mode 100644 index c35a508..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMapVersion.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// MAMapVersion.h -// MAMapKit -// -// Created by yi chen on 2/24/16. -// Copyright © 2016 Amap. All rights reserved. -// - -#import - -#ifndef MAMapVersion_h -#define MAMapVersion_h - -#define MAMapVersionNumber 50600 -#define MAMapMinRequiredFoundationVersion 10400 - -// 依赖库版本检测 -#if AMapFoundationVersionNumber < MAMapMinRequiredFoundationVersion -#error "The AMapFoundationKit version is less than minimum required, please update! Any questions please to visit http://lbs.amap.com" -#endif - -FOUNDATION_EXTERN NSString * const MAMapKitVersion; -FOUNDATION_EXTERN NSString * const MAMapKitName; - - -#endif /* MAMapVersion_h */ diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMapView.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMapView.h deleted file mode 100644 index c3e7ff7..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMapView.h +++ /dev/null @@ -1,682 +0,0 @@ -// -// MAMapView.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import -#import "MAGeometry.h" -#import "MAOverlay.h" -#import "MAOverlayRenderer.h" -#import "MAAnnotationView.h" -#import "MAOverlayView.h" - -typedef NS_ENUM(NSInteger, MAMapLanguage) -{ - MAMapLanguageZhCN = 0, ///< 中文 - MAMapLanguageEn = 1, ///< 英文 -}; - -typedef NS_ENUM(NSInteger, MAMapType) -{ - MAMapTypeStandard, ///< 普通地图 - MAMapTypeSatellite ///< 卫星地图 -}; - -typedef NS_ENUM(NSInteger, MAUserTrackingMode) -{ - MAUserTrackingModeNone = 0, ///< 不追踪用户的location更新 - MAUserTrackingModeFollow = 1, ///< 追踪用户的location更新 - MAUserTrackingModeFollowWithHeading = 2 ///< 追踪用户的location与heading更新 -}; - -@protocol MAMapViewDelegate; - -@class MAUserLocation; -@class MAAnnotationView; -@class MAUserLocationRepresentation; - -@interface MAMapView : UIView - -#pragma mark - Properties - -///地图View的Delegate -@property (nonatomic, weak) id delegate; - -///地图类型 -@property (nonatomic, assign) MAMapType mapType; - -///地图语言 -@property (nonatomic, assign) MAMapLanguage language; - -///是否显示交通,默认为NO -@property (nonatomic, assign, getter = isShowTraffic) BOOL showTraffic; - -///是否支持平移,默认为YES -@property (nonatomic, assign, getter = isScrollEnabled) BOOL scrollEnabled; - -///是否支持缩放,默认为YES -@property (nonatomic, assign, getter = isZoomEnabled) BOOL zoomEnabled; - -///标识当前地图中心位置是否在中国范围外。此属性不是精确判断,不能用于边界区域 -@property (nonatomic, readonly) BOOL isAbroad; - -///是否允许对annotationView根据zIndex进行排序,默认为YES。当annotationView数量比较大时可能会引起性能问题,可以设置此属性为NO -@property (nonatomic, assign) BOOL allowsAnnotationViewSorting; - -#pragma mark - Logo - -///logo位置, 必须在mapView.bounds之内,否则会被忽略 -@property (nonatomic) CGPoint logoCenter; - -///logo的宽高 -@property (nonatomic, readonly) CGSize logoSize; - -#pragma mark - Compass - -///是否显示罗盘,默认为YES -@property (nonatomic, assign) BOOL showsCompass; - -///罗盘原点位置 -@property (nonatomic) CGPoint compassOrigin; - -///罗盘的宽高 -@property (nonatomic, readonly) CGSize compassSize; - - -#pragma mark - Scale - -///是否显示比例尺,默认为YES -@property (nonatomic) BOOL showsScale; - -///比例尺原点位置 -@property (nonatomic) CGPoint scaleOrigin; - -///比例尺的最大宽高 -@property (nonatomic, readonly) CGSize scaleSize; - -///在当前缩放级别下, 基于地图中心点, 1 screen point 对应的距离(单位是米). 支持KVO -@property (nonatomic, readonly) CGFloat metersPerPointForCurrentZoomLevel; - - -#pragma mark - Movement - -///当前地图的中心点经纬度坐标,改变该值时,地图缩放级别不会发生变化 -@property (nonatomic, assign) CLLocationCoordinate2D centerCoordinate; - -///当前地图的经纬度范围,设定的该范围可能会被调整为适合地图窗口显示的范围 -@property (nonatomic, assign) MACoordinateRegion region; - -///当前地图可见范围的map rect -@property (nonatomic, assign) MAMapRect visibleMapRect; - -#pragma mark - Limitation - -///设置可见地图区域的矩形边界,如限制地图只显示北京市范围 -@property (nonatomic, assign) MACoordinateRegion limitRegion; - -///设置可见地图区域的矩形边界,如限制地图只显示北京市范围 -@property (nonatomic, assign) MAMapRect limitMapRect; - -#pragma mark - Zoom - -///缩放级别, [3, 20] -@property (nonatomic, assign) double zoomLevel; - -///最小缩放级别, 最小值为3 -@property (nonatomic, assign) double minZoomLevel; - -///最大缩放级别,最大值为20 -@property (nonatomic, assign) double maxZoomLevel; - -#pragma mark - UserLocation - -///是否显示用户位置 -@property (nonatomic, assign, getter = isShowsUserLocation) BOOL showsUserLocation; - -///当前的位置数据 -@property (nonatomic, readonly) MAUserLocation *userLocation; - -///定位用户位置的模式 -@property (nonatomic) MAUserTrackingMode userTrackingMode; - -///当前位置再地图中是否可见 -@property (nonatomic, readonly, getter=isUserLocationVisible) BOOL userLocationVisible; - -#pragma mark - Annotations - -///标注数组 -@property (nonatomic, readonly) NSArray *annotations; - -///处于选中状态的标注数据数据(其count == 0 或 1) -@property (nonatomic, copy) NSArray *selectedAnnotations; - -///annotation 可见区域 -@property (nonatomic, readonly) CGRect annotationVisibleRect; - -#pragma mark - Overlays - -///Overlay数组 -@property (nonatomic, readonly) NSArray *overlays; - -#pragma mark - Compass func - -/** - * @brief 设置罗盘的图像 - * @param image 当设置图像非空时,指南针将呈现该图像,如果为nil时,则恢复默认 - */ -- (void)setCompassImage:(UIImage *)image; - -#pragma mark - Scale func - -/** - * @brief 在指定的缩放级别下, 基于地图中心点, 1 screen point 对应的距离(单位是米) - * @param zoomLevel 指定的缩放级别, 在[minZoomLevel, maxZoomLevel]范围内 - * @return 对应的距离(单位是米) - */ -- (CGFloat)metersPerPointForZoomLevel:(CGFloat)zoomLevel; - -#pragma mark - Movement func - -/** - * @brief 设定地图中心点经纬度 - * @param centerCoordinate 要设定的地图中心点经纬度 - * @param animated 是否采用动画效果 - */ -- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate animated:(BOOL)animated; - -/** - * @brief 设定当前地图的region - * @param region 要设定的地图范围,用经纬度的方式表示 - * @param animated 是否采用动画效果 - */ -- (void)setRegion:(MACoordinateRegion)region animated:(BOOL)animated; - - -/** - * @brief 根据当前地图视图frame的大小调整region范围,返回适合当前地图frame的region,调整过程中当前地图的中心点不会改变 - * @param region 要调整的经纬度范围 - * @return 调整后的经纬度范围 - */ -- (MACoordinateRegion)regionThatFits:(MACoordinateRegion)region; - -/** - * @brief 设置当前地图可见范围的map rect - * @param mapRect 要调整的map rect - * @param animated 是否采用动画效果 - */ -- (void)setVisibleMapRect:(MAMapRect)mapRect animated:(BOOL)animated; - -/** - * @brief 设置当前地图可见范围的map rect - * @param mapRect 要设置的map rect - * @param insets 嵌入边界 - * @param animated 是否采用动画效果 - */ -- (void)setVisibleMapRect:(MAMapRect)mapRect edgePadding:(UIEdgeInsets)insets animated:(BOOL)animated; - -/** - * @brief 调整map rect使其适合地图窗口显示的范围 - * @param mapRect 要调整的map rect - * @return 调整后的maprect - */ -- (MAMapRect)mapRectThatFits:(MAMapRect)mapRect; - -/** - * @brief 调整map rect使其适合地图窗口显示的范围 - * @param mapRect 要调整的map rect - * @param insets 嵌入边界 - * @return 调整后的map rect - */ -- (MAMapRect)mapRectThatFits:(MAMapRect)mapRect edgePadding:(UIEdgeInsets)insets; - -#pragma mark - Zoom func - -/** - * @brief 设置当前地图的缩放级别zoom level - * @param newZoomLevel 要设置的zoom level - * @param animated 是否采用动画效果 - */ -- (void)setZoomLevel:(double)newZoomLevel animated:(BOOL)animated; - -/** - * @brief 设置当前地图的缩放级别zoom level - * @param newZoomLevel 要设置的zoom level - * @param pivot 指定缩放的锚点,屏幕坐标 - * @param animated 是否采用动画效果 - */ -- (void)setZoomLevel:(double)newZoomLevel atPivot:(CGPoint)pivot animated:(BOOL)animated; - -#pragma mark - Conversions func - -/** - * @brief 将经纬度坐标转化为相对于指定view的坐标 - * @param coordinate 要转化的经纬度坐标 - * @param view 指定的坐标系统的view - * @return 指定view的坐标 - */ -- (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(UIView *)view; - -/** - * @brief 将相对于view的坐标转化为经纬度坐标 - * @param point 要转化的坐标 - * @param view point所基于的view - * @return 转化后的经纬度坐标 - */ -- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view; - -/** - * @brief 将map rect 转化为相对于view的坐标 - * @param region 要转化的 map rect - * @param view 返回值所基于的view - * @return 基于view的坐标 - */ -- (CGRect)convertRegion:(MACoordinateRegion)region toRectToView:(UIView *)view; - -/** - * @brief 将相对于view的rectangle转化为region - @param rect 要转化的rectangle - @param view rectangle所基于的view - @return 转化后的region - */ -- (MACoordinateRegion)convertRect:(CGRect)rect toRegionFromView:(UIView *)view; - - -#pragma mark - UserLocation func - -/** - * @brief 设置追踪用户位置的模式 - * @param mode 要使用的模式 - * @param animated 是否采用动画效果 - */ -- (void)setUserTrackingMode:(MAUserTrackingMode)mode animated:(BOOL)animated; - -/** - * @brief 设定UserLocationView样式。如果用户自定义了userlocation的annotationView,或者该annotationView还未添加到地图上,此方法将不起作用 - * @param representation 样式信息对象 - */ -- (void)updateUserLocationRepresentation:(MAUserLocationRepresentation *)representation; - -#pragma mark - Annotations func - -/** - * @brief 向地图窗口添加标注,需要实现MAMapViewDelegate的-mapView:viewForAnnotation:函数来生成标注对应的View - * @param annotation 要添加的标注 - */ -- (void)addAnnotation:(id )annotation; - -/** - * @brief 向地图窗口添加一组标注,需要实现MAMapViewDelegate的-mapView:viewForAnnotation:函数来生成标注对应的View - *@param annotations 要添加的标注数组 - */ -- (void)addAnnotations:(NSArray *)annotations; - -/** - * @brief 移除标注 - * @param annotation 要移除的标注 - */ -- (void)removeAnnotation:(id )annotation; - -/** - * @brief 移除一组标注 - * @param annotations 要移除的标注数组 - */ -- (void)removeAnnotations:(NSArray *)annotations; - -/** - * @brief 根据标注数据过去标注view - * @param annotation 标注数据 - * @return 对应的标注view - */ -- (MAAnnotationView *)viewForAnnotation:(id )annotation; - -/** - * @brief 从复用内存池中获取制定复用标识的annotation view - * @param identifier 复用标识 - * @return annotation view - */ -- (MAAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier; - -/** - * @brief 选中标注数据对应的view - * @param annotation 标注数据 - 8 @param animated 是否有动画效果 - */ -- (void)selectAnnotation:(id )annotation animated:(BOOL)animated; - -/** - * @brief 取消选中标注数据对应的view - * @param annotation 标注数据 - * @param animated 是否有动画效果 - */ -- (void)deselectAnnotation:(id )annotation animated:(BOOL)animated; - -/** - * @brief 获取指定投影矩形范围内的标注 - * @param mapRect 投影矩形范围 - * @return 标注集合 - */ -- (NSSet *)annotationsInMapRect:(MAMapRect)mapRect; - -/** - * @brief 设置地图使其可以显示数组中所有的annotation, 如果数组中只有一个则直接设置地图中心为annotation的位置 - * @param annotations 需要显示的annotation - * @param animated 是否执行动画 - */ -- (void)showAnnotations:(NSArray *)annotations animated:(BOOL)animated; - -/** - * @brief 设置地图使其可以显示数组中所有的annotation, 如果数组中只有一个则直接设置地图中心为annotation的位置 - * @param annotations 需要显示的annotation - * @param insets insets 嵌入边界 - * @param animated 是否执行动画 - */ -- (void)showAnnotations:(NSArray *)annotations edgePadding:(UIEdgeInsets)insets animated:(BOOL)animated; - -#pragma mark - Overlays func - -/** - * @brief 查找指定overlay对应的Renderer,如果该Renderer尚未创建,返回nil - * @param overlay 指定的overlay - * @return 指定overlay对应的Renderer - */ -- (MAOverlayRenderer *)rendererForOverlay:(id )overlay; -- (MAOverlayView *)viewForOverlay:(id )overlay __attribute__ ((deprecated("use - (MAOverlayRenderer *)rendererForOverlay:(id )overlay instead"))); - -/** - * @brief 向地图添加Overlay,需要实现MAMapViewDelegate的-mapView:rendererForOverlay:函数来生成标注对应的Renderer - * @param overlay 要添加的overlay - */ -- (void)addOverlay:(id )overlay; - -/** - * @brief 向地图添加一组Overlay,需要实现MAMapViewDelegate的-mapView:rendererForOverlay:函数来生成标注对应的Renderer - * @param overlays 要添加的overlay数组 - */ -- (void)addOverlays:(NSArray *)overlays; - -/** - * @brief 移除Overlay - * @param overlay 要移除的overlay - */ -- (void)removeOverlay:(id )overlay; - -/** - * @brief 移除一组Overlay - * @param overlays 要移除的overlay数组 - */ -- (void)removeOverlays:(NSArray *)overlays; - -/** - * @brief 在指定的索引处添加一个Overlay - * @param overlay 要添加的overlay - * @param index 指定的索引 - */ -- (void)insertOverlay:(id )overlay atIndex:(NSUInteger)index; - -/** - * @brief 在交换指定索引处的Overlay - * @param index1 索引1 - * @param index2 索引2 - */ -- (void)exchangeOverlayAtIndex:(NSUInteger)index1 withOverlayAtIndex:(NSUInteger)index2; - -/** - * @brief 在指定的Overlay之上插入一个overlay - * @param overlay 带添加的Overlay - * @param sibling 用于指定相对位置的Overlay - */ -- (void)insertOverlay:(id )overlay aboveOverlay:(id )sibling; - -/** - * @brief 在指定的Overlay之下插入一个overlay - * @param overlay 带添加的Overlay - * @param sibling 用于指定相对位置的Overlay - */ -- (void)insertOverlay:(id )overlay belowOverlay:(id )sibling; - -/** - * @brief 设置地图使其可以显示数组中所有的overlay - * @param overlays 需要显示的overlays - * @param animated 是否执行动画 - */ -- (void)showOverlays:(NSArray *)overlays animated:(BOOL)animated; - -/** - * @brief 设置地图使其可以显示数组中所有的overlay - * @param overlays 需要显示的overlays - * @param insets insets 嵌入边界 - * @param animated 是否执行动画 - */ -- (void)showOverlays:(NSArray *)overlays edgePadding:(UIEdgeInsets)insets animated:(BOOL)animated; - -#pragma mark - Cache - -/** - * @brief 清除所有磁盘上缓存的地图数据 - */ -- (void)clearDisk; - -@end - - -#pragma mark - Snapshots - -///地图view关于截图的类别 -@interface MAMapView (Snapshot) - -/** - * @brief 在指定区域内截图(默认会包含该区域内的annotationView) - * @param rect 指定的区域 - * @return 截图image - */ -- (UIImage *)takeSnapshotInRect:(CGRect)rect; - -/** - * @brief 获得地图当前可视区域截图 - * @param rect 指定截图区域 - * @param block 回调block - */ -- (void)takeSnapshotInRect:(CGRect)rect withCompletionBlock:(void (^)(UIImage *resultImage, CGRect rect))block; - -@end - -#pragma mark - LocationOption - -///定位相关参数的类别 -@interface MAMapView (LocationOption) - -///设定定位的最小更新距离。默认为kCLDistanceFilterNone,会提示任何移动 -@property (nonatomic) CLLocationDistance distanceFilter; - -///设定定位精度。默认为kCLLocationAccuracyBest -@property (nonatomic) CLLocationAccuracy desiredAccuracy; - -///设定最小更新角度。默认为1度,设定为kCLHeadingFilterNone会提示任何角度改变 -@property (nonatomic) CLLocationDegrees headingFilter; - -///指定定位是否会被系统自动暂停。默认为YES。只在iOS 6.0之后起作用 -@property (nonatomic) BOOL pausesLocationUpdatesAutomatically; - -///是否允许后台定位。默认为NO。只在iOS 9.0之后起作用。设置为YES的时候必须保证 Background Modes 中的 Location updates处于选中状态,否则会抛出异常 -@property (nonatomic) BOOL allowsBackgroundLocationUpdates; - -@end - -#pragma mark - MAMapViewDelegate - -///地图view的delegate -@protocol MAMapViewDelegate -@optional - -/** - * @brief 地图区域即将改变时会调用此接口 - * @param mapView 地图View - * @param animated 是否动画 - */ -- (void)mapView:(MAMapView *)mapView regionWillChangeAnimated:(BOOL)animated; - -/** - * @brief 地图区域改变完成后会调用此接口 - * @param mapView 地图View - * @param animated 是否动画 - */ -- (void)mapView:(MAMapView *)mapView regionDidChangeAnimated:(BOOL)animated; - -/** - * @brief 地图将要发生移动时调用此接口 - * @param mapView 地图view - * @param wasUserAction 标识是否是用户动作 - */ -- (void)mapView:(MAMapView *)mapView mapWillMoveByUser:(BOOL)wasUserAction; - -/** - * @brief 地图移动结束后调用此接口 - * @param mapView 地图view - * @param wasUserAction 标识是否是用户动作 - */ -- (void)mapView:(MAMapView *)mapView mapDidMoveByUser:(BOOL)wasUserAction; - -/** - * @brief 地图将要发生缩放时调用此接口 - * @param mapView 地图view - * @param wasUserAction 标识是否是用户动作 - */ -- (void)mapView:(MAMapView *)mapView mapWillZoomByUser:(BOOL)wasUserAction; - -/** - * @brief 地图缩放结束后调用此接口 - * @param mapView 地图view - * @param wasUserAction 标识是否是用户动作 - */ -- (void)mapView:(MAMapView *)mapView mapDidZoomByUser:(BOOL)wasUserAction; - -/** - * @brief 单击地图底图调用此接口 - * @param mapView 地图View - * @param coordinate 点击位置经纬度 - */ -- (void)mapView:(MAMapView *)mapView didSingleTappedAtCoordinate:(CLLocationCoordinate2D)coordinate; - -/** - * @brief 长按地图底图调用此接口 - * @param mapView 地图View - * @param coordinate 长按位置经纬度 - */ -- (void)mapView:(MAMapView *)mapView didLongPressedAtCoordinate:(CLLocationCoordinate2D)coordinate; - -/** - * @brief 根据anntation生成对应的View - * @param mapView 地图View - * @param annotation 指定的标注 - * @return 生成的标注View - */ -- (MAAnnotationView*)mapView:(MAMapView *)mapView viewForAnnotation:(id )annotation; - -/** - * @brief 当mapView新添加annotation views时调用此接口 - * @param mapView 地图View - * @param views 新添加的annotation views - */ -- (void)mapView:(MAMapView *)mapView didAddAnnotationViews:(NSArray *)views; - -/** - * @brief 当选中一个annotation views时调用此接口 - * @param mapView 地图View - * @param view 选中的annotationView - */ -- (void)mapView:(MAMapView *)mapView didSelectAnnotationView:(MAAnnotationView *)view; - -/** - * @brief 当取消选中一个annotation views时调用此接口 - * @param mapView 地图View - * @param view 取消选中的annotationView - */ -- (void)mapView:(MAMapView *)mapView didDeselectAnnotationView:(MAAnnotationView *)view; - -/** - * @brief 标注view的accessory view(必须继承自UIControl)被点击时调用此接口 - * @param mapView 地图View - * @param view callout所属的标注view - * @param control 对应的control - */ -- (void)mapView:(MAMapView *)mapView annotationView:(MAAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control; - -/** - * @brief 标注view的calloutview整体点击时调用此接口 - * @param mapView 地图的view - * @param view calloutView所属的annotationView - */ -- (void)mapView:(MAMapView *)mapView didAnnotationViewCalloutTapped:(MAAnnotationView *)view; - -/** - * @brief 在地图View将要启动定位时调用此接口 - * @param mapView 地图View - */ -- (void)mapViewWillStartLocatingUser:(MAMapView *)mapView; - -/** - * @brief 在地图View停止定位后调用此接口 - * @param mapView 地图View - */ -- (void)mapViewDidStopLocatingUser:(MAMapView *)mapView; - -/** - * @brief 位置或者设备方向更新后调用此接口 - * @param mapView 地图View - * @param userLocation 用户定位信息(包括位置与设备方向等数据) - * @param updatingLocation 标示是否是location数据更新, YES:location数据更新 NO:heading数据更新 - */ -- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation; - -/** - * @brief 定位失败后调用此接口 - * @param mapView 地图View - * @param error 错误号,参考CLError.h中定义的错误号 - */ -- (void)mapView:(MAMapView *)mapView didFailToLocateUserWithError:(NSError *)error; - -/** - * @brief 当userTrackingMode改变时调用此接口 - * @param mapView 地图View - * @param mode 改变后的mode - * @param animated 动画 - */ -- (void)mapView:(MAMapView *)mapView didChangeUserTrackingMode:(MAUserTrackingMode)mode animated:(BOOL)animated; - -/** - * @brief 拖动annotation view时view的状态变化,ios3.2以后支持 - * @param mapView 地图View - * @param view annotation view - * @param newState 新状态 - * @param oldState 旧状态 - */ -- (void)mapView:(MAMapView *)mapView annotationView:(MAAnnotationView *)view didChangeDragState:(MAAnnotationViewDragState)newState fromOldState:(MAAnnotationViewDragState)oldState; - -/** - * @brief 根据overlay生成对应的Renderer - * @param mapView 地图View - * @param overlay 指定的overlay - * @return 生成的覆盖物Renderer - */ -- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id )overlay; - -/** - * @brief 当mapView新添加overlay renderer时调用此接口 - * @param mapView 地图View - * @param renderers 新添加的overlay renderers - */ -- (void)mapView:(MAMapView *)mapView didAddOverlayRenderers:(NSArray *)renderers; - -#pragma mark - Deprecated - -- (MAOverlayView *)mapView:(MAMapView *)mapView viewForOverlay:(id )overlay __attribute__ ((deprecated("use - (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id )overlay instead"))); - -- (void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation __attribute__ ((deprecated("use -(void)mapView:(MAMapView *)mapView didUpdateUserLocation:(MAUserLocation *)userLocation updatingLocation:(BOOL)updatingLocation instead"))); - -- (void)mapView:(MAMapView *)mapView didAddOverlayViews:(NSArray *)overlayViews __attribute__ ((deprecated("use - (void)mapView:(MAMapView *)mapView didAddOverlayRenderers:(NSArray *)renderers instead"))); - - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMultiColoredPolylineRenderer.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMultiColoredPolylineRenderer.h deleted file mode 100644 index 8d58da0..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMultiColoredPolylineRenderer.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// MAMultiColoredPolylineRenderer.h -// MapKit_static -// -// Created by yi chen on 12/11/15. -// Copyright © 2015 Amap. All rights reserved. -// - -#import "MAPolylineRenderer.h" -#import "MAMultiPolyline.h" - -///此类用于绘制MAMultiPolyline对应的多段线,支持分段颜色绘制。MAMultiColoredPolylineRenderer仅支持lineJoin = kCGLineJoinRound, lineCap = kCGLineCapRound,设为其他值无效。 -@interface MAMultiColoredPolylineRenderer : MAPolylineRenderer - -/** - * @brief 根据指定的MAPolyline生成一个多段线Renderer - * @param multiPolyline 指定MAMultiPolyline - * @return 新生成的多段线Renderer - */ -- (instancetype)initWithMultiPolyline:(MAMultiPolyline *)multiPolyline; - -///关联的MAMultiPolyline model -@property (nonatomic, readonly) MAMultiPolyline *multiPolyline; - -///分段绘制的颜色。需要分段颜色绘制时,必须设置(内容必须为UIColor) -@property (nonatomic, strong) NSArray *strokeColors; - -///颜色是否渐变。在颜色渐变情况下,暂不支持虚线绘制。 -@property (nonatomic, assign, getter=isGradient) BOOL gradient; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMultiPoint.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMultiPoint.h deleted file mode 100644 index f5a7b4a..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMultiPoint.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// MAMultiPoint.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import -#import "MAGeometry.h" -#import "MAShape.h" - -///该类是个由多个点组成的虚基类, 不能直接实例化对象, 要使用其子类MAPolyline,MAPolygon来实例化 -@interface MAMultiPoint : MAShape - -///坐标点数组 -@property (nonatomic, readonly) MAMapPoint *points; - -///坐标点的个数 -@property (nonatomic, readonly) NSUInteger pointCount; - -/** - * @brief 将内部的坐标点数据转化为经纬度坐标并拷贝到coords内存中 - * @param coords 调用者提供的内存空间, 该空间长度必须大于等于要拷贝的坐标点的个数(range.length) - * @param range 要拷贝的数据范围 - */ -- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMultiPolyline.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMultiPolyline.h deleted file mode 100644 index 7d1ba53..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAMultiPolyline.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// MAMultiPolyline.h -// MapKit_static -// -// Created by yi chen on 12/11/15. -// Copyright © 2015 Amap. All rights reserved. -// - -#import "MAPolyline.h" - -///此类用于定义一个由多个点相连的多段线,绘制时支持分段采用不同颜色绘制,点与点之间尾部相连但第一点与最后一个点不相连, 通常MAMultiPolyline是MAMultiColoredPolylineRenderer(分段颜色绘制)model -@interface MAMultiPolyline : MAPolyline - -///颜色索引数组,成员为NSNumber,且为非负数,负数按0处理 -@property (nonatomic, strong, readonly) NSArray *drawStyleIndexes; - -/** - * @brief 分段绘制,根据map point数据生成多段线 - * - * 分段颜色绘制:其对应的MAMultiColoredPolylineRenderer必须设置strokeColors属性 - * - * @param points 指定的直角坐标点数组,注意:如果有连续重复点,需要去重处理,只保留一个,否则会导致绘制有问题。 - * @param count 坐标点的个数 - * @param drawStyleIndexes 纹理索引数组(颜色索引数组), 成员为NSNumber, 且为非负数 - * @return 生成的折线对象 - */ -+ (instancetype)polylineWithPoints:(MAMapPoint *)points count:(NSUInteger)count drawStyleIndexes:(NSArray*)drawStyleIndexes; - -/** - * @brief 分段绘制,根据经纬度坐标数据生成多段线 - * - * 分段颜色绘制:其对应的MAMultiColoredPolylineRenderer必须设置strokeColors属性 - * - * @param coords 指定的经纬度坐标点数组,注意:如果有连续重复点,需要去重处理,只保留一个,否则会导致绘制有问题。 - * @param count 坐标点的个数 - * @param drawStyleIndexes 纹理索引数组(颜色索引数组), 成员为NSNumber, 且为非负数 - * @return 生成的折线对象 - */ -+ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count drawStyleIndexes:(NSArray*)drawStyleIndexes; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlay.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlay.h deleted file mode 100644 index d2fc4c8..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlay.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// MAOverlay.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import "MAAnnotation.h" -#import "MAGeometry.h" - -///该类是地图覆盖物的基类,所有地图的覆盖物需要继承自此类 -@protocol MAOverlay -@required - -///返回区域中心坐标 -@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; - -///区域外接矩形 -@property (nonatomic, readonly) MAMapRect boundingMapRect; - -@optional - -/** - * @brief 判断boundingMapRect和给定的mapRect是否相交,可以用MAMapRectIntersectsRect([overlay boundingMapRect], mapRect)替代 - - * @param mapRect 指定的map rect - * @return 两个矩形是否相交 - */ -- (BOOL)intersectsMapRect:(MAMapRect)mapRect; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayPathRenderer.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayPathRenderer.h deleted file mode 100644 index dc7c77d..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayPathRenderer.h +++ /dev/null @@ -1,80 +0,0 @@ -// -// MAOverlayPathRenderer.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import -#import "MAOverlayRenderer.h" - -///该类提供使用CGPathRef来绘制overlay,默认的操作是使用fill attributes, stroke attributes绘制当前path到context中, 可以使用该类的子类MACircleRenderer, MAPolylineRenderer, MAPolygonRenderer或者继承该类, 如果继承该类,需要重载-(void)createPath方法 -@interface MAOverlayPathRenderer : MAOverlayRenderer - -///填充颜色,默认是[UIColor colorWithRed:0 green:1 blue:0 alpha:0.6] -@property (strong) UIColor *fillColor; - -///笔触颜色,默认是[UIColor colorWithRed:1 green:0 blue:0 alpha:0.6] -@property (strong) UIColor *strokeColor; - -///笔触宽度,默认是0 -@property CGFloat lineWidth; - -///LineJoin,默认是kCGLineJoinRound -@property CGLineJoin lineJoin; - -///LineCap,默认是kCGLineCapRound -@property CGLineCap lineCap; - -///MiterLimit,默认是10.f -@property CGFloat miterLimit; - -///LineDashPhase,默认是0.f -@property CGFloat lineDashPhase; - -///LineDashPattern,默认是nil -@property (copy) NSArray *lineDashPattern; - -///当前的path -@property CGPathRef path; - -/** - * @brief 子类需要重载该方法并设置(self.path = newPath) - */ -- (void)createPath; - -/** - * @brief 释放当前path,调用之后 path == NULL - */ -- (void)invalidatePath; - -/** - * @brief 将当前的stroke attributes设置到指定的context - * @param context 目标context - * @param zoomScale 当前缩放比例值 - */ -- (void)applyStrokePropertiesToContext:(CGContextRef)context atZoomScale:(MAZoomScale)zoomScale; - -/** - * @brief 将当前的fill attributes设置到指定的context - * @param context 目标context - * @param zoomScale 当前缩放比例值 - */ -- (void)applyFillPropertiesToContext:(CGContextRef)context atZoomScale:(MAZoomScale)zoomScale; - -/** - * @brief 绘制path - * @param path 要绘制的path - * @param context 目标context - */ -- (void)strokePath:(CGPathRef)path inContext:(CGContextRef)context; - -/** - * @brief 填充path - * @param path 要绘制的path - * @param context 目标context - */ -- (void)fillPath:(CGPathRef)path inContext:(CGContextRef)context; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayPathView.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayPathView.h deleted file mode 100644 index f7f4f64..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayPathView.h +++ /dev/null @@ -1,99 +0,0 @@ -// -// MAOverlayPathView.h -// MAMapKitNew -// -// Created by AutoNavi. -// Copyright (c) 2014年 Amap. All rights reserved. -// - -#import "MAOverlayView.h" - -/*! - @brief 该类提供使用CGPathRef来绘制overlay,默认的操作是使用fill attributes, stroke attributes绘制当前path到context中, 可以使用该类的子类MACircleView, MAPolylineView, MAPolygonView或者继承该类, 如果继承该类,需要重载-(void)createPath方法 - */ -@interface MAOverlayPathView : MAOverlayView - -/*! - @brief 填充颜色,默认是[UIColor colorWithRed:0 green:1 blue:0 alpha:0.6] - */ -@property (strong) UIColor *fillColor; - -/*! - @brief 笔触颜色,默认是[UIColor colorWithRed:1 green:0 blue:0 alpha:0.6] - */ -@property (strong) UIColor *strokeColor; - -/*! - @brief 笔触宽度,默认是0 - */ -@property CGFloat lineWidth; - -/*! - @brief LineJoin,默认是kCGLineJoinRound - */ -@property CGLineJoin lineJoin; - -/*! - @brief LineCap,默认是kCGLineCapRound - */ -@property CGLineCap lineCap; - -/*! - @brief MiterLimit,默认是10.f - */ -@property CGFloat miterLimit; - -/*! - @brief LineDashPhase,默认是0.f - */ -@property CGFloat lineDashPhase; - -/*! - @brief LineDashPattern,默认是nil - */ -@property (copy) NSArray *lineDashPattern; - -/*! - @brief 子类需要重载该方法并设置(self.path = newPath) - */ -- (void)createPath; - -/*! - @brief 当前的path - */ -@property CGPathRef path; - -/*! - @brief 释放当前path,调用之后 path == NULL - */ -- (void)invalidatePath; - -/*! - @brief 将当前的stroke attributes设置到指定的context - @param context 目标context - @param zoomScale 当前缩放比例值 - */ -- (void)applyStrokePropertiesToContext:(CGContextRef)context atZoomScale:(MAZoomScale)zoomScale; - -/*! - @brief 将当前的fill attributes设置到指定的context - @param context 目标context - @param zoomScale 当前缩放比例值 - */ -- (void)applyFillPropertiesToContext:(CGContextRef)context atZoomScale:(MAZoomScale)zoomScale; - -/*! - @brief 绘制path - @param path 要绘制的path - @param context 目标context - */ -- (void)strokePath:(CGPathRef)path inContext:(CGContextRef)context; - -/*! - @brief 填充path - @param path 要绘制的path - @param context 目标context - */ -- (void)fillPath:(CGPathRef)path inContext:(CGContextRef)context; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayRenderer.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayRenderer.h deleted file mode 100644 index a5076d5..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayRenderer.h +++ /dev/null @@ -1,94 +0,0 @@ -// -// MAOverlayRenderer.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import "MAGeometry.h" -#import "MAOverlay.h" - -///该类是地图覆盖物Renderer的基类, 提供绘制overlay的接口但并无实际的实现 -@interface MAOverlayRenderer : NSObject - -///关联的overlay对象 -@property (nonatomic, readonly) id overlay; - -///overlay的透明度 -@property CGFloat alpha; - -///context的比例系数 -@property (readonly) CGFloat contentScaleFactor; - -/** - * @brief 初始化并返回一个overlay renderer - * @param overlay 关联的overlay对象 - * @return 初始化成功则返回overlay renderer,否则返回nil - */ -- (id)initWithOverlay:(id )overlay; - -/** - * @brief 将MAMapPoint转化为相对于receiver的本地坐标 - * @param mapPoint 要转化的MAMapPoint - * @return 相对于receiver的本地坐标 - */ -- (CGPoint)pointForMapPoint:(MAMapPoint)mapPoint; - -/** - * @brief 将相对于receiver的本地坐标转化为MAMapPoint - * @param point 要转化的相对于receiver的本地坐标 - * @return MAMapPoint - */ -- (MAMapPoint)mapPointForPoint:(CGPoint)point; - -/** - * @brief 将MAMapRect转化为相对于receiver的本地rect - * @param mapRect 要转化的MAMapRect - * @return 相对于receiver的本地rect - */ -- (CGRect)rectForMapRect:(MAMapRect)mapRect; - -/** - * @brief 将相对于receiver的本地rect转化为MAMapRect - * @param rect 要转化的相对于receiver的本地rect - * @return MAMapRect - */ -- (MAMapRect)mapRectForRect:(CGRect)rect; - -/** - * @brief 判断overlay renderer是否可以绘制包含的内容 - * @param mapRect 该MAMapRect范围内需要绘制 - * @param zoomScale 当前的缩放比例值 - * @return 是否可以进行绘制 - */ -- (BOOL)canDrawMapRect:(MAMapRect)mapRect zoomScale:(MAZoomScale)zoomScale; - -/** - * @brief 绘制overlay renderer的内容 - * @param mapRect 该MAMapRect范围内需要更新 - * @param zoomScale 当前的缩放比例值 - * @param context 绘制操作的graphics context - */ -- (void)drawMapRect:(MAMapRect)mapRect zoomScale:(MAZoomScale)zoomScale inContext:(CGContextRef)context; - -/** - * @brief 设置是否需要重新绘制 - */ -- (void)setNeedsDisplay; - -/** - * @brief 重绘指定map rect内的内容 - * @param mapRect 该map rect范围内的内容需要重绘 - */ -- (void)setNeedsDisplayInMapRect:(MAMapRect)mapRect; - -/** - * @brief 重绘指定zoom scale下map rect内的内容 - * @param mapRect 该map rect范围内的内容需要重绘 - * @param zoomScale 当前的缩放比例值 - */ -- (void)setNeedsDisplayInMapRect:(MAMapRect)mapRect zoomScale:(MAZoomScale)zoomScale; - - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayView.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayView.h deleted file mode 100644 index 4602ac4..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAOverlayView.h +++ /dev/null @@ -1,98 +0,0 @@ -// -// MAOverlayView.h -// MAMapKitNew -// -// Created by AutoNavi. -// Copyright (c) 2014年 Amap. All rights reserved. -// - -#import "MAGeometry.h" -#import "MAOverlay.h" - -/*! - @brief 该类是地图覆盖物View的基类, 提供绘制overlay的接口但并无实际的实现 - */ -@interface MAOverlayView : UIView - -/*! - @brief 初始化并返回一个overlay view - @param overlay 关联的overlay对象 - @return 初始化成功则返回overlay view,否则返回nil - */ -- (id)initWithOverlay:(id )overlay; - -/*! - @brief 关联的overlay对象 - */ -@property (nonatomic, readonly) id overlay; - -/*! - @brief 将MAMapPoint转化为相对于receiver的本地坐标 - @param mapPoint 要转化的MAMapPoint - @return 相对于receiver的本地坐标 - */ -- (CGPoint)pointForMapPoint:(MAMapPoint)mapPoint; - -/*! - @brief 将相对于receiver的本地坐标转化为MAMapPoint - @param point 要转化的相对于receiver的本地坐标 - @return MAMapPoint - */ -- (MAMapPoint)mapPointForPoint:(CGPoint)point; - -/*! - @brief 将MAMapRect转化为相对于receiver的本地rect - @param mapRect 要转化的MAMapRect - @return 相对于receiver的本地rect - */ -- (CGRect)rectForMapRect:(MAMapRect)mapRect; - -/*! - @brief 将相对于receiver的本地rect转化为MAMapRect - @param rect 要转化的相对于receiver的本地rect - @return MAMapRect - */ -- (MAMapRect)mapRectForRect:(CGRect)rect; - -/*! - @brief 判断overlay view是否可以绘制包含的内容 - @param mapRect 该MAMapRect范围内需要绘制 - @param zoomScale 当前的缩放比例值 - @return 是否可以进行绘制 - */ -- (BOOL)canDrawMapRect:(MAMapRect)mapRect zoomScale:(MAZoomScale)zoomScale; - -/*! - @brief 绘制overlay view的内容 - @param mapRect 该MAMapRect范围内需要更新 - @param zoomScale 当前的缩放比例值 - @param context 绘制操作的graphics context - */ -- (void)drawMapRect:(MAMapRect)mapRect zoomScale:(MAZoomScale)zoomScale inContext:(CGContextRef)context; - -- (void)setNeedsDisplay; - -/*! - @brief 重绘指定map rect内的内容 - @param mapRect 该map rect范围内的内容需要重绘 - */ -- (void)setNeedsDisplayInMapRect:(MAMapRect)mapRect; - -/*! - @brief 重绘指定zoom scale下map rect内的内容 - @param mapRect 该map rect范围内的内容需要重绘 - @param zoomScale 当前的缩放比例值 - */ -- (void)setNeedsDisplayInMapRect:(MAMapRect)mapRect zoomScale:(MAZoomScale)zoomScale; - -/*! - @brief overlay的透明度 - */ -@property CGFloat alpha; - -/*! - @brief context的比例系数 - */ -@property (readonly) CGFloat contentScaleFactor; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPinAnnotationView.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPinAnnotationView.h deleted file mode 100644 index bae8598..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPinAnnotationView.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// MAPinAnnotationView.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import "MAAnnotationView.h" - -///大头针颜色 -typedef NS_ENUM(NSInteger, MAPinAnnotationColor) { - MAPinAnnotationColorRed = 0, ///< 红色大头针 - MAPinAnnotationColorGreen, ///< 绿色大头针 - MAPinAnnotationColorPurple ///< 紫色大头针 -}; - -///提供类似大头针效果的annotation view -@interface MAPinAnnotationView : MAAnnotationView - -///大头针的颜色,有MAPinAnnotationColorRed, MAPinAnnotationColorGreen, MAPinAnnotationColorPurple三种 -@property (nonatomic) MAPinAnnotationColor pinColor; - -///动画效果 -@property (nonatomic) BOOL animatesDrop; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPointAnnotation.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPointAnnotation.h deleted file mode 100644 index c545b58..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPointAnnotation.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// MAPointAnnotation.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import "MAShape.h" - -///点标注数据 -@interface MAPointAnnotation : MAShape - -///经纬度 -@property (nonatomic, assign) CLLocationCoordinate2D coordinate; - -///是否固定在屏幕一点, 注意,拖动或者手动改变经纬度,都会导致设置失效 -@property (nonatomic, assign, getter = isLockedToScreen) BOOL lockedToScreen; - -///固定屏幕点的坐标 -@property (nonatomic, assign) CGPoint lockedScreenPoint; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolygon.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolygon.h deleted file mode 100644 index 5163782..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolygon.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// MAPolygon.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import "MAMultiPoint.h" -#import "MAOverlay.h" - -///此类用于定义一个由多个点组成的闭合多边形, 点与点之间按顺序尾部相连, 第一个点与最后一个点相连, 通常MAPolygon是MAPolygonRenderer的model -@interface MAPolygon : MAMultiPoint - -///内嵌MAPolygon数组,在生成的多边形中将会裁减掉内嵌polygon包含的区域 -@property (readonly) NSArray *interiorPolygons; - -/** - * @brief 根据map point数据生成多边形 - * @param points mapPoint数据,points对应的内存会拷贝,调用者负责该内存的释放 - * @param count 点的个数 - * @return 新生成的多边形 - */ -+ (instancetype)polygonWithPoints:(MAMapPoint *)points count:(NSUInteger)count; - -/** - * @brief 根据map point数据和interior polygons生成多边形 - * @param points mapPoint数据,points对应的内存会拷贝,调用者负责该内存的释放 - * @param count 点的个数 - * @param interiorPolygons MAPolygon数组,指定在生成的多边形中需要裁剪掉的区域 - * @return 新生成的多边形 - */ -+ (instancetype)polygonWithPoints:(MAMapPoint *)points count:(NSUInteger)count interiorPolygons:(NSArray *)interiorPolygons; - -/** - * @brief 根据经纬度坐标数据生成闭合多边形 - * @param coords 经纬度坐标点数据,coords对应的内存会拷贝,调用者负责该内存的释放 - * @param count 经纬度坐标点数组个数 - * @return 新生成的多边形 - */ -+ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count; - -/** - * @brief 根据经纬度坐标数据和interior polygons生成闭合多边形 - * @param coords 经纬度坐标点数据,coords对应的内存会拷贝,调用者负责该内存的释放 - * @param count 经纬度坐标点数组个数 - * @param interiorPolygons MAPolygon数组,指定在生成的多边形中需要裁剪掉的区域 - * @return 新生成的多边形 - */ -+ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(NSArray *)interiorPolygons; -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolygonRenderer.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolygonRenderer.h deleted file mode 100644 index ac4b45f..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolygonRenderer.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// MAPolygonRenderer.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import "MAOverlayPathRenderer.h" -#import "MAPolygon.h" - -///此类是MAPolygon的显示多边形Renderer,可以通过MAOverlayPathRenderer修改其fill和stroke attributes -@interface MAPolygonRenderer : MAOverlayPathRenderer - -///关联的MAPolygon model -@property (nonatomic, readonly) MAPolygon *polygon; - -/** - * @brief 根据指定的多边形生成一个多边形renderer - * @param polygon 指定的多边形数据对象 - * @return 新生成的多边形renderer - */ -- (id)initWithPolygon:(MAPolygon *)polygon; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolygonView.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolygonView.h deleted file mode 100644 index 827600b..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolygonView.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// MAPolygonView.h -// MAMapKitNew -// -// Created by AutoNavi. -// Copyright (c) 2014年 Amap. All rights reserved. -// - -#import "MAOverlayPathView.h" -#import "MAPolygon.h" - -/*! - @brief 此类是MAPolygon的显示多边形View,可以通过MAOverlayPathView修改其fill和stroke attributes - */ -@interface MAPolygonView : MAOverlayPathView - -/*! - @brief 根据指定的多边形生成一个多边形view - @param polygon 指定的多边形数据对象 - @return 新生成的多边形view - */ -- (id)initWithPolygon:(MAPolygon *)polygon; - -/*! - @brief 关联的MAPolygon model - */ -@property (nonatomic, readonly) MAPolygon *polygon; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolyline.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolyline.h deleted file mode 100644 index ff8503b..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolyline.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// MAPolyline.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import "MAMultiPoint.h" -#import "MAOverlay.h" - -///此类用于定义一个由多个点相连的多段线,点与点之间尾部想连但第一点与最后一个点不相连, 通常MAPolyline是MAPolylineRenderer的model -@interface MAPolyline : MAMultiPoint - -/** - * @brief 根据map point数据生成多段线 - * @param points mapPoint数据,points对应的内存会拷贝,调用者负责该内存的释放 - * @param count count map point个数 - * @return 生成的多段线 - */ -+ (instancetype)polylineWithPoints:(MAMapPoint *)points count:(NSUInteger)count; - -/** - * @brief 根据经纬度坐标数据生成多段线 - * @param coords 经纬度坐标数据,coords对应的内存会拷贝,调用者负责该内存的释放 - * @param count 经纬度坐标个数 - * @return 生成的多段线 - */ -+ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolylineRenderer.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolylineRenderer.h deleted file mode 100644 index 88a9e18..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolylineRenderer.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// MAPolylineRenderer.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import "MAOverlayPathRenderer.h" -#import "MAPolyline.h" - -///此类是MAPolyline的显示多段线renderer,可以通过MAOverlayPathRenderer修改其fill和stroke attributes -@interface MAPolylineRenderer : MAOverlayPathRenderer - -///关联的MAPolyline model -@property (nonatomic, readonly) MAPolyline *polyline; - -/** - * @brief 根据指定的MAPolyline生成一个多段线renderer - * @param polyline 指定MAPolyline - * @return 新生成的多段线renderer - */ -- (id)initWithPolyline:(MAPolyline *)polyline; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolylineView.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolylineView.h deleted file mode 100644 index a585ba4..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAPolylineView.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// MAPolylineView.h -// MAMapKitNew -// -// Created by AutoNavi. -// Copyright (c) 2014年 Amap. All rights reserved. -// - -#import "MAOverlayPathView.h" -#import "MAPolyline.h" - -/*! - @brief 此类是MAPolyline的显示多段线View,可以通过MAOverlayPathView修改其fill和stroke attributes - */ -@interface MAPolylineView : MAOverlayPathView - -/*! - @brief 根据指定的MAPolyline生成一个多段线view - @param polyline 指定MAPolyline - @return 新生成的多段线view - */ -- (id)initWithPolyline:(MAPolyline *)polyline; - -/*! - @brief 关联的MAPolyline model - */ -@property (nonatomic, readonly) MAPolyline *polyline; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAShape.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAShape.h deleted file mode 100644 index d197701..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAShape.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// MAShape.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2013年 Amap. All rights reserved. -// - -#import -#import "MAAnnotation.h" - -///该类为一个抽象类,定义了基于MAAnnotation的MAShape类的基本属性和行为,不能直接使用,必须子类化之后才能使用 -@interface MAShape : NSObject - -///标题 -@property (nonatomic, copy) NSString *title; - -///副标题 -@property (nonatomic, copy) NSString *subtitle; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MATileOverlay.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MATileOverlay.h deleted file mode 100644 index 2bbd3b5..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MATileOverlay.h +++ /dev/null @@ -1,67 +0,0 @@ -// -// MATileOverlay.h -// MAMapKitNew -// -// Created by xiaoming han on 14-1-24. -// Copyright (c) 2014年 Amap. All rights reserved. -// - -#import "MAOverlay.h" - -///该类是覆盖在球面墨卡托投影上的图片tiles的数据源 -@interface MATileOverlay : NSObject - -/** - * @brief 根据指定的URLTemplate生成tileOverlay - * @param URLTemplate URLTemplate是一个包含"{x}","{y}","{z}","{scale}"的字符串,"{x}","{y}","{z}","{scale}"会被tile path的值所替换,并生成用来加载tile图片数据的URL 。例如 http://server/path?x={x}&y={y}&z={z}&scale={scale} - * @return 以指定的URLTemplate字符串生成tileOverlay - */ -- (instancetype)initWithURLTemplate:(NSString *)URLTemplate; - -///默认tileSize 256x256 -@property CGSize tileSize; - -///overlay可以渲染的最小缩放级别。当0级时,一个tile覆盖整个世界范围,1级时覆盖 1/4th 世界,2级时1/16th,以此类推。 -@property NSInteger minimumZ; - -///overlay可以渲染的最大缩放级别。 -@property NSInteger maximumZ; - -///同initWithURLTemplate:中的URLTemplate -@property (readonly) NSString *URLTemplate; - -///暂未开放 -@property (nonatomic) BOOL canReplaceMapContent; - -///区域外接矩形,可用来设定tileOverlay的可渲染区域 -@property (nonatomic) MAMapRect boundingMapRect; - -@end - -///记录某特定tile的据结构。contentScaleFactor根据设备的ScrennScale而定, 为1.0或2.0。 -struct MATileOverlayPath{ - NSInteger x; ///< x坐标 - NSInteger y; ///< y坐标 - NSInteger z; ///< 缩放级别 - CGFloat contentScaleFactor; ///< 屏幕的scale factor -}; -typedef struct MATileOverlayPath MATileOverlayPath; - -///子类可覆盖CustomLoading中的方法来自定义加载MATileOverlay的行为。 -@interface MATileOverlay (CustomLoading) - -/** - * @brief 以tile path生成URL。用于加载tile,此方法默认填充URLTemplate - * @param path tile path - * @return 以tile path生成tileOverlay - */ -- (NSURL *)URLForTilePath:(MATileOverlayPath)path; - -/** - * @brief 加载被请求的tile,并以tile数据或加载tile失败error访问回调block;默认实现为首先用URLForTilePath去获取URL,然后用异步NSURLConnection加载tile - * @param path tile path - * @param result 用来传入tile数据或加载tile失败的error访问的回调block - */ -- (void)loadTileAtPath:(MATileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error))result; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MATileOverlayRenderer.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MATileOverlayRenderer.h deleted file mode 100644 index 77de306..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MATileOverlayRenderer.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// MATileOverlayRenderer.h -// MAMapKitNew -// -// Created by xiaoming han on 14-1-24. -// Copyright (c) 2014年 Amap. All rights reserved. -// - -#import "MAOverlayRenderer.h" -#import "MATileOverlay.h" - -///此类将MATileOverlay中的tile渲染到地图上 -@interface MATileOverlayRenderer : MAOverlayRenderer - -///覆盖在球面墨卡托投影上的图片tiles的数据源 -@property (nonatomic ,readonly) MATileOverlay *tileOverlay; - -/** - * @brief 根据指定的tileOverlay生成MATileOverlayRenderer - * @param overlay 数据源 - * @return 初始化成功则返回overlay renderer,否则返回nil - */ -- (instancetype)initWithTileOverlay:(MATileOverlay *)overlay; - -/** - * @brief 清除所有tile的缓存,并刷新overlay - */ -- (void)reloadData; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MATileOverlayView.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MATileOverlayView.h deleted file mode 100644 index 3110e68..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MATileOverlayView.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// MATileOverlayView.h -// MAMapKitNew -// -// Created by xiaoming han on 14-5-4. -// Copyright (c) 2014年 Amap. All rights reserved. -// - -#import "MAOverlayView.h" -#import "MATileOverlay.h" - -/*! - @brief 此类将MATileOverlay中的tile渲染到地图上 - */ -@interface MATileOverlayView : MAOverlayView - -/*! - @brief 覆盖在球面墨卡托投影上的图片tiles的数据源 - */ -@property (nonatomic ,readonly) MATileOverlay *tileOverlay; - -/*! - @brief 根据指定的tileOverlay生成MAOverlayView - @param overlay 数据源 - @return 初始化成功则返回overlayView,否则返回nil - */ -- (id)initWithTileOverlay:(MATileOverlay *)overlay; - -/*! - @brief 清除所有tile的缓存,并刷新overlay - */ -- (void)reloadData; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAUserLocation.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAUserLocation.h deleted file mode 100755 index b69e5e1..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAUserLocation.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// MAUserLocation.h -// MAMapKit -// -// Created by AutoNavi. -// Copyright (c) 2012年 Amap. All rights reserved. -// - -#import -#import "MAAnnotation.h" - -@class CLLocation; -@class CLHeading; - -///定位信息类 -@interface MAUserLocation : NSObject - -///位置更新状态,如果正在更新位置信息,则该值为YES. -@property (nonatomic, readonly, getter = isUpdating) BOOL updating; - -///位置信息, 如果MAMapView的showsUserLocation为NO, 或者尚未定位成功, 则该值为nil. -@property (nonatomic, readonly) CLLocation *location; - -///heading信息. -@property (nonatomic, readonly) CLHeading *heading; - -///定位标注点要显示的标题信息. -@property (nonatomic, copy) NSString *title; - -///定位标注点要显示的子标题信息. -@property (nonatomic, copy) NSString *subtitle; - -@end - diff --git a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAUserLocationRepresentation.h b/Pods/AMap2DMap/MAMapKit.framework/Headers/MAUserLocationRepresentation.h deleted file mode 100644 index 415bac7..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/Headers/MAUserLocationRepresentation.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// MAUserLocationRepresentation.h -// MAMapKitNew -// -// Created by AutoNavi. -// Copyright (c) 2014年 Amap. All rights reserved. -// - -#import -#import - -///用户位置显示样式控制 -@interface MAUserLocationRepresentation : NSObject - -///标注图片。若设置为nil,则为默认图片。 -@property (nonatomic, strong) UIImage *image; - -///是否显示精度圈。默认为YES -@property (nonatomic, assign) BOOL showsAccuracyRing; - -///是否显示方向指示( MAUserTrackingModeFollowWithHeading 模式开启)。默认为YES -@property (nonatomic, assign) BOOL showsHeadingIndicator; - -///精度圈边线宽度,默认是2 -@property (nonatomic, assign) CGFloat lineWidth; - -///精度圈填充颜色 -@property (nonatomic, strong) UIColor *fillColor; - -///精度圈边线颜色 -@property (nonatomic, strong) UIColor *strokeColor; - -///边线虚线样式, 默认是nil -@property (nonatomic, copy) NSArray *lineDashPattern; - -@end diff --git a/Pods/AMap2DMap/MAMapKit.framework/MAMapKit b/Pods/AMap2DMap/MAMapKit.framework/MAMapKit deleted file mode 100644 index 9aec388..0000000 Binary files a/Pods/AMap2DMap/MAMapKit.framework/MAMapKit and /dev/null differ diff --git a/Pods/AMap2DMap/MAMapKit.framework/version.txt b/Pods/AMap2DMap/MAMapKit.framework/version.txt deleted file mode 100644 index 00c0a7d..0000000 --- a/Pods/AMap2DMap/MAMapKit.framework/version.txt +++ /dev/null @@ -1 +0,0 @@ -5.6.0+2dmap.ece60af diff --git a/Pods/AMapFoundation/AMapFoundationKit.framework/AMapFoundationKit b/Pods/AMapFoundation/AMapFoundationKit.framework/AMapFoundationKit index 2f7e604..7d7604e 100644 Binary files a/Pods/AMapFoundation/AMapFoundationKit.framework/AMapFoundationKit and b/Pods/AMapFoundation/AMapFoundationKit.framework/AMapFoundationKit differ diff --git a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapFoundationConst.h b/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapFoundationConst.h new file mode 100644 index 0000000..8bd86ab --- /dev/null +++ b/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapFoundationConst.h @@ -0,0 +1,48 @@ +// +// AMapFoundationConst.h +// AMapFoundationKit +// +// Created by JL on 2019/7/22. +// Copyright © 2019 Amap.com. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef NSInteger AMapFoundationNSErrorCode; + +//ErrorDomain:文件不存在 错误码:-555555 +extern NSErrorDomain const AMapFoundationNSErrorFileDonotExist; +extern AMapFoundationNSErrorCode const AMapFoundationNSErrorFileDonotExistCode; + +//ErrorDomain:文件路径不合法 错误码:-555556 +extern NSErrorDomain const AMapFoundationNSErrorFilePathInvaild; +extern AMapFoundationNSErrorCode const AMapFoundationNSErrorFilePathInvaildCode; + +//ErrorDomain:指定类型的日志文件不存在 错误码:-555557 +extern NSErrorDomain const AMapFoundationNSErrorTypeLogDonotExist; +extern AMapFoundationNSErrorCode const AMapFoundationNSErrorTypeLogDonotExistCode; + +//ErrorDomain:待上传的数据为空(可能是组装/压缩时出错) 错误码:-555558 +extern NSErrorDomain const AMapFoundationNSErrorUploadDataIsEmpty; +extern AMapFoundationNSErrorCode const AMapFoundationNSErrorUploadDataIsEmptyCode; + +//ErrorDomain:参数错误 错误码:-444444 +extern NSErrorDomain const AMapFoundationNSErrorParametersInvalid; +extern AMapFoundationNSErrorCode const AMapFoundationNSErrorParametersInvalidCode; + + +extern NSErrorDomain const AMapFoundationNSErrorCloudConfigDisable; +extern AMapFoundationNSErrorCode const AMapFoundationNSErrorCloudConfigDisableCode; + +extern NSErrorDomain const AMapFoundationNSErrorNetworkUnusable; +extern AMapFoundationNSErrorCode const AMapFoundationNSErrorNetworkUnusableCode; + +extern NSErrorDomain const AMapFoundationNSErrorCurrentworkIsRunning; +extern AMapFoundationNSErrorCode const AMapFoundationNSErrorCurrentworkIsRunningCode; + +extern NSErrorDomain const AMapFoundationNSErrorCurrentUploadSizeHaveExcess; +extern AMapFoundationNSErrorCode const AMapFoundationNSErrorCurrentUploadSizeHaveExcessCode; + +NS_ASSUME_NONNULL_END diff --git a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapFoundationKit.h b/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapFoundationKit.h index ff93550..258e115 100644 --- a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapFoundationKit.h +++ b/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapFoundationKit.h @@ -11,8 +11,6 @@ #import #import #import +#import #import -#import -#import -#import diff --git a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapFoundationVersion.h b/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapFoundationVersion.h index 860e0f5..665e6af 100644 --- a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapFoundationVersion.h +++ b/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapFoundationVersion.h @@ -11,7 +11,7 @@ #ifndef AMapFoundationVersion_h #define AMapFoundationVersion_h -#define AMapFoundationVersionNumber 10506 +#define AMapFoundationVersionNumber 10604 FOUNDATION_EXTERN NSString * const AMapFoundationVersion; FOUNDATION_EXTERN NSString * const AMapFoundationName; diff --git a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapServices.h b/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapServices.h index 6085c9f..1cfe638 100644 --- a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapServices.h +++ b/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/AMapServices.h @@ -8,6 +8,13 @@ #import + +/** + * 是否为海外用户...海外用户,SDK内部会屏蔽一些操作 默认为NO. + * @warning AMapServices初始化之前,设置才能生效 + */ +extern BOOL _amapLocationOverseas; + ///高德SDK服务类 @interface AMapServices : NSObject @@ -16,6 +23,7 @@ */ + (AMapServices *)sharedServices; + ///APIkey。设置key,需要在高德官网控制台绑定对应的bundleid。 @property (nonatomic, copy) NSString *apiKey; @@ -23,7 +31,7 @@ @property (nonatomic, assign) BOOL enableHTTPS; ///是否启用崩溃日志上传。默认为YES, 只有在真机上设置有效。\n开启崩溃日志上传有助于我们更好的了解SDK的状况,可以帮助我们持续优化和改进SDK。需要注意的是,SDK内部是通过设置NSUncaughtExceptionHandler来捕获异常的,如果您的APP中使用了其他收集崩溃日志的SDK,或者自己有设置NSUncaughtExceptionHandler的话,请保证 AMapServices 的初始化是在其他设置NSUncaughtExceptionHandler操作之后进行的,我们的handler会再处理完异常后调用前一次设置的handler,保证之前设置的handler会被执行。 -@property (nonatomic, assign) BOOL crashReportEnabled; +@property (nonatomic, assign) BOOL crashReportEnabled __attribute__((deprecated("从v1.5.7开始废弃,调用无任何作用"))); ///设备标识,取自idfv。用于排查问题时提供。 @property (nonatomic, readonly) NSString *identifier; diff --git a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/NSMutableArray+AMapSafe.h b/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/NSMutableArray+AMapSafe.h deleted file mode 100644 index 2f3341e..0000000 --- a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/NSMutableArray+AMapSafe.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// NSArray(AMapSave).h -// AMapFoundationKit -// -// Created by zhou on 2018/2/23. -// Copyright © 2018年 Amap.com. All rights reserved. -// - -#import - -@interface NSMutableArray (AMapSafe) - -- (BOOL)amf_addObjectSafe:(ObjectType)anObject; - -@end diff --git a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/NSMutableDictionary+AMapSafe.h b/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/NSMutableDictionary+AMapSafe.h deleted file mode 100644 index 9785942..0000000 --- a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/NSMutableDictionary+AMapSafe.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// NSMutableDictionary+AMapSave.h -// AMapFoundationKit -// -// Created by zhou on 2018/2/23. -// Copyright © 2018年 Amap.com. All rights reserved. -// - -#import - -@interface NSMutableDictionary (AMapSafe) - -- (BOOL)amf_setObjectSafe:(ObjectType)anObject forKey:(KeyType )aKey; - -@end diff --git a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/NSObject+AMapJsonSerialization.h b/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/NSObject+AMapJsonSerialization.h deleted file mode 100644 index 875a680..0000000 --- a/Pods/AMapFoundation/AMapFoundationKit.framework/Headers/NSObject+AMapJsonSerialization.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// NSObject+JsonAutoSerialize.h -// AMapFoundation -// -// Created by zhou on 2018/2/1. -// Copyright © 2018年 Amap.com. All rights reserved. -// - -#import - -// 网络自动化解析数组定义宏 -#define AMapJsonArray(key,type) NSArray *key; \ -@property (nonatomic, strong, readonly) type *__Array__##key - -#define AMapJsonMutableArray(key,type) NSMutableArray *key; \ -@property (nonatomic, strong, readonly) type *__Array__##key - -#define AMapNestedArray(key,type) NSArray *key; \ -@property (nonatomic, strong, readonly) type *__Array__##key - -#define AMapNestedMutableArray(key,type) NSMutableArray *key; \ -@property (nonatomic, strong, readonly) type *__Array__##key - -//#define AMapBind(key,propertyName,type) *key; \ -//@property (nonatomic, strong, readonly) type *__Bind__##propertyName##__##key - -@protocol AMapJsonManualSerialization - -@optional - -- (void)manualDeserializationJsonData:(NSDictionary *)jsonDictionary forInfo:(id)customInfo; - -- (NSMutableDictionary *)manualSerializeObjectForInfo:(id)customInfo; - -@end - -@interface NSObject (AMapJsonSerialization) - -// 反序列化自动解析Json数据,并根据和dictionaryJson的key匹配的属性名进行自动赋值,注意dictionaryJson需要和对象对应,注意只有非基础类型属性的解析才会回调手动解析(需实现AMapManuallParseJson协议) -- (void)amf_deserializationJsonData:(NSDictionary *)dictionaryJson forInfo:(id)customInfo; - -// 将Module数据对象序列化成Json数据对象的Dictionary,对于NSString、NSMutableArray、NSNumber、NSNull、NSArray和NSMutableArray会返回nil -- (NSMutableDictionary *)amf_serializeJsonObjectForInfo:(id)customInfo; - -// 将NSArray或NSMutableArray序列化成Json数据对象的数组,仅适用于是NSArray和NSMutableArray类型的对象调用,否则会返回nil -- (NSMutableArray *)amf_serializeJsonArrayForInfo:(id)customInfo; - -@end diff --git a/Pods/AMapFoundation/AMapFoundationKit.framework/version.txt b/Pods/AMapFoundation/AMapFoundationKit.framework/version.txt index 7ae74e8..e03b20b 100644 --- a/Pods/AMapFoundation/AMapFoundationKit.framework/version.txt +++ b/Pods/AMapFoundation/AMapFoundationKit.framework/version.txt @@ -1 +1 @@ -1.5.6+foundation.1d90b58 +1.6.4+foundation.f7f9056 diff --git a/Pods/AMapLocation/AMapLocationKit.framework/AMapLocationKit b/Pods/AMapLocation/AMapLocationKit.framework/AMapLocationKit index cd64562..8c233eb 100644 Binary files a/Pods/AMapLocation/AMapLocationKit.framework/AMapLocationKit and b/Pods/AMapLocation/AMapLocationKit.framework/AMapLocationKit differ diff --git a/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapGeoFenceError.h b/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapGeoFenceError.h index c064ab2..5d68451 100644 --- a/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapGeoFenceError.h +++ b/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapGeoFenceError.h @@ -21,6 +21,7 @@ typedef NS_ENUM(NSInteger, AMapGeoFenceErrorCode) { AMapGeoFenceErrorFailureAuth = 4, ///< 鉴权失败 AMapGeoFenceErrorNoValidFence = 5, ///< 无可用围栏 AMapGeoFenceErroFailureLocating = 6, ///< 定位错误 + AMapGeoFenceErroFailureFullAccuracyLocating = 7, ///< 精确定位错误 }; #endif /* AMapGeoFenceError_h */ diff --git a/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapGeoFenceManager.h b/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapGeoFenceManager.h index e0dfaf2..99d61e5 100644 --- a/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapGeoFenceManager.h +++ b/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapGeoFenceManager.h @@ -165,27 +165,42 @@ typedef NS_OPTIONS(NSUInteger, AMapGeoFenceRegionActiveStatus) */ - (void)removeTheGeoFenceRegion:(AMapGeoFenceRegion *)region; - /** * @brief 移除指定customID的围栏 * @param customID 用户执行添加围栏函数时传入的customID */ - (void)removeGeoFenceRegionsWithCustomID:(NSString *)customID; - /** * @brief 移除所有围栏 */ - (void)removeAllGeoFenceRegions; - @end - - ///地理围栏代理协议(since 2.3.0),该协议定义了获取地理围栏相关回调方法,包括添加、状态改变等。 @protocol AMapGeoFenceManagerDelegate +@required + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 + +/** + * @brief iOS14及以上版本使用地理围栏功能,需要在plist中配置NSLocationTemporaryUsageDescriptionDictionary字典描述,且添加自定义Key描述地理围栏的使用场景,此描述会在申请临时精确定位权限的弹窗中展示。该回调触发条件:拥有定位权限,但是没有获得精确定位权限的情况下,会触发该回调。此方法实现调用申请临时精确定位权限API即可: + * [manager requestTemporaryFullAccuracyAuthorizationWithPurposeKey:@"PurposeKey" completion:^(NSError *error){ + * if(completion){ + * completion(error); + * } + * }]; (必须调用,不然无法正常获取临时精确定位权限) + * @param manager 地理围栏管理类。 + * @param locationManager 需要申请临时精确定位权限的locationManager。 + * @param completion 临时精确定位权限API回调结果。直接返回系统error即可 + * @since 2.6.7 + */ +- (void)amapLocationManager:(AMapGeoFenceManager *)manager doRequireTemporaryFullAccuracyAuth:(CLLocationManager*)locationManager completion:(void(^)(NSError *error))completion; + +#endif + @optional /** diff --git a/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationCommonObj.h b/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationCommonObj.h index 9e9acd5..6b6ac44 100644 --- a/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationCommonObj.h +++ b/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationCommonObj.h @@ -28,6 +28,7 @@ typedef NS_ENUM(NSInteger, AMapLocationErrorCode) AMapLocationErrorCannotConnectToHost = 9, ///<服务器连接失败 AMapLocationErrorRegionMonitoringFailure=10,///<地理围栏错误 AMapLocationErrorRiskOfFakeLocation = 11, ///<存在虚拟定位风险 + AMapLocationErrorNoFullAccuracyAuth = 12, ///<精确定位权限异常 }; ///AMapLocation Region State @@ -46,6 +47,13 @@ typedef NS_ENUM(NSInteger, AMapLocationReGeocodeLanguage) AMapLocationReGeocodeLanguageEnglish = 2, ///<英文 }; +///AMapLocation Accuracy Mode +typedef NS_ENUM(NSInteger, AMapLocationAccuracyMode) { + AMapLocationFullAndReduceAccuracy = 0, + AMapLocationFullAccuracy, + AMapLocationReduceAccuracy +}; + ///逆地理信息 @interface AMapLocationReGeocode : NSObject diff --git a/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationManager.h b/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationManager.h index 25743a0..d019781 100644 --- a/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationManager.h +++ b/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationManager.h @@ -31,7 +31,9 @@ typedef void (^AMapLocatingCompletionBlock)(CLLocation *location, AMapLocationRe ///设定定位的最小更新距离。单位米,默认为 kCLDistanceFilterNone,表示只要检测到设备位置发生变化就会更新位置信息。 @property(nonatomic, assign) CLLocationDistance distanceFilter; -///设定期望的定位精度。单位米,默认为 kCLLocationAccuracyBest。定位服务会尽可能去获取满足desiredAccuracy的定位结果,但不保证一定会得到满足期望的结果。 \n注意:设置为kCLLocationAccuracyBest或kCLLocationAccuracyBestForNavigation时,单次定位会在达到locationTimeout设定的时间后,将时间内获取到的最高精度的定位结果返回。 +///设定期望的定位精度。单位米,默认为 kCLLocationAccuracyBest。定位服务会尽可能去获取满足desiredAccuracy的定位结果,但不保证一定会得到满足期望的结果。 +///注意:设置为kCLLocationAccuracyBest或kCLLocationAccuracyBestForNavigation时,单次定位会在达到locationTimeout设定的时间后,将时间内获取到的最高精度的定位结果返回。 +///⚠️ 当iOS14及以上时,模糊定位权限下可能拿不到设置精度的经纬度 @property(nonatomic, assign) CLLocationAccuracy desiredAccuracy; ///指定定位是否会被系统自动暂停。默认为NO。 @@ -49,7 +51,7 @@ typedef void (^AMapLocatingCompletionBlock)(CLLocation *location, AMapLocationRe ///连续定位是否返回逆地理信息,默认NO。 @property (nonatomic, assign) BOOL locatingWithReGeocode; -// 逆地址语言类型,默认是AMapLocationRegionLanguageDefault +///逆地址语言类型,默认是AMapLocationRegionLanguageDefault @property (nonatomic, assign) AMapLocationReGeocodeLanguage reGeocodeLanguage; ///获取被监控的region集合。 @@ -58,6 +60,38 @@ typedef void (^AMapLocatingCompletionBlock)(CLLocation *location, AMapLocationRe ///检测是否存在虚拟定位风险,默认为NO,不检测。 \n注意:设置为YES时,单次定位通过 AMapLocatingCompletionBlock 的error给出虚拟定位风险提示;连续定位通过 amapLocationManager:didFailWithError: 方法的error给出虚拟定位风险提示。error格式为 error.domain==AMapLocationErrorDomain; error.code==AMapLocationErrorRiskOfFakeLocation; \n附带的error的详细信息参考 error.localizedDescription 中的描述以及 error.userInfo 中的信息(error.userInfo.AMapLocationRiskyLocateResult 表示有虚拟风险的定位结果; error.userInfo.AMapLocationAccessoryInfo 表示外接辅助设备信息)。 @property (nonatomic, assign) BOOL detectRiskOfFakeLocation; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 + +/** + * @brief 设置预期定位精度权限模式,默认为CLAccuracyAuthorizationFullAccuracy精确模式。 + 注意:如果定位时未获得定位权限,则首先会调用申请定位权限API,实际定位精度权限取决于用户的权限设置,当前定位精度权限可通过currentAuthorization获取;如果定位时已获得定位模糊权限,该属性设置CLAccuracyAuthorizationFullAccuracy,则会触发回调amapLocationManager:doRequireTemporaryFullAccuracyAuth:completion:,需在该回调中实现调用申请临时精确定位权限API,如果用户选择拒绝,则可以在completion回调中设置ignoreAuthMatch控制是否要继续开启模糊定位;如果定位时已获得精确定位权限,则可通过desiredAccuracy参数设定期望的定位精度; + * @since 2.6.7 + */ +//@property (nonatomic, assign) CLAccuracyAuthorization desiredAccuracyMode API_AVAILABLE(ios(14.0)); + +/** + * @brief 设置定位数据回调精度模式,默认为AMapLocationAccuracyFullAndReduce。 + 注意:如果定位时未获得定位权限,则首先会调用申请定位权限API,实际定位精度权限取决于用户的权限设置。 + * ———————————————————————————————————————————————————————————————— + * | 设置选项 | doRequireTemporaryFullAccuracyAuth | 异常/定位数据回调 | + * | AMapLocationFullAndReduceAccuracy | 会触发申请临时精确定位回调 | 如果未获得精确定位权限,则依然开启定位,回调模糊定位 | + * | AMapLocationFullAccuracy | 会触发申请临时精确定位回调 | 如果未获得精确定位权限,则不开启定位,回调error | + * | AMapLocationReduceAccuracy | 不会触发申请临时精确定位回调 | 根据当前定位精度权限,回调定位数据 | + * ———————————————————————————————————————————————————————————————— + * 当设置AMapLocationFullAndReduceAccuracy时,定位数据回调可通过currentAuthorization判断当前是否是精确定位 + * @since 2.6.7 + */ +@property (nonatomic, assign) AMapLocationAccuracyMode locationAccuracyMode API_AVAILABLE(ios(14.0)); + +/** + * @brief 获取当前定位精度权限。注意:可能与setAccuracyAuthorizationMode设置不一致 + * @since 2.6.7 + */ +@property (nonatomic, readonly) CLAccuracyAuthorization currentAuthorization API_AVAILABLE(ios(14.0)); + +#endif + /** * @brief 设备是否支持方向识别 * @return YES:设备支持方向识别 ; NO:设备不支持支持方向识别 @@ -124,9 +158,27 @@ typedef void (^AMapLocatingCompletionBlock)(CLLocation *location, AMapLocationRe @optional +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 + +/** + * @brief 当plist配置NSLocationTemporaryUsageDescriptionDictionary且desiredAccuracyMode设置CLAccuracyAuthorizationFullAccuracy精确定位模式时,如果用户只授权模糊定位,会调用代理的此方法。此方法实现调用申请临时精确定位权限API即可: + * [manager requestTemporaryFullAccuracyAuthorizationWithPurposeKey:@"PurposeKey" completion:^(NSError *error){ + * if(completion){ + * completion(error); + * } + * }]; (必须调用,不然无法正常获取临时精确定位权限) + * @param manager 定位 AMapLocationManager 类。 + * @param locationManager 需要申请临时精确定位权限的locationManager。 + * @param completion 临时精确定位权限API回调结果,error: 直接返回系统error即可。 + * @since 2.6.7 + */ +- (void)amapLocationManager:(AMapLocationManager *)manager doRequireTemporaryFullAccuracyAuth:(CLLocationManager*)locationManager completion:(void(^)(NSError *error))completion; + +#endif + /** * @brief 当plist配置NSLocationAlwaysUsageDescription或者NSLocationAlwaysAndWhenInUseUsageDescription,并且[CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined,会调用代理的此方法。 - 此方法实现调用申请后台权限API即可:[locationManager requestAlwaysAuthorization](必须调用,不然无法正常获取定位权限) + 此方法实现调用申请后台权限API即可:[locationManager requestAlwaysAuthorization] (必须调用,不然无法正常获取定位权限) * @param manager 定位 AMapLocationManager 类。 * @param locationManager 需要申请后台定位权限的locationManager。 * @since 2.6.2 @@ -156,12 +208,19 @@ typedef void (^AMapLocatingCompletionBlock)(CLLocation *location, AMapLocationRe - (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode; /** - * @brief 定位权限状态改变时回调函数 + * @brief 定位权限状态改变时回调函数。注意:iOS13及之前版本回调 * @param manager 定位 AMapLocationManager 类。 * @param status 定位权限状态。 */ - (void)amapLocationManager:(AMapLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status; +/** + * @brief 定位权限状态改变时回调函数。注意:iOS14及之后版本回调 + * @param manager 定位 AMapLocationManager 类。 + * @param locationManager 定位CLLocationManager类,可通过locationManager.authorizationStatus获取定位权限,通过locationManager.accuracyAuthorization获取定位精度权限 + */ +- (void)amapLocationManager:(AMapLocationManager *)manager locationManagerDidChangeAuthorization:(CLLocationManager*)locationManager; + /** * @brief 是否显示设备朝向校准 * @param manager 定位 AMapLocationManager 类。 diff --git a/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationVersion.h b/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationVersion.h index 57e09bf..651160e 100644 --- a/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationVersion.h +++ b/Pods/AMapLocation/AMapLocationKit.framework/Headers/AMapLocationVersion.h @@ -12,8 +12,8 @@ #ifndef AMapLoctionVersion_h #define AMapLoctionVersion_h -#define AMapLocationVersionNumber 20602 -#define AMapLocationFoundationVersionMinRequired 10400 +#define AMapLocationVersionNumber 20607 +#define AMapLocationFoundationVersionMinRequired 10604 // 依赖库版本检测 #if AMapFoundationVersionNumber < AMapLocationFoundationVersionMinRequired diff --git a/Pods/AMapLocation/AMapLocationKit.framework/version.txt b/Pods/AMapLocation/AMapLocationKit.framework/version.txt index a478625..c8e96ed 100644 --- a/Pods/AMapLocation/AMapLocationKit.framework/version.txt +++ b/Pods/AMapLocation/AMapLocationKit.framework/version.txt @@ -1 +1 @@ -2.6.2+loc.428123e +2.6.7+loc.ec398d6 diff --git a/Pods/AMapSearch/AMapSearchKit.framework/AMapSearchKit b/Pods/AMapSearch/AMapSearchKit.framework/AMapSearchKit new file mode 100644 index 0000000..f6dd905 Binary files /dev/null and b/Pods/AMapSearch/AMapSearchKit.framework/AMapSearchKit differ diff --git a/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapCommonObj.h b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapCommonObj.h new file mode 100644 index 0000000..c272a19 --- /dev/null +++ b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapCommonObj.h @@ -0,0 +1,864 @@ +// +// AMapCommonObj.h +// AMapSearchKit +// +// Created by xiaoming han on 15/7/22. +// Copyright (c) 2015年 Amap. All rights reserved. +// + +/* 该文件定义了搜索结果的基础数据类型。*/ + +#import +#import + +#pragma mark - AMapSearchObject + +///搜索SDK基础类, 通用数据结构和response支持copy和coding(since 4.4.1)。 +@interface AMapSearchObject : NSObject + +/** + * @brief 返回格式化的描述信息。通用数据结构和response类型有效。 + */ +- (NSString *)formattedDescription; + +@end + +#pragma mark - 通用数据结构 + +///经纬度, description中格式为 <经度,纬度> +@interface AMapGeoPoint : AMapSearchObject +///纬度(垂直方向) +@property (nonatomic, assign) CGFloat latitude; +///经度(水平方向) +@property (nonatomic, assign) CGFloat longitude; + +/** + * @brief 实例化一个AMapGeoPoint对象 + * @param lat 纬度 + * @param lon 经度 + */ ++ (AMapGeoPoint *)locationWithLatitude:(CGFloat)lat longitude:(CGFloat)lon; +@end + +///多边形, 当传入两个点的时候,当做矩形处理:左下-右上两个顶点;其他情况视为多边形,几个点即为几边型。 +@interface AMapGeoPolygon : AMapSearchObject +///坐标集, AMapGeoPoint 数组 +@property (nonatomic, strong) NSArray *points; + +/** + * @brief 实例化一个多边形对象 + * @param points 坐标集, AMapGeoPoint 数组 + */ ++ (AMapGeoPolygon *)polygonWithPoints:(NSArray *)points; +@end + +@class AMapDistrict; +///城市 +@interface AMapCity : AMapSearchObject +///城市名称 +@property (nonatomic, copy) NSString *city; +///城市编码 +@property (nonatomic, copy) NSString *citycode; +///城市区域编码 +@property (nonatomic, copy) NSString *adcode; +///此区域的建议结果数目, AMapSuggestion 中使用 +@property (nonatomic, assign) NSInteger num; +///途径区域 AMapDistrict 数组,AMepStep中使用,只有name和adcode。 +@property (nonatomic, strong) NSArray *districts; +@end + +///建议信息 +@interface AMapSuggestion : AMapSearchObject +///NSString 数组 +@property (nonatomic, strong) NSArray *keywords; +///AMapCity 数组 +@property (nonatomic, strong) NSArray *cities; +@end + +#pragma mark - 输入提示 + +///输入提示 +@interface AMapTip : AMapSearchObject +///poi的id +@property (nonatomic, copy) NSString *uid; +///名称 +@property (nonatomic, copy) NSString *name; +///区域编码 +@property (nonatomic, copy) NSString *adcode; +///所属区域 +@property (nonatomic, copy) NSString *district; +///地址 +@property (nonatomic, copy) NSString *address; +///位置 +@property (nonatomic, copy) AMapGeoPoint *location; +///类型码, since 4.5.0. 对应描述可下载参考官网文档 http://a.amap.com/lbs/static/zip/AMap_API_Table.zip。 +@property (nonatomic, copy) NSString *typecode; +@end + +#pragma mark - POI + +///POI图片信息 +@interface AMapImage : AMapSearchObject +///标题 +@property (nonatomic, copy) NSString *title; +///url +@property (nonatomic, copy) NSString *url; +@end + +///POI扩展信息 +@interface AMapPOIExtension : AMapSearchObject +///评分 +@property (nonatomic, assign) CGFloat rating; +///人均消费 +@property (nonatomic, assign) CGFloat cost; +///营业时间 +@property (nonatomic, copy) NSString *openTime; +@end + +///POI室内地图信息 +@interface AMapIndoorData : AMapSearchObject +///楼层,为0时为POI本身 +@property (nonatomic, assign) NSInteger floor; +///楼层名称 +@property (nonatomic, copy) NSString *floorName; +///建筑物ID +@property (nonatomic, copy) NSString *pid; +@end + +///子POI +@interface AMapSubPOI : AMapSearchObject +///POI全局唯一ID +@property (nonatomic, copy) NSString *uid; +///名称 +@property (nonatomic, copy) NSString *name; +///名称简写 +@property (nonatomic, copy) NSString *sname; +///经纬度 +@property (nonatomic, copy) AMapGeoPoint *location; +///地址 +@property (nonatomic, copy) NSString *address; +///距中心点距离 +@property (nonatomic, assign) NSInteger distance; +///子POI类型 +@property (nonatomic, copy) NSString *subtype; +@end + +///沿途POI +@interface AMapRoutePOI : AMapSearchObject +///POI全局唯一ID +@property (nonatomic, copy) NSString *uid; +///名称 +@property (nonatomic, copy) NSString *name; +///经纬度 +@property (nonatomic, copy) AMapGeoPoint *location; +///用户起点经过途经点再到终点的距离,单位是米 +@property (nonatomic, assign) NSInteger distance; +///用户起点经过途经点再到终点的时间,单位为秒 +@property (nonatomic, assign) NSInteger duration; +@end + +///POI +@interface AMapPOI : AMapSearchObject +///POI全局唯一ID +@property (nonatomic, copy) NSString *uid; +///名称 +@property (nonatomic, copy) NSString *name; +///兴趣点类型 +@property (nonatomic, copy) NSString *type; +///类型编码 +@property (nonatomic, copy) NSString *typecode; +///经纬度 +@property (nonatomic, copy) AMapGeoPoint *location; +///地址 +@property (nonatomic, copy) NSString *address; +///电话 +@property (nonatomic, copy) NSString *tel; +///距中心点的距离,单位米。在周边搜索时有效 +@property (nonatomic, assign) NSInteger distance; +///停车场类型,地上、地下、路边 +@property (nonatomic, copy) NSString *parkingType; +///商铺id +@property (nonatomic, copy) NSString *shopID; + +///邮编 +@property (nonatomic, copy) NSString *postcode; +///网址 +@property (nonatomic, copy) NSString *website; +///电子邮件 +@property (nonatomic, copy) NSString *email; +///省 +@property (nonatomic, copy) NSString *province; +///省编码 +@property (nonatomic, copy) NSString *pcode; +///城市名称 +@property (nonatomic, copy) NSString *city; +///城市编码 +@property (nonatomic, copy) NSString *citycode; +///区域名称 +@property (nonatomic, copy) NSString *district; +///区域编码 +@property (nonatomic, copy) NSString *adcode; +///地理格ID +@property (nonatomic, copy) NSString *gridcode; +///入口经纬度 +@property (nonatomic, copy) AMapGeoPoint *enterLocation; +///出口经纬度 +@property (nonatomic, copy) AMapGeoPoint *exitLocation; +///方向 +@property (nonatomic, copy) NSString *direction; +///是否有室内地图 +@property (nonatomic, assign) BOOL hasIndoorMap; +///所在商圈 +@property (nonatomic, copy) NSString *businessArea; +///室内信息 +@property (nonatomic, strong) AMapIndoorData *indoorData; +///子POI列表 +@property (nonatomic, strong) NSArray *subPOIs; +///图片列表 +@property (nonatomic, strong) NSArray *images; + +///扩展信息只有在ID查询时有效 +@property (nonatomic, strong) AMapPOIExtension *extensionInfo; +@end + +#pragma mark - 逆地理编码 && 地理编码 + +///兴趣区域 +@interface AMapAOI : AMapSearchObject +///AOI全局唯一ID +@property (nonatomic, copy) NSString *uid; +///名称 +@property (nonatomic, copy) NSString *name; +///所在区域编码 +@property (nonatomic, copy) NSString *adcode; +///中心点经纬度 +@property (nonatomic, copy) AMapGeoPoint *location; +///面积,单位平方米 +@property (nonatomic, assign) CGFloat area; +@end + +///道路 +@interface AMapRoad : AMapSearchObject +///道路ID +@property (nonatomic, copy) NSString *uid; +///道路名称 +@property (nonatomic, copy) NSString *name; +///距离(单位:米) +@property (nonatomic, assign) NSInteger distance; +///方向 +@property (nonatomic, copy) NSString *direction; +///坐标点 +@property (nonatomic, copy) AMapGeoPoint *location; +@end + +///道路交叉口 +@interface AMapRoadInter : AMapSearchObject +///距离(单位:米) +@property (nonatomic, assign) NSInteger distance; +///方向 +@property (nonatomic, copy) NSString *direction; +///经纬度 +@property (nonatomic, copy) AMapGeoPoint *location; +///第一条道路ID +@property (nonatomic, copy) NSString *firstId; +///第一条道路名称 +@property (nonatomic, copy) NSString *firstName; +///第二条道路ID +@property (nonatomic, copy) NSString *secondId; +///第二条道路名称 +@property (nonatomic, copy) NSString *secondName; +@end + +///门牌信息 +@interface AMapStreetNumber : AMapSearchObject +///街道名称 +@property (nonatomic, copy) NSString *street; +///门牌号 +@property (nonatomic, copy) NSString *number; +///坐标点 +@property (nonatomic, copy) AMapGeoPoint *location; +///距离(单位:米) +@property (nonatomic, assign) NSInteger distance; +///方向 +@property (nonatomic, copy) NSString *direction; +@end + +///商圈 +@interface AMapBusinessArea : AMapSearchObject +///名称 +@property (nonatomic, strong) NSString *name; +///中心坐标 +@property (nonatomic, copy) AMapGeoPoint *location; +@end + +///地址组成要素 +@interface AMapAddressComponent : AMapSearchObject +///国家(since 5.7.0) +@property (nonatomic, copy) NSString *country; +///国家简码(since 7.4.0)仅海外生效 +@property (nonatomic, copy) NSString *countryCode; +///省/直辖市 +@property (nonatomic, copy) NSString *province; +///市 +@property (nonatomic, copy) NSString *city; +///城市编码 +@property (nonatomic, copy) NSString *citycode; +///区 +@property (nonatomic, copy) NSString *district; +///区域编码 +@property (nonatomic, copy) NSString *adcode; +///乡镇街道 +@property (nonatomic, copy) NSString *township; +///乡镇街道编码 +@property (nonatomic, copy) NSString *towncode; +///社区 +@property (nonatomic, copy) NSString *neighborhood; +///建筑 +@property (nonatomic, copy) NSString *building; +///门牌信息 +@property (nonatomic, strong) AMapStreetNumber *streetNumber; +///商圈列表 AMapBusinessArea 数组 +@property (nonatomic, strong) NSArray *businessAreas; +@end + +///逆地理编码 +@interface AMapReGeocode : AMapSearchObject +///格式化地址 +@property (nonatomic, copy) NSString *formattedAddress; +///地址组成要素 +@property (nonatomic, strong) AMapAddressComponent *addressComponent; + +///道路信息 AMapRoad 数组 +@property (nonatomic, strong) NSArray *roads; +///道路路口信息 AMapRoadInter 数组 +@property (nonatomic, strong) NSArray *roadinters; +///兴趣点信息 AMapPOI 数组 +@property (nonatomic, strong) NSArray *pois; +///兴趣区域信息 AMapAOI 数组 +@property (nonatomic, strong) NSArray *aois; +@end + +///地理编码 +@interface AMapGeocode : AMapSearchObject +///格式化地址 +@property (nonatomic, copy) NSString *formattedAddress; +///所在省/直辖市 +@property (nonatomic, copy) NSString *province; +///城市名 +@property (nonatomic, copy) NSString *city; +///城市编码 +@property (nonatomic, copy) NSString *citycode; +///区域名称 +@property (nonatomic, copy) NSString *district; +///区域编码 +@property (nonatomic, copy) NSString *adcode; +///乡镇街道 +@property (nonatomic, copy) NSString *township; +///社区 +@property (nonatomic, copy) NSString *neighborhood; +///楼 +@property (nonatomic, copy) NSString *building; +///坐标点 +@property (nonatomic, copy) AMapGeoPoint *location; +///匹配的等级 +@property (nonatomic, copy) NSString *level; +///国家(since 7.4.0)仅海外生效 +@property (nonatomic, copy) NSString *country; +///国家简码(since 7.4.0)仅海外生效 +@property (nonatomic, copy) NSString *postcode; +@end + +#pragma mark - 公交查询 +@class AMapBusLine; + +///公交站 +@interface AMapBusStop : AMapSearchObject +///公交站点ID +@property (nonatomic, copy) NSString *uid; +///区域编码 +@property (nonatomic, copy) NSString *adcode; +///公交站名 +@property (nonatomic, copy) NSString *name; +///城市编码 +@property (nonatomic, copy) NSString *citycode; +///经纬度坐标 +@property (nonatomic, copy) AMapGeoPoint *location; +///途径此站的公交路线 AMapBusLine 数组 +@property (nonatomic, strong) NSArray *buslines; +///查询公交线路时的第几站 +@property (nonatomic, copy) NSString *sequence; +@end + +///公交线路 +@interface AMapBusLine : AMapSearchObject +///公交线路ID +@property (nonatomic, copy) NSString *uid; +///公交类型 +@property (nonatomic, copy) NSString *type; +///公交线路名称 +@property (nonatomic, copy) NSString *name; +///坐标集合 +@property (nonatomic, copy) NSString *polyline; +///城市编码 +@property (nonatomic, copy) NSString *citycode; +///首发站 +@property (nonatomic, copy) NSString *startStop; +///终点站 +@property (nonatomic, copy) NSString *endStop; +///当查询公交站点时,返回的 AMapBusLine 中含有该字段 +@property (nonatomic, copy) AMapGeoPoint *location; + +///首班车时间 +@property (nonatomic, copy) NSString *startTime; +///末班车时间 +@property (nonatomic, copy) NSString *endTime; +///所属公交公司 +@property (nonatomic, copy) NSString *company; +///距离。在公交线路查询时,该值为此线路的全程距离,单位为千米; 在公交路径规划时,该值为乘坐此路公交车的行驶距离,单位为米 +@property (nonatomic, assign) CGFloat distance; +///起步价 +@property (nonatomic, assign) CGFloat basicPrice; +///全程票价 +@property (nonatomic, assign) CGFloat totalPrice; +///矩形区域左下、右上顶点坐标 +@property (nonatomic, copy) AMapGeoPolygon *bounds; +///本线路公交站 AMapBusStop 数组 +@property (nonatomic, strong) NSArray *busStops; + +///起程站 +@property (nonatomic, strong) AMapBusStop *departureStop; +///下车站 +@property (nonatomic, strong) AMapBusStop *arrivalStop; +///途径公交站 AMapBusStop 数组 +@property (nonatomic, strong) NSArray *viaBusStops; +///预计行驶时间(单位:秒) +@property (nonatomic, assign) NSInteger duration; +@end + +#pragma mark - 行政区划 +///行政区划 +@interface AMapDistrict : AMapSearchObject +///区域编码 +@property (nonatomic, copy) NSString *adcode; +///城市编码 +@property (nonatomic, copy) NSString *citycode; +///行政区名称 +@property (nonatomic, copy) NSString *name; +///级别 +@property (nonatomic, copy) NSString *level; +///城市中心点 +@property (nonatomic, copy) AMapGeoPoint *center; +///下级行政区域数组 +@property (nonatomic, strong) NSArray *districts; +///行政区边界坐标点, NSString 数组 +@property (nonatomic, strong) NSArray *polylines; +@end + +#pragma mark - 路径规划 + +///实时路况信息 +@interface AMapTMC : AMapSearchObject +///长度(单位:米) +@property (nonatomic, assign) NSInteger distance; +///路况状态描述:0 未知,1 畅通,2 缓行,3 拥堵,4 严重拥堵 +@property (nonatomic, copy) NSString *status; +///此路段坐标点串 +@property (nonatomic, copy) NSString *polyline; +@end + +///路段基本信息 +@interface AMapStep : AMapSearchObject +///行走指示 +@property (nonatomic, copy) NSString *instruction; +///方向 +@property (nonatomic, copy) NSString *orientation; +///道路名称 +@property (nonatomic, copy) NSString *road; +///此路段长度(单位:米) +@property (nonatomic, assign) NSInteger distance; +///此路段预计耗时(单位:秒) +@property (nonatomic, assign) NSInteger duration; +///此路段坐标点串 +@property (nonatomic, copy) NSString *polyline; +///导航主要动作 +@property (nonatomic, copy) NSString *action; +///导航辅助动作 +@property (nonatomic, copy) NSString *assistantAction; +///此段收费(单位:元) +@property (nonatomic, assign) CGFloat tolls; +///收费路段长度(单位:米) +@property (nonatomic, assign) NSInteger tollDistance; +///主要收费路段 +@property (nonatomic, copy) NSString *tollRoad; + +///途径城市 AMapCity 数组,只有驾车路径规划时有效 +@property (nonatomic, strong) NSArray *cities; +///路况信息数组,只有驾车路径规划时有效 +@property (nonatomic, strong) NSArray *tmcs; +@end + +///步行、骑行、驾车方案 +@interface AMapPath : AMapSearchObject +///起点和终点的距离 +@property (nonatomic, assign) NSInteger distance; +///预计耗时(单位:秒) +@property (nonatomic, assign) NSInteger duration; +///导航策略 +@property (nonatomic, copy) NSString *strategy; +///导航路段 AMapStep 数组 +@property (nonatomic, strong) NSArray *steps; +///此方案费用(单位:元) +@property (nonatomic, assign) CGFloat tolls; +///此方案收费路段长度(单位:米) +@property (nonatomic, assign) NSInteger tollDistance; +///此方案交通信号灯个数 +@property (nonatomic, assign) NSInteger totalTrafficLights; + +/** + 限行信息,仅在驾车和货车路径规划时有效。(since 6.0.0) + 驾车路径规划时: + 0 代表限行已规避或未限行; 1 代表限行无法规避。 + 货车路径规划时: + 0,未知(未输入完整/正确车牌号信息时候显示) + 1,已规避限行 + 2,起点限行 + 3,途径点在限行区域内(设置途径点才出现此报错) + 4,途径限行区域 + 5,终点限行 + */ +@property (nonatomic, assign) NSInteger restriction; +///规划路径完整坐标点串集合(since 7.4.0) +@property (nonatomic, copy) NSString *polyline; + +@end + +@interface AMapFutureTimeInfoElement : AMapSearchObject + +///总时长(分钟) +@property (nonatomic, assign) NSInteger duration; +///对应的路径规划方案中的路线 +@property (nonatomic, assign) NSInteger pathindex; +/** + 0:代表限行已规避或未限行,即该路线没有限行路段 + 1:代表限行无法规避,即该线路有限行路段 + */ +@property (nonatomic, assign) NSInteger restriction; +///路况信息数组,只会返回AMapTMC中的status、polyline +@property (nonatomic, strong) NSArray *tmcs; + +@end + +@interface AMapFutureTimeInfo : AMapSearchObject + +///出发时间 +@property (nonatomic, copy) NSString *startTime; +///路线列表 AMapFutureTimeInfoElement 数组 +@property (nonatomic, strong) NSArray *elements; +@end + +///步行换乘信息 +@interface AMapWalking : AMapSearchObject +///起点坐标 +@property (nonatomic, copy) AMapGeoPoint *origin; +///终点坐标 +@property (nonatomic, copy) AMapGeoPoint *destination; +///起点和终点的步行距离 +@property (nonatomic, assign) NSInteger distance; +///步行预计时间 +@property (nonatomic, assign) NSInteger duration; +///步行路段 AMapStep 数组 +@property (nonatomic, strong) NSArray *steps; +@end + +///出租车信息 +@interface AMapTaxi : AMapSearchObject +///起点坐标 +@property (nonatomic, copy) AMapGeoPoint *origin; +///终点坐标 +@property (nonatomic, copy) AMapGeoPoint *destination; +///距离,单位米 +@property (nonatomic, assign) NSInteger distance; +///耗时,单位秒 +@property (nonatomic, assign) NSInteger duration; +///起点名称 +@property (nonatomic, copy) NSString *sname; +///终点名称 +@property (nonatomic, copy) NSString *tname; +@end + +///火车站 +@interface AMapRailwayStation : AMapSearchObject +///火车站ID +@property (nonatomic, copy) NSString *uid; +///名称 +@property (nonatomic, copy) NSString *name; +///经纬度坐标 +@property (nonatomic, copy) AMapGeoPoint *location; +///区域编码 +@property (nonatomic, copy) NSString *adcode; +///发车、到站时间,途径站时则为进站时间 +@property (nonatomic, copy) NSString *time; +///途径站点的停靠时间,单位为分钟 +@property (nonatomic, assign) NSInteger wait; +///是否是始发站,为出发站时有效 +@property (nonatomic, assign) BOOL isStart; +///是否是终点站,为到达站时有效 +@property (nonatomic, assign) BOOL isEnd; +@end + +///火车仓位及价格信息 +@interface AMapRailwaySpace : AMapSearchObject +///类型,硬卧、硬座等 +@property (nonatomic, copy) NSString *code; +///票价,单位元 +@property (nonatomic, assign) CGFloat cost; +@end + +///火车信息 +@interface AMapRailway : AMapSearchObject +///火车线路ID +@property (nonatomic, copy) NSString *uid; +///名称 +@property (nonatomic, copy) NSString *name; +///车次 +@property (nonatomic, copy) NSString *trip; +///类型 +@property (nonatomic, copy) NSString *type; +///该换乘段行车总距离,单位为米 +@property (nonatomic, assign) NSInteger distance; +///该线路车段耗时,单位为秒 +@property (nonatomic, assign) NSInteger time; +///出发站 +@property (nonatomic, strong) AMapRailwayStation *departureStation; +///到达站 +@property (nonatomic, strong) AMapRailwayStation *arrivalStation; +///仓位及价格信息 +@property (nonatomic, strong) NSArray *spaces; + +///途径站点信息 +@property (nonatomic, strong) NSArray *viaStops; +///备选路线信息, 目前只有id和name +@property (nonatomic, strong) NSArray *alters; +@end + + +///公交换乘路段,如果walking和buslines同时有值,则是先walking后buslines +@interface AMapSegment : AMapSearchObject +///此路段步行导航信息 +@property (nonatomic, strong) AMapWalking *walking; +///此路段可供选择的不同公交线路 AMapBusLine 数组 +@property (nonatomic, strong) NSArray *buslines; +///出租车信息,跨城时有效 +@property (nonatomic, strong) AMapTaxi *taxi; +///火车信息,跨城时有效 +@property (nonatomic, strong) AMapRailway *railway; +///入口名称 +@property (nonatomic, copy) NSString *enterName; +///入口经纬度 +@property (nonatomic, copy) AMapGeoPoint *enterLocation; +///出口名称 +@property (nonatomic, copy) NSString *exitName; +///出口经纬度 +@property (nonatomic, copy) AMapGeoPoint *exitLocation; +@end + +///公交方案 +@interface AMapTransit : AMapSearchObject +///此公交方案价格(单位:元) +@property (nonatomic, assign) CGFloat cost; +///此换乘方案预期时间(单位:秒) +@property (nonatomic, assign) NSInteger duration; +///是否是夜班车 +@property (nonatomic, assign) BOOL nightflag; +///此方案总步行距离(单位:米) +@property (nonatomic, assign) NSInteger walkingDistance; +///换乘路段 AMapSegment 数组 +@property (nonatomic, strong) NSArray *segments; +///当前方案的总距离 +@property (nonatomic, assign) NSInteger distance; +@end + +///路径规划信息 +@interface AMapRoute : AMapSearchObject +///起点坐标 +@property (nonatomic, copy) AMapGeoPoint *origin; +///终点坐标 +@property (nonatomic, copy) AMapGeoPoint *destination; +///出租车费用(单位:元) +@property (nonatomic, assign) CGFloat taxiCost; +///步行、骑行、驾车方案列表 AMapPath 数组 +@property (nonatomic, strong) NSArray *paths; +///公交换乘方案列表 AMapTransit 数组 +@property (nonatomic, strong) NSArray *transits; +@end + +///距离测量结果 +@interface AMapDistanceResult : AMapSearchObject +///起点坐标,起点坐标序列号(从1开始) +@property (nonatomic, assign) NSInteger originID; +///终点坐标,终点坐标序列号(从1开始) +@property (nonatomic, assign) NSInteger destID; +///路径距离,单位:米 +@property (nonatomic, assign) NSInteger distance; +///预计行驶时间,单位:秒 +@property (nonatomic, assign) NSInteger duration; +///错误信息,建议用此字段判断请求是否成功 +@property (nonatomic, copy) NSString *info; +///在驾车模式下有效。默认为0;1:指定地点之间没有可以行车的道路;2:起点/终点 距离所有道路均距离过远(例如在海洋/矿业);3;起点/终点不在中国境内; +@property (nonatomic, assign) NSInteger code; +@end + +#pragma mark - 天气查询 + +///实况天气,仅支持中国部分地区数据(台湾省目前没有数据)返回 +@interface AMapLocalWeatherLive : AMapSearchObject +///区域编码 +@property (nonatomic, copy) NSString *adcode; +///省份名 +@property (nonatomic, copy) NSString *province; +///城市名 +@property (nonatomic, copy) NSString *city; +///天气现象 +@property (nonatomic, copy) NSString *weather; +///实时温度 +@property (nonatomic, copy) NSString *temperature; +///风向 +@property (nonatomic, copy) NSString *windDirection; +///风力,单位:级 +@property (nonatomic, copy) NSString *windPower; +///空气湿度 +@property (nonatomic, copy) NSString *humidity; +///数据发布时间 +@property (nonatomic, copy) NSString *reportTime; +@end + +///某一天的天气预报信息 +@interface AMapLocalDayWeatherForecast : AMapSearchObject +///日期 +@property (nonatomic, copy) NSString *date; +///星期 +@property (nonatomic, copy) NSString *week; +///白天天气现象 +@property (nonatomic, copy) NSString *dayWeather; +///晚上天气现象 +@property (nonatomic, copy) NSString *nightWeather; +///白天温度 +@property (nonatomic, copy) NSString *dayTemp; +///晚上温度 +@property (nonatomic, copy) NSString *nightTemp; +///白天风向 +@property (nonatomic, copy) NSString *dayWind; +///晚上风向 +@property (nonatomic, copy) NSString *nightWind; +///白天风力 +@property (nonatomic, copy) NSString *dayPower; +///晚上风力 +@property (nonatomic, copy) NSString *nightPower; +@end + +///天气预报类,支持当前时间在内的3天的天气进行预报 +@interface AMapLocalWeatherForecast : AMapSearchObject +///区域编码 +@property (nonatomic, copy) NSString *adcode; +///省份名 +@property (nonatomic, copy) NSString *province; +///城市名 +@property (nonatomic, copy) NSString *city; +///数据发布时间 +@property (nonatomic, copy) NSString *reportTime; +///天气预报AMapLocalDayWeatherForecast数组 +@property (nonatomic, strong) NSArray *casts; +@end + +#pragma mark - 附近搜索 +///附近搜索返回的用户信息 +@interface AMapNearbyUserInfo : AMapSearchObject +///用户ID +@property (nonatomic, copy) NSString *userID; +///最后更新位置 +@property (nonatomic, copy) AMapGeoPoint *location; +///与搜索点的距离,由搜索时searchType决定 +@property (nonatomic, assign) CGFloat distance; +///最后更新的时间戳,单位秒 +@property (nonatomic, assign) NSTimeInterval updatetime; +@end + +#pragma mark - 交通态势 + +///道路路况评价 since 5.1.0 +@interface AMapTrafficEvaluation : AMapSearchObject +///综述 +@property (nonatomic, copy) NSString *evaluationDescription; +///0:未知;1:畅通;2:缓行;3:拥堵 +@property (nonatomic, assign) NSInteger status; +///畅通所占百分比 +@property (nonatomic, copy) NSString *expedite; +///缓行所占百分比 +@property (nonatomic, copy) NSString *congested; +///拥堵所占百分比 +@property (nonatomic, copy) NSString *blocked; +///未知路段所占百分比 +@property (nonatomic, copy) NSString *unknown; +@end + +///道路路况返回的道路信息 since 5.1.0 +@interface AMapTrafficRoad : AMapSearchObject +///道路名称 +@property (nonatomic, copy) NSString *name; +///0:未知;1:畅通;2:缓行;3:拥堵 +@property (nonatomic, assign) NSInteger status; +///方向描述 +@property (nonatomic, copy) NSString *direction; +///车行角度,判断道路正反向使用。 以正东方向为0度,逆时针方向为正,取值范围:[0,360] +@property (nonatomic, assign) float angle; +///速度 单位:千米/小时 +@property (nonatomic, assign) float speed; +///道路坐标集,经度和纬度使用","分隔,坐标之间使用";"分隔。例如:x1,y1;x2,y2 +@property (nonatomic, copy) NSString *polyline; +@end + +///道路路况信息 since 5.1.0 +@interface AMapTrafficInfo : AMapSearchObject +///路况综述 +@property (nonatomic, copy) NSString *statusDescription; +///路况评价 +@property (nonatomic, strong) AMapTrafficEvaluation *evaluation; +///道路信息 +@property (nonatomic, strong) NSArray* roads; + +@end + +#pragma mark - 企业地图基础数据类型 + +///POI点的图片信息 +@interface AMapCloudImage : AMapSearchObject +///图片的id标识 +@property (nonatomic, copy) NSString *uid; +///图片压缩后的url串 +@property (nonatomic, copy) NSString *preurl; +///图片原始的url +@property (nonatomic, copy) NSString *url; +@end + +///POI信息 +@interface AMapCloudPOI : AMapSearchObject +///唯一标识 +@property (nonatomic, assign) NSInteger uid; +///名称 +@property (nonatomic, copy) NSString *name; +///坐标位置 +@property (nonatomic, copy) AMapGeoPoint *location; +///地址 +@property (nonatomic, copy) NSString *address; +///用户自定义字段 +@property (nonatomic, strong) NSDictionary *customFields; +///创建时间 +@property (nonatomic, copy) NSString *createTime; +///更新时间 +@property (nonatomic, copy) NSString *updateTime; +///离当前位置的距离(只在企业地图周边搜索时有效) +@property (nonatomic, assign) NSInteger distance; +///图片信息 +@property (nonatomic, strong) NSArray *images __attribute((deprecated("已废弃 since 7.4.0"))); + +@end diff --git a/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapNearbySearchManager.h b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapNearbySearchManager.h new file mode 100644 index 0000000..1d725f0 --- /dev/null +++ b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapNearbySearchManager.h @@ -0,0 +1,85 @@ +// +// AMapNearbySearchManager.h +// AMapSearchKit +// +// Created by xiaoming han on 15/8/31. +// Copyright (c) 2015年 Amap. All rights reserved. +// + +#import +#import "AMapNearbyUploadInfo.h" + +@class AMapNearbySearchManager; + +///附近搜索代理 +@protocol AMapNearbySearchManagerDelegate +@optional + +/** + * @brief 开启自动上传,需实现该回调。 + */ +- (AMapNearbyUploadInfo *)nearbyInfoForUploading:(AMapNearbySearchManager *)manager; + +/** + * @brief 用户信息上传完毕回调。 + * @param error 错误,为空时表示成功。 + */ +- (void)onNearbyInfoUploadedWithError:(NSError *)error; + +/** + * @brief 用户信息清除完毕回调。 + * @param error 错误,为空时表示成功。 + */ +- (void)onUserInfoClearedWithError:(NSError *)error; + +@end + +///附近搜索管理类,同时只能有一个实例开启,否则可能会出现错误。 +@interface AMapNearbySearchManager : NSObject + +///上传最小间隔,默认15s,最小7s。自动上传的过程中设置无效。 +@property (nonatomic, assign) NSTimeInterval uploadTimeInterval; + +///代理对象。 +@property (nonatomic, weak) id delegate; + +///是否正在自动上传状态中。 +@property (nonatomic, readonly) BOOL isAutoUploading; + +/** + * @brief manager单例. + * 初始化之前请设置key,否则将无法正常使用该服务. + * @return nearbySearch实例。 + */ ++ (instancetype)sharedInstance; + +/** + * @brief 请使用单例。 + */ +- (instancetype)init __attribute__((unavailable)); + +/** + * @brief 启动自动上传。 + */ +- (void)startAutoUploadNearbyInfo; + +/** + * @brief 关闭自动上传。 + */ +- (void)stopAutoUploadNearbyInfo; + +/** + * @brief 执行单次上传,执行间隔不低于uploadTimeInterval最小值,否则执行失败。 + * @param info 需要上传的信息。 + * @return 成功执行返回YES,否则返回NO。 + */ +- (BOOL)uploadNearbyInfo:(AMapNearbyUploadInfo *)info __attribute((deprecated("已废弃 since 7.4.0,该功能不再支持"))); + +/** + * @brief 清除服务器上某一用户的信息。 + * @param userID 指定的用户ID + * @return 成功执行返回YES,否则返回NO。 + */ +- (BOOL)clearUserInfoWithID:(NSString *)userID __attribute((deprecated("已废弃 since 7.4.0,该功能不再支持"))); + +@end diff --git a/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapNearbyUploadInfo.h b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapNearbyUploadInfo.h new file mode 100644 index 0000000..d8d316b --- /dev/null +++ b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapNearbyUploadInfo.h @@ -0,0 +1,32 @@ +// +// AMapNearbyUploadInfo.h +// AMapSearchKit +// +// Created by xiaoming han on 15/9/6. +// Copyright (c) 2015年 Amap. All rights reserved. +// + +#import +#import + +///上传经纬度类型 +typedef NS_ENUM(NSInteger, AMapSearchCoordinateType) +{ + AMapSearchCoordinateTypeGPS = 1, ///< 标准GPS坐标 + AMapSearchCoordinateTypeAMap = 2, ///< 高德坐标 +}; + + +///附近搜索上传信息 +@interface AMapNearbyUploadInfo : NSObject + +///用户唯一标识,不能为空,否则上传会失败. 长度不超过32字符,只能包含英文、数字、下划线、短横杠 +@property (nonatomic, copy) NSString *userID; + +///坐标类型,默认是 AMapSearchCoordinateTypeAMap +@property (nonatomic, assign) AMapSearchCoordinateType coordinateType; + +///用户位置经纬度。 +@property (nonatomic, assign) CLLocationCoordinate2D coordinate; + +@end diff --git a/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchAPI.h b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchAPI.h new file mode 100644 index 0000000..4e3ee10 --- /dev/null +++ b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchAPI.h @@ -0,0 +1,370 @@ +// +// AMapSearchAPI.h +// AMapSearchKit +// +// Created by xiaoming han on 15/7/22. +// Copyright (c) 2015年 Amap. All rights reserved. +// + +#import +#import "AMapSearchObj.h" +#import "AMapCommonObj.h" + +@protocol AMapSearchDelegate; + +///搜索结果语言 +#define AMapSearchLanguageZhCN @"zh" ///< 中文 +#define AMapSearchLanguageEn @"en" ///< 英文 + +///搜索类 +@interface AMapSearchAPI : NSObject + +///实现了 AMapSearchDelegate 协议的类指针。 +@property (nonatomic, weak) id delegate; + +///查询超时时间,单位秒,默认为20秒。 +@property (nonatomic, assign) NSInteger timeout; + +///查询结果返回语言, 默认为中文。 +@property (nonatomic, copy) NSString *language; + +/** + * @brief AMapSearch的初始化函数。 + * 初始化之前请正确设置key,否则将无法正常使用搜索服务. + * @return AMapSearch类对象实例 + */ +- (instancetype)init; + +/** + * @brief 取消所有未回调的请求,触发错误回调。 + */ +- (void)cancelAllRequests; + +#pragma mark - 搜索服务接口 + +/** + * @brief POI ID查询接口 + * @param request 查询选项。具体属性字段请参考 AMapPOIIDSearchRequest 类。 + */ +- (void)AMapPOIIDSearch:(AMapPOIIDSearchRequest *)request; + +/** + * @brief POI 关键字查询接口 + * @param request 查询选项。具体属性字段请参考 AMapPOIKeywordsSearchRequest 类。 + */ +- (void)AMapPOIKeywordsSearch:(AMapPOIKeywordsSearchRequest *)request; + +/** + * @brief POI 周边查询接口 + * @param request 查询选项。具体属性字段请参考 AMapPOIAroundSearchRequest 类。 + */ +- (void)AMapPOIAroundSearch:(AMapPOIAroundSearchRequest *)request; + +/** + * @brief POI 多边形查询接口 + * @param request 查询选项。具体属性字段请参考 AMapPOIPolygonSearchRequest 类。 + */ +- (void)AMapPOIPolygonSearch:(AMapPOIPolygonSearchRequest *)request; + +/** + * @brief 沿途查询接口 (v4.3.0) + * @param request 查询选项。具体属性字段请参考 AMapRoutePOISearchRequest 类。 + */ +- (void)AMapRoutePOISearch:(AMapRoutePOISearchRequest *)request; + +/** + * @brief 地址编码查询接口 + * @param request 查询选项。具体属性字段请参考 AMapGeocodeSearchRequest 类。 + */ +- (void)AMapGeocodeSearch:(AMapGeocodeSearchRequest *)request; + +/** + * @brief 逆地址编码查询接口 + * @param request 查询选项。具体属性字段请参考 AMapReGeocodeSearchRequest 类。 + */ +- (void)AMapReGoecodeSearch:(AMapReGeocodeSearchRequest *)request; + +/** + * @brief 输入提示查询接口 + * @param request 查询选项。具体属性字段请参考 AMapInputTipsSearchRequest 类。 + */ +- (void)AMapInputTipsSearch:(AMapInputTipsSearchRequest *)request; + +/** + * @brief 公交站点查询接口 + * @param request 查询选项。具体属性字段请参考 AMapBusStopSearchRequest 类。 + */ +- (void)AMapBusStopSearch:(AMapBusStopSearchRequest *)request; + +/** + * @brief 公交线路关键字查询 + * @param request 查询选项。具体属性字段请参考 AMapBusLineIDSearchRequest 类。 + */ +- (void)AMapBusLineIDSearch:(AMapBusLineIDSearchRequest *)request; + +/** + * @brief 公交线路关键字查询 + * @param request 查询选项。具体属性字段请参考 AMapBusLineNameSearchRequest 类。 + */ +- (void)AMapBusLineNameSearch:(AMapBusLineNameSearchRequest *)request; + +/** + * @brief 行政区域查询接口 + * @param request 查询选项。具体属性字段请参考 AMapDistrictSearchRequest 类。 + */ +- (void)AMapDistrictSearch:(AMapDistrictSearchRequest *)request; + +/** + * @brief 驾车路径规划查询接口 + * @param request 查询选项。具体属性字段请参考 AMapDrivingRouteSearchRequest 类。 + */ +- (void)AMapDrivingRouteSearch:(AMapDrivingRouteSearchRequest *)request; + +/** + * @brief 步行路径规划查询接口 + * @param request 查询选项。具体属性字段请参考 AMapWalkingRouteSearchRequest 类。 + */ +- (void)AMapWalkingRouteSearch:(AMapWalkingRouteSearchRequest *)request; + +/** + * @brief 公交路径规划查询接口 + * @param request 查询选项。具体属性字段请参考 AMapTransitRouteSearchRequest 类。 + */ +- (void)AMapTransitRouteSearch:(AMapTransitRouteSearchRequest *)request; + +/** + * @brief 骑行路径规划查询接口 (since 4.3.0) + * @param request 查询选项。具体属性字段请参考 AMapRidingRouteSearchRequest 类。 + */ +- (void)AMapRidingRouteSearch:(AMapRidingRouteSearchRequest *)request; + +/** + * @brief 货车路径规划查询接口 (since 6.1.0) + * @param request 查询选项。具体属性字段请参考 AMapTruckRouteSearchRequest 类。 + */ +- (void)AMapTruckRouteSearch:(AMapTruckRouteSearchRequest *)request; + +/** + * @brief 未来路线规划查询接口 (since 6.9.0) + * @param request 查询选项。具体属性字段请参考 AMapTruckRouteSearchRequest 类。 + */ +- (void)AMapFutureRouteSearch:(AMapFutureRouteSearchRequest *)request; + +/** + * @brief 天气查询接口 + * @param request 查询选项。具体属性字段请参考 AMapWeatherSearchRequest 类。 + */ +- (void)AMapWeatherSearch:(AMapWeatherSearchRequest *)request; + +/** + * @brief 查询指定道路的实时路况 since 5.1.0 + * @param request 查询选项。具体属性字段请参考 AMapRoadTrafficSearchRequest 类。 + */ +- (void)AMapRoadTrafficSearch:(AMapRoadTrafficSearchRequest *)request; + +/** + * @brief 查询圆形区域内道路的实时路况 since 5.5.0 + * @param request 查询选项。具体属性字段请参考 AMapRoadTrafficSearchRequest 类。 + */ +- (void)AMapRoadTrafficCircleSearch:(AMapRoadTrafficCircleSearchRequest *)request; + +/** + * @brief 距离查询(since 6.1.0) + * @param request 查询选项。具体属性字段请参考 AMapDistanceSearchRequest 类。 + */ +- (void)AMapDistanceSearch:(AMapDistanceSearchRequest *)request; + +#pragma mark - 附近搜索相关 + +/** + * @brief 附近搜索查询接口 + * @param request 查询选项。具体属性字段请参考 AMapNearbySearchRequest 类。 + */ +- (void)AMapNearbySearch:(AMapNearbySearchRequest *)request __attribute__((deprecated("已废弃, from 7.4.0,该功能不再支持"))); + +#pragma mark - 企业地图搜索相关 + +/** + * @brief 企业地图周边查询接口 + * @param request 查询选项。具体属性字段请参考 AMapCloudPOIAroundSearchRequest 类。 + */ +- (void)AMapCloudPOIAroundSearch:(AMapCloudPOIAroundSearchRequest *)request; + +/** + * @brief 企业地图polygon区域查询接口 + * @param request 查询选项。具体属性字段请参考 AMapCloudPOIPolygonSearchRequest 类。 + */ +- (void)AMapCloudPOIPolygonSearch:(AMapCloudPOIPolygonSearchRequest *)request; + +/** + * @brief 企业地图ID查询接口 + * @param request 查询选项。具体属性字段请参考 AMapCloudPOIIDSearchRequest 类。 + */ +- (void)AMapCloudPOIIDSearch:(AMapCloudPOIIDSearchRequest *)request; + +/** + * @brief 企业地图本地查询接口 + * @param request 查询选项。具体属性字段请参考 AMapCloudPOILocalSearchRequest 类。 + */ +- (void)AMapCloudPOILocalSearch:(AMapCloudPOILocalSearchRequest *)request; + +#pragma mark - 短串分享相关 + +/** + * @brief 位置短串分享接口 + * @param request 查询选项。具体属性字段请参考 AMapLocationShareSearchRequest 类。 + */ +- (void)AMapLocationShareSearch:(AMapLocationShareSearchRequest *)request; + +/** + * @brief 兴趣点短串分享接口 + * @param request 查询选项。具体属性字段请参考 AMapPOIShareSearchRequest 类。 + */ +- (void)AMapPOIShareSearch:(AMapPOIShareSearchRequest *)request; + +/** + * @brief 路线规划短串分享接口 + * @param request 查询选项。具体属性字段请参考 AMapRouteShareSearchRequest 类。 + */ +- (void)AMapRouteShareSearch:(AMapRouteShareSearchRequest *)request; + +/** + * @brief 导航短串分享接口 + * @param request 查询选项。具体属性字段请参考 AMapNavigationShareSearchRequest 类。 + */ +- (void)AMapNavigationShareSearch:(AMapNavigationShareSearchRequest *)request; + +@end + +#pragma mark - AMapSearchDelegate + +///AMapSearchDelegate协议, 定义了搜索结果的回调方法,发生错误时的错误回调方法。 +@protocol AMapSearchDelegate +@optional + +/** + * @brief 当请求发生错误时,会调用代理的此方法. + * @param request 发生错误的请求. + * @param error 返回的错误. + */ +- (void)AMapSearchRequest:(id)request didFailWithError:(NSError *)error; + +/** + * @brief POI查询回调函数 + * @param request 发起的请求,具体字段参考 AMapPOISearchBaseRequest 及其子类。 + * @param response 响应结果,具体字段参考 AMapPOISearchResponse 。 + */ +- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response; + +/** + * @brief 沿途查询回调函数 (since v4.3.0) + * @param request 发起的请求,具体字段参考 AMapRoutePOISearchRequest 及其子类。 + * @param response 响应结果,具体字段参考 AMapRoutePOISearchResponse 。 + */ +- (void)onRoutePOISearchDone:(AMapRoutePOISearchRequest *)request response:(AMapRoutePOISearchResponse *)response; + +/** + * @brief 地理编码查询回调函数 + * @param request 发起的请求,具体字段参考 AMapGeocodeSearchRequest 。 + * @param response 响应结果,具体字段参考 AMapGeocodeSearchResponse 。 + */ +- (void)onGeocodeSearchDone:(AMapGeocodeSearchRequest *)request response:(AMapGeocodeSearchResponse *)response; + +/** + * @brief 逆地理编码查询回调函数 + * @param request 发起的请求,具体字段参考 AMapReGeocodeSearchRequest 。 + * @param response 响应结果,具体字段参考 AMapReGeocodeSearchResponse 。 + */ +- (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response; + +/** + * @brief 输入提示查询回调函数 + * @param request 发起的请求,具体字段参考 AMapInputTipsSearchRequest 。 + * @param response 响应结果,具体字段参考 AMapInputTipsSearchResponse 。 + */ +- (void)onInputTipsSearchDone:(AMapInputTipsSearchRequest *)request response:(AMapInputTipsSearchResponse *)response; + +/** + * @brief 公交站查询回调函数 + * @param request 发起的请求,具体字段参考 AMapBusStopSearchRequest 。 + * @param response 响应结果,具体字段参考 AMapBusStopSearchResponse 。 + */ +- (void)onBusStopSearchDone:(AMapBusStopSearchRequest *)request response:(AMapBusStopSearchResponse *)response; + +/** + * @brief 公交线路关键字查询回调 + * @param request 发起的请求,具体字段参考 AMapBusLineSearchRequest 。 + * @param response 响应结果,具体字段参考 AMapBusLineSearchResponse 。 + */ +- (void)onBusLineSearchDone:(AMapBusLineBaseSearchRequest *)request response:(AMapBusLineSearchResponse *)response; + +/** + * @brief 行政区域查询回调函数 + * @param request 发起的请求,具体字段参考 AMapDistrictSearchRequest 。 + * @param response 响应结果,具体字段参考 AMapDistrictSearchResponse 。 + */ +- (void)onDistrictSearchDone:(AMapDistrictSearchRequest *)request response:(AMapDistrictSearchResponse *)response; + +/** + * @brief 路径规划查询回调 + * @param request 发起的请求,具体字段参考 AMapRouteSearchBaseRequest 及其子类。 + * @param response 响应结果,具体字段参考 AMapRouteSearchResponse 。 + */ +- (void)onRouteSearchDone:(AMapRouteSearchBaseRequest *)request response:(AMapRouteSearchResponse *)response; + +/** + * @brief 未来路径规划查询回调 since 6.9.0 + * @param request 发起的请求,具体字段参考 AMapRouteSearchBaseRequest 及其子类。 + * @param response 响应结果,具体字段参考 AMapRouteSearchResponse 。 + */ +- (void)onFutureRouteSearchDone:(AMapRouteSearchBaseRequest *)request response:(AMapFutureRouteSearchResponse *)response; + +/** + * @brief 距离查询回调 + * @param request 发起的请求,具体字段参考 AMapDistanceSearchRequest 及其子类。 + * @param response 响应结果,具体字段参考 AMapDistanceSearchResponse 。 + */ +- (void)onDistanceSearchDone:(AMapDistanceSearchRequest *)request response:(AMapDistanceSearchResponse *)response; + +/** + * @brief 天气查询回调 + * @param request 发起的请求,具体字段参考 AMapWeatherSearchRequest 。 + * @param response 响应结果,具体字段参考 AMapWeatherSearchResponse 。 + */ +- (void)onWeatherSearchDone:(AMapWeatherSearchRequest *)request response:(AMapWeatherSearchResponse *)response; + + +/** + * @brief 道路路况查询回调 since 5.1.0 + * @param request 发起的请求,具体字段参考 AMapRoadTrafficSearchBaseRequest 及其子类 。 + * @param response 响应结果,具体字段参考 AMapRoadTrafficSearchResponse 。 + */ +- (void)onRoadTrafficSearchDone:(AMapRoadTrafficSearchBaseRequest *)request response:(AMapRoadTrafficSearchResponse *)response; +#pragma mark - 附近搜索回调 + +/** + * @brief 附近搜索回调 + * @param request 发起的请求,具体字段参考 AMapNearbySearchRequest 。 + * @param response 响应结果,具体字段参考 AMapNearbySearchResponse 。 + */ +- (void)onNearbySearchDone:(AMapNearbySearchRequest *)request response:(AMapNearbySearchResponse *)response; + +#pragma mark - 企业地图搜索回调 + +/** + * @brief 企业地图查询回调函数 + * @param request 发起的请求,具体字段参考 AMapCloudSearchBaseRequest 。 + * @param response 响应结果,具体字段参考 AMapCloudPOISearchResponse 。 + */ +- (void)onCloudSearchDone:(AMapCloudSearchBaseRequest *)request response:(AMapCloudPOISearchResponse *)response; + +#pragma mark - 短串分享搜索回调 + +/** + * @brief 短串分享搜索回调 + * @param request 发起的请求 + * @param response 相应结果,具体字段参考 AMapShareSearchResponse。 + */ +- (void)onShareSearchDone:(AMapShareSearchBaseRequest *)request response:(AMapShareSearchResponse *)response; + +@end diff --git a/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchError.h b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchError.h new file mode 100644 index 0000000..32d6fc8 --- /dev/null +++ b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchError.h @@ -0,0 +1,72 @@ +// +// AMapSearchError.h +// AMapSearchKit +// +// Created by xiaoming han on 15/7/29. +// Copyright (c) 2015年 Amap. All rights reserved. +// + +#ifndef AMapSearchKit_AMapSearchError_h +#define AMapSearchKit_AMapSearchError_h + +///AMapSearch errorDomain +extern NSString * const AMapSearchErrorDomain; + +///AMapSearch errorCode +typedef NS_ENUM(NSInteger, AMapSearchErrorCode) +{ + AMapSearchErrorOK = 1000,///< 没有错误 + AMapSearchErrorInvalidSignature = 1001,///< 无效签名 + AMapSearchErrorInvalidUserKey = 1002,///< key非法或过期 + AMapSearchErrorServiceNotAvailable = 1003,///< 没有权限使用相应的接口 + AMapSearchErrorDailyQueryOverLimit = 1004,///< 访问已超出日访问量 + AMapSearchErrorTooFrequently = 1005,///< 用户访问过于频繁 + AMapSearchErrorInvalidUserIP = 1006,///< 用户IP无效 + AMapSearchErrorInvalidUserDomain = 1007,///< 用户域名无效 + AMapSearchErrorInvalidUserSCode = 1008,///< 安全码验证错误,bundleID与key不对应 + AMapSearchErrorUserKeyNotMatch = 1009,///< 请求key与绑定平台不符 + AMapSearchErrorIPQueryOverLimit = 1010,///< IP请求超限 + AMapSearchErrorNotSupportHttps = 1011,///< 不支持HTTPS请求 + AMapSearchErrorInsufficientPrivileges = 1012,///< 权限不足,服务请求被拒绝 + AMapSearchErrorUserKeyRecycled = 1013,///< 开发者key被删除,无法正常使用 + + AMapSearchErrorInvalidResponse = 1100,///< 请求服务响应错误 + AMapSearchErrorInvalidEngineData = 1101,///< 引擎返回数据异常 + AMapSearchErrorConnectTimeout = 1102,///< 服务端请求链接超时 + AMapSearchErrorReturnTimeout = 1103,///< 读取服务结果超时 + AMapSearchErrorInvalidParams = 1200,///< 请求参数非法 + AMapSearchErrorMissingRequiredParams = 1201,///< 缺少必填参数 + AMapSearchErrorIllegalRequest = 1202,///< 请求协议非法 + AMapSearchErrorServiceUnknown = 1203,///< 其他服务端未知错误 + + AMapSearchErrorClientUnknown = 1800,///< 客户端未知错误,服务返回结果为空或其他错误 + AMapSearchErrorInvalidProtocol = 1801,///< 协议解析错误,通常是返回结果无法解析 + AMapSearchErrorTimeOut = 1802,///< 连接超时 + AMapSearchErrorBadURL = 1803,///< URL异常 + AMapSearchErrorCannotFindHost = 1804,///< 找不到主机 + AMapSearchErrorCannotConnectToHost = 1805,///< 服务器连接失败 + AMapSearchErrorNotConnectedToInternet = 1806,///< 连接异常,通常为没有网络的情况 + AMapSearchErrorCancelled = 1807,///< 连接取消 + + AMapSearchErrorOverPassPointCount = 1809,///< 途经点个数超限 + AMapSearchErrorOverPassAreaMaxCount = 1810,///< 避让区域个数超限 + AMapSearchErrorOverPassAreaMaxArea = 1811,///< 避让区域大小超限 + AMapSearchErrorOverPassAreaPointCount = 1812,///< 避让区域点个数超限 + + AMapSearchErrorTableIDNotExist = 2000,///< table id 格式不正确 + AMapSearchErrorIDNotExist = 2001,///< id 不存在 + AMapSearchErrorServiceMaintenance = 2002,///< 服务器维护中 + AMapSearchErrorEngineTableIDNotExist = 2003,///< key对应的table id 不存在 + AMapSearchErrorInvalidNearbyUserID = 2100,///< 找不到对应userID的信息 + AMapSearchErrorNearbyKeyNotBind = 2101,///< key未开通“附近”功能 + + AMapSearchErrorOutOfService = 3000,///< 规划点(包括起点、终点、途经点)不在中国范围内 + AMapSearchErrorNoRoadsNearby = 3001,///< 规划点(包括起点、终点、途经点)附近搜不到道路 + AMapSearchErrorRouteFailed = 3002,///< 路线计算失败,通常是由于道路连通关系导致 + AMapSearchErrorOverDirectionRange = 3003,///< 起点终点距离过长 + + AMapSearchErrorShareLicenseExpired = 4000,///< 短串分享认证失败 + AMapSearchErrorShareFailed = 4001,///< 短串请求失败 +}; + +#endif diff --git a/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchKit.h b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchKit.h new file mode 100644 index 0000000..ed46e5c --- /dev/null +++ b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchKit.h @@ -0,0 +1,16 @@ +// +// AMapSearchKit.h +// AMapSearchKit +// +// Created by xiaoming han on 15/7/22. +// Copyright (c) 2015年 Amap. All rights reserved. +// + +#import +#import +#import +#import +#import +#import + +#import diff --git a/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchObj.h b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchObj.h new file mode 100644 index 0000000..78b5e74 --- /dev/null +++ b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchObj.h @@ -0,0 +1,757 @@ +// +// AMapSearchObj.h +// AMapSearchKit +// +// Created by xiaoming han on 15/7/22. +// Copyright (c) 2015年 Amap. All rights reserved. +// + +/* 该文件定义了搜索请求和返回对象。*/ + +#import +#import "AMapCommonObj.h" + +///沿途搜索类型 +typedef NS_ENUM(NSInteger, AMapRoutePOISearchType) +{ + AMapRoutePOISearchTypeGasStation = 0, ///< 加油站 + AMapRoutePOISearchTypeMaintenanceStation = 1, ///< 维修站 + AMapRoutePOISearchTypeATM = 2, ///< ATM + AMapRoutePOISearchTypeToilet = 3, ///< 厕所 + AMapRoutePOISearchTypeGasAirStation = 4, ///< 加气站 + AMapRoutePOISearchTypeParkStation = 5, ///< 服务区 +}; + +///天气查询类型 +typedef NS_ENUM(NSInteger, AMapWeatherType) +{ + AMapWeatherTypeLive = 1, ///< 实时 + AMapWeatherTypeForecast ///< 预报 +}; + +///企业地图搜索结果排序 +typedef NS_ENUM(NSInteger, AMapCloudSortType) +{ + AMapCloudSortTypeDESC = 0, ///< 降序 + AMapCloudSortTypeASC = 1 ///< 升序 +}; + +///附近搜索距离类型 +typedef NS_ENUM(NSInteger, AMapNearbySearchType) +{ + AMapNearbySearchTypeLiner = 0, ///< 直线距离 + AMapNearbySearchTypeDriving = 1, ///< 驾车行驶距离 +}; + +///货车类型 +typedef NS_ENUM(NSInteger, AMapTruckSizeType) +{ + AMapTruckSizeTypeMini = 1, ///< 微型车 + AMapTruckSizeTypeLight = 2, ///< 轻型车 + AMapTruckSizeTypeMedium = 3, ///< 中型车 + AMapTruckSizeTypeHeavy = 4, ///< 重型车 +}; + +///规避道路类型 +typedef NS_ENUM(NSInteger, AMapDrivingRouteExcludeType) +{ + AMapDrivingRouteExcludeTypeNone = 0, ///< 不规避 + AMapDrivingRouteExcludeTypeToll = 1, ///< 收费道路 + AMapDrivingRouteExcludeTypeMotorway = 2, ///< 高速路 + AMapDrivingRouteExcludeTypeFerry = 3, ///< 渡船 +}; + +#pragma mark - AMapPOISearchBaseRequest + +///POI搜索请求基类 +@interface AMapPOISearchBaseRequest : AMapSearchObject +///类型,多个类型用“|”分割 可选值:文本分类、分类代码 +@property (nonatomic, copy) NSString *types; +///排序规则, 0-距离排序;1-综合排序, 默认0 +@property (nonatomic, assign) NSInteger sortrule; +///每页记录数, 范围1-50, [default = 20] +@property (nonatomic, assign) NSInteger offset; +///当前页数, 范围1-100, [default = 1] +@property (nonatomic, assign) NSInteger page; +///建筑物POI编号,传入建筑物POI之后,则只在该建筑物之内进行搜索(since 4.5.0) +@property (nonatomic, copy) NSString *building; +///是否返回扩展信息,默认为 NO。 +@property (nonatomic, assign) BOOL requireExtension; +///是否返回子POI,默认为 NO。 +@property (nonatomic, assign) BOOL requireSubPOIs; +@end + +///POI ID搜索请求 +@interface AMapPOIIDSearchRequest : AMapPOISearchBaseRequest +///POI全局唯一ID +@property (nonatomic, copy) NSString *uid; +@end + +///POI关键字搜索 +@interface AMapPOIKeywordsSearchRequest : AMapPOISearchBaseRequest +///查询关键字,多个关键字用“|”分割 +@property (nonatomic, copy) NSString *keywords; +///查询城市,可选值:cityname(中文或中文全拼)、citycode、adcode.(注:台湾省的城市一律设置为【台湾】,不具体到市。) +@property (nonatomic, copy) NSString *city; +///强制城市限制功能 默认NO,例如:在上海搜索天安门,如果citylimit为true,将不返回北京的天安门相关的POI +@property (nonatomic, assign) BOOL cityLimit; +///设置后,如果sortrule==0,则返回结果会按照距离此点的远近来排序,since 5.2.1 +@property (nonatomic, strong) AMapGeoPoint *location; + +@end + +///POI周边搜索 +@interface AMapPOIAroundSearchRequest : AMapPOISearchBaseRequest +///查询关键字,多个关键字用“|”分割 +@property (nonatomic, copy) NSString *keywords; +///中心点坐标 +@property (nonatomic, copy) AMapGeoPoint *location; +///查询半径,范围:0-50000,单位:米 [default = 3000] +@property (nonatomic, assign) NSInteger radius; +///查询城市,可选值:cityname(中文或中文全拼)、citycode、adcode。注:当用户指定的经纬度和city出现冲突,若范围内有用户指定city的数据,则返回相关数据,否则返回为空。(since 5.7.0) +@property (nonatomic, copy) NSString *city; +///是否对结果进行人工干预,如火车站,原因为poi较为特殊,结果存在人工干预,干预结果优先,所以距离优先的排序未生效,默认为YES (since 7.4.0) +@property (nonatomic, assign) BOOL special; + +@end + +///POI多边形搜索 +@interface AMapPOIPolygonSearchRequest : AMapPOISearchBaseRequest +///查询关键字,多个关键字用“|”分割 +@property (nonatomic, copy) NSString *keywords; +///多边形 +@property (nonatomic, copy) AMapGeoPolygon *polygon; +@end + +///POI搜索返回 +@interface AMapPOISearchResponse : AMapSearchObject +///返回的POI数目 +@property (nonatomic, assign) NSInteger count; +///关键字建议列表和城市建议列表 +@property (nonatomic, strong) AMapSuggestion *suggestion; +///POI结果,AMapPOI 数组 +@property (nonatomic, strong) NSArray *pois; +@end + +#pragma mark - AMapPOIRouteSearchRequest +///沿途搜索, 注意起点和终点不能相距太远(大概70公里),否则可能搜索结果为空 +@interface AMapRoutePOISearchRequest : AMapSearchObject +///中心点坐标 +@property (nonatomic, copy) AMapGeoPoint *origin; +///目标点坐标 +@property (nonatomic, copy) AMapGeoPoint *destination; +///搜索类型 +@property (nonatomic, assign) AMapRoutePOISearchType searchType; +///驾车导航策略,同驾车路径规划请求的策略(5 多策略除外) +@property (nonatomic, assign) NSInteger strategy; +///道路周围搜索范围,单位米,[0-500],默认250。 +@property (nonatomic, assign) NSInteger range; +///用户自己规划的路线,在origine、destination未填入时为必填.格式为:"经度,维度;经度,维度;...". 目前限制个数最多为100个点 +@property (nonatomic, strong) NSString *polylineStr; +///用户自己规划的路线,在origine、destination未填入且polylineStr未填入时为必填. 目前限制个数最多为100个点 +@property (nonatomic, strong) NSArray *polyline; + +@end + +///沿途搜索返回 +@interface AMapRoutePOISearchResponse : AMapSearchObject +///返回的POI数目 +@property (nonatomic, assign) NSInteger count; +///POI结果,AMapRoutePOI 数组 +@property (nonatomic, strong) NSArray *pois; +@end + +#pragma mark - AMapInputTipsSearchRequest + +///搜索提示请求 +@interface AMapInputTipsSearchRequest : AMapSearchObject +///查询关键字 +@property (nonatomic, copy) NSString *keywords; +///查询城市,可选值:cityname(中文或中文全拼)、citycode、adcode. +@property (nonatomic, copy) NSString *city; +///类型,多个类型用“|”分割 可选值:文本分类、分类代码 +@property (nonatomic, copy) NSString *types; +///强制城市限制功能,例如:在上海搜索天安门,如果citylimit为true,将不返回北京的天安门相关的POI +@property (nonatomic, assign) BOOL cityLimit; +///格式形如:@"116.481488,39.990464",(经度,纬度),不可以包含空格。如果设置,在此location附近优先返回搜索关键词信息, since 5.0.0 +@property (nonatomic, copy) NSString *location; +@end + +///搜索提示返回 +@interface AMapInputTipsSearchResponse : AMapSearchObject +///返回数目 +@property (nonatomic, assign) NSInteger count; +///提示列表 AMapTip 数组, AMapTip 有多种属性,可根据该对象的返回信息,配合其他搜索服务使用,完善您应用的功能。如:\n 1)uid为空,location为空,该提示语为品牌词,可根据该品牌词进行POI关键词搜索。\n 2)uid不为空,location为空,为公交线路,根据uid进行公交线路查询。\n 3)uid不为空,location也不为空,是一个真实存在的POI,可直接显示在地图上。 +@property (nonatomic, strong) NSArray *tips; +@end + +#pragma mark - AMapGeocodeSearchRequest + +///地理编码请求 +@interface AMapGeocodeSearchRequest : AMapSearchObject +///地址 +@property (nonatomic, copy) NSString *address; +///查询城市,可选值:cityname(中文或中文全拼)、citycode、adcode. +@property (nonatomic, copy) NSString *city; +///指定查询国家,支持多个国家,用“|”分隔,可选值:国家代码ISO 3166 或 global,仅海外生效(since 7.4.0) +@property (nonatomic, copy) NSString *country; +@end + +///地理编码返回 +@interface AMapGeocodeSearchResponse : AMapSearchObject +///返回数目 +@property (nonatomic, assign) NSInteger count; +///地理编码结果 AMapGeocode 数组 +@property (nonatomic, strong) NSArray *geocodes; +@end + + +#pragma mark - AMapReGeocodeSearchRequest + +///逆地理编码请求 +@interface AMapReGeocodeSearchRequest : AMapSearchObject +///是否返回扩展信息,默认NO。 +@property (nonatomic, assign) BOOL requireExtension; +///中心点坐标。 +@property (nonatomic, copy) AMapGeoPoint *location; +///查询半径,单位米,范围0~3000,默认1000。 +@property (nonatomic, assign) NSInteger radius; +///指定返回结果poi数组中的POI类型,在requireExtension=YES时生效。输入为typecode, 支持传入多个typecode, 多值时用“|”分割 +@property (nonatomic, copy) NSString *poitype; +///distance 按距离返回,score 按权重返回,仅海外生效(since 7.4.0) +@property (nonatomic, copy) NSString *mode; + +@end + +///逆地理编码返回 +@interface AMapReGeocodeSearchResponse : AMapSearchObject +///逆地理编码结果 +@property (nonatomic, strong) AMapReGeocode *regeocode; +@end + +#pragma mark - AMapBusStopSearchRequest + +///公交站点请求 +@interface AMapBusStopSearchRequest : AMapSearchObject +///查询关键字 +@property (nonatomic, copy) NSString *keywords; +///城市 可选值:cityname(中文或中文全拼)、citycode、adcode +@property (nonatomic, copy) NSString *city; +///每页记录数,默认为20,取值为:1-50 +@property (nonatomic, assign) NSInteger offset; +///当前页数,默认值为1,取值为:1-100 +@property (nonatomic, assign) NSInteger page; +@end + +///公交站点返回 +@interface AMapBusStopSearchResponse : AMapSearchObject +///公交站数目 +@property (nonatomic, assign) NSInteger count; +///关键字建议列表和城市建议列表 +@property (nonatomic, strong) AMapSuggestion *suggestion; +///公交站点数组,数组中存放AMapBusStop对象 +@property (nonatomic, strong) NSArray *busstops; +@end + +#pragma mark - AMapBusLineSearchRequest + +///公交线路查询请求基类,不可直接调用 +@interface AMapBusLineBaseSearchRequest : AMapSearchObject +///城市 可选值:cityname(中文或中文全拼)、citycode、adcode +@property (nonatomic, copy) NSString *city; +///是否返回扩展信息,默认为NO +@property (nonatomic, assign) BOOL requireExtension; +///每页记录数,默认为20,取值为1-50 +@property (nonatomic, assign) NSInteger offset; +///当前页数,默认为1,取值为1-100 +@property (nonatomic, assign) NSInteger page; +@end + +///公交站线路根据名字请求 +@interface AMapBusLineNameSearchRequest : AMapBusLineBaseSearchRequest +///查询关键字 +@property (nonatomic, copy) NSString *keywords; +@end + +///公交站线路根据ID请求 +@interface AMapBusLineIDSearchRequest : AMapBusLineBaseSearchRequest +///唯一标识 +@property (nonatomic, copy) NSString *uid; +@end + +///公交站线路返回 +@interface AMapBusLineSearchResponse : AMapSearchObject +///返回公交站数目 +@property (nonatomic, assign) NSInteger count; +///关键字建议列表和城市建议列表 +@property (nonatomic, strong) AMapSuggestion *suggestion; +///公交线路数组,数组中存放 AMapBusLine 对象 +@property (nonatomic, strong) NSArray *buslines; +@end + +#pragma mark - AMapDistrictSearchRequest +///行政区划查询请求 +@interface AMapDistrictSearchRequest : AMapSearchObject +///查询关键字,只支持单关键字搜索,全国范围 +@property (nonatomic, copy) NSString *keywords; +///是否返回边界坐标,默认NO +@property (nonatomic, assign) BOOL requireExtension; +///是否显示商圈信息,默认NO。注:已废弃,行政区划搜索无商圈信息。 +@property (nonatomic, assign) BOOL showBusinessArea __attribute__((deprecated("已废弃, from 5.3.0")));; +///每页记录数, 范围1-50, [default = 20] +@property (nonatomic, assign) NSInteger offset; +///当前页数, 范围1-100, [default = 1] +@property (nonatomic, assign) NSInteger page; +///子区域层级,默认1。规则:设置显示下级行政区级数(行政区级别包括:国家、省/直辖市、市、区/县、乡镇/街道多级数据)可选值:0、1、2、3等数字,0-不返回下级行政区;1-返回下一级行政区;2-返回下两级行政区;3-返回下三级行政区 +@property (nonatomic, assign) NSInteger subdistrict; + +@end + +///行政区划响应 +@interface AMapDistrictSearchResponse : AMapSearchObject +///返回数目 +@property (nonatomic, assign) NSInteger count; +///行政区域 AMapDistrict 数组 +@property (nonatomic, strong) NSArray *districts; +@end + +#pragma mark - AMapRouteSearchBaseRequest + +///路径规划基础类,不可直接调用 +@interface AMapRouteSearchBaseRequest : AMapSearchObject +///出发点 +@property (nonatomic, copy) AMapGeoPoint *origin; +///目的地 +@property (nonatomic, copy) AMapGeoPoint *destination; +@end + +#pragma mark - AMapDrivingRouteSearchRequest + +///驾车路径规划 +@interface AMapDrivingRouteSearchRequest : AMapRouteSearchBaseRequest + +/** + 驾车导航策略,默认策略为0。 + 0,速度优先(时间);1,费用优先(不走收费路段的最快道路);2,距离优先;3,不走快速路;4,躲避拥堵; + 5,多策略(同时使用速度优先、费用优先、距离优先三个策略计算路径),其中必须说明,就算使用三个策略算路,会根据路况不固定的返回一至三条路径规划信息; + 6,不走高速;7,不走高速且避免收费;8,躲避收费和拥堵;9,不走高速且躲避收费和拥堵; + 10,多备选,时间最短,距离最短,躲避拥堵(考虑路况); + 11,多备选,时间最短,距离最短; + 12,多备选,躲避拥堵(考虑路况); + 13,多备选,不走高速; + 14,多备选,费用优先; + 15,多备选,躲避拥堵,不走高速(考虑路况); + 16,多备选,费用有限,不走高速; + 17,多备选,躲避拥堵,费用优先(考虑路况); + 18,多备选,躲避拥堵,不走高速,费用优先(考虑路况); + 19,多备选,高速优先; + 20,多备选,高速优先,躲避拥堵(考虑路况) + */ +@property (nonatomic, assign) NSInteger strategy; +///途经点 AMapGeoPoint 数组,最多支持16个途经点 +@property (nonatomic, copy) NSArray *waypoints; +///避让区域 AMapGeoPolygon 数组,最多支持100个避让区域,每个区域16个点 +@property (nonatomic, copy) NSArray *avoidpolygons; +///避让道路名 +@property (nonatomic, copy) NSString *avoidroad; +///出发点 POI ID +@property (nonatomic, copy) NSString *originId; +///目的地 POI ID +@property (nonatomic, copy) NSString *destinationId; +///出发点POI类型编码 +@property (nonatomic, copy) NSString *origintype; +///目的地POI类型编码 +@property (nonatomic, copy) NSString *destinationtype; +///是否返回扩展信息,默认为 NO +@property (nonatomic, assign) BOOL requireExtension; +///车牌省份,用汉字填入车牌省份缩写。用于判断是否限行 +@property (nonatomic, copy) NSString *plateProvince; +///车牌详情,填入除省份及标点之外的字母和数字(需大写)。用于判断是否限行。 +@property (nonatomic, copy) NSString *plateNumber; +///使用轮渡,0使用1不使用,默认为0使用 +@property (nonatomic, assign) NSInteger ferry; +/** + 驾车路径规划车辆类型,默认策略为0。 + 0:普通汽车(默认值); + 1:纯电动车; + 2:插电混动车 + */ +@property (nonatomic, assign) NSInteger cartype; +///规避道路类型,默认为AMapDrivingRouteExcludeTypeNone,仅海外生效 +@property (nonatomic, assign) AMapDrivingRouteExcludeType exclude; + +@end + +#pragma mark - AMapWalkingRouteSearchRequest + +///步行路径规划 +@interface AMapWalkingRouteSearchRequest : AMapRouteSearchBaseRequest +///是否提供备选步行方案([default = 0])0-只提供一条步行方案; 1-提供备选步行方案(有可能无备选方案) +@property (nonatomic, assign) NSInteger multipath __attribute__((deprecated("已废弃, from 5.0.0"))); +@end + +#pragma mark - AMapTransitRouteSearchRequest + +///公交路径规划 +@interface AMapTransitRouteSearchRequest : AMapRouteSearchBaseRequest +///公交换乘策略([default = 0])\n 0-最快捷模式;\n 1-最经济模式;\n 2-最少换乘模式;\n 3-最少步行模式;\n 4-最舒适模式;\n 5-不乘地铁模式 +@property (nonatomic, assign) NSInteger strategy; +///城市, 必填 +@property (nonatomic, copy) NSString *city; +///目的城市, 跨城时需要填写,否则会出错 +@property (nonatomic, copy) NSString *destinationCity; +///是否包含夜班车,默认为 NO +@property (nonatomic, assign) BOOL nightflag; +///是否返回扩展信息,默认为 NO +@property (nonatomic, assign) BOOL requireExtension; +@end + +#pragma mark - AMapRidingRouteSearchRequest + +///骑行路径规划 +@interface AMapRidingRouteSearchRequest : AMapRouteSearchBaseRequest +///路径方案类型([default = 0])\n 0-推荐路线及最快路线综合\n 1-推荐路线\n 2-最快路线 +@property (nonatomic, assign) NSInteger type __attribute__((deprecated("已废弃, from 5.0.0"))); +///是否返回扩展信息,默认为 NO (since 7.6.0) +@property (nonatomic, assign) BOOL requireExtension; +@end + +///路径规划返回 +@interface AMapRouteSearchResponse : AMapSearchObject +///路径规划信息数目 +@property (nonatomic, assign) NSInteger count; +///路径规划信息 +@property (nonatomic, strong) AMapRoute *route; +@end + +///骑行路径规划返回 +@interface AMapRidingRouteSearchResponse : AMapRouteSearchResponse +@end + +#pragma mark - AMapTruckRouteSearchRequest + +///货车路径规划(since 6.1.0) +@interface AMapTruckRouteSearchRequest : AMapRouteSearchBaseRequest + +/** + 驾车导航策略,默认为策略1。 + 1,返回的结果考虑路况,尽量躲避拥堵而规划路径,与高德地图的“躲避拥堵”策略一致; + 2,返回的结果不走高速,与高德地图“不走高速”策略一致; + 3,返回的结果尽可能规划收费较低甚至免费的路径,与高德地图“避免收费”策略一致; + 4,返回的结果考虑路况,尽量躲避拥堵而规划路径,并且不走高速,与高德地图的“躲避拥堵&不走高速”策略一致; + 5,返回的结果尽量不走高速,并且尽量规划收费较低甚至免费的路径结果,与高德地图的“避免收费&不走高速”策略一致; + 6,返回路径规划结果会尽量的躲避拥堵,并且规划收费较低甚至免费的路径结果,与高德地图的“躲避拥堵&避免收费”策略一致; + 7,返回的结果尽量躲避拥堵,规划收费较低甚至免费的路径结果,并且尽量不走高速路,与高德地图的“避免拥堵&避免收费&不走高速”策略一致; + 8,返回的结果会优先选择高速路,与高德地图的“高速优先”策略一致; + 9,返回的结果会优先考虑高速路,并且会考虑路况躲避拥堵,与高德地图的“躲避拥堵&高速优先”策略一致。 + */ +@property (nonatomic, assign) NSInteger strategy; +///途经点 AMapGeoPoint 数组,最多支持16个途经点 +@property (nonatomic, copy) NSArray *waypoints; +///出发点 POI ID +@property (nonatomic, copy) NSString *originId; +///目的地 POI ID +@property (nonatomic, copy) NSString *destinationId; +///出发点POI类型编码 +@property (nonatomic, copy) NSString *origintype; +///目的地POI类型编码 +@property (nonatomic, copy) NSString *destinationtype; +///车牌省份,用汉字填入车牌省份缩写。用于判断是否限行 +@property (nonatomic, copy) NSString *plateProvince; +///车牌详情,填入除省份及标点之外的字母和数字(需大写)。用于判断是否限行。 +@property (nonatomic, copy) NSString *plateNumber; +///货车大小,默认为 轻型车(AMapTruckSizeTypeLight) +@property (nonatomic, assign) AMapTruckSizeType size; +///车辆高度,单位米,取值[0 – 25.5]米,默认 1.6 米 +@property (nonatomic, assign) CGFloat height; +///车辆宽度,单位米,取值[0 – 25.5]米,默认 2.5 米 +@property (nonatomic, assign) CGFloat width; +///车辆总重,单位吨,取值[0 – 6553.5]吨,默认 0.9 吨 +@property (nonatomic, assign) CGFloat load; +///货车核定载重,单位吨,取值[0 – 6553.5]吨,默认 10 吨 +@property (nonatomic, assign) CGFloat weight; +///车辆轴数,单位个,取值[0 –255]个,默认 2个轴 +@property (nonatomic, assign) NSInteger axis; +///是否返回扩展信息,默认为 NO (since 7.6.0) +@property (nonatomic, assign) BOOL requireExtension; +@end + +#pragma mark - AMapDistanceSearchRequest + +///距离查询请求(since 6.1.0) +@interface AMapDistanceSearchRequest : AMapSearchObject +///起点坐标数组,最多支持100个点。 +@property (nonatomic, strong) NSArray *origins; +///终点坐标 +@property (nonatomic, strong) AMapGeoPoint *destination; +///路径计算的方式和方法.0:直线距离; 1:驾车导航距离(仅支持国内坐标)此时会考虑路况,故在不同时间请求返回结果可能不同,此策略和driving接口的 strategy=4策略一致; 默认为1 +@property (nonatomic, assign) NSInteger type; +///是否返回扩展信息,默认为 NO (since 7.6.0) +@property (nonatomic, assign) BOOL requireExtension; +@end + +///距离查询结果(since 6.1.0) +@interface AMapDistanceSearchResponse : AMapSearchObject +///距离查询结果 AMapDistanceResult 数组。 +@property (nonatomic, strong) NSArray *results; + +@end + +#pragma mark - AMapWeatherSearchRequest + +///天气查询请求 +@interface AMapWeatherSearchRequest : AMapSearchObject +///城市名称,支持cityname及adcode +@property (nonatomic, copy) NSString *city; +///气象类型,Live为实时天气,Forecast为后三天预报天气,默认为Live +@property (nonatomic, assign) AMapWeatherType type; +@end + +///天气查询返回 +@interface AMapWeatherSearchResponse : AMapSearchObject +///实时天气数据信息 AMapLocalWeatherLive 数组,仅在请求实时天气时有返回。 +@property (nonatomic, strong) NSArray *lives; +///预报天气数据信息 AMapLocalWeatherForecast 数组,仅在请求预报天气时有返回 +@property (nonatomic, strong) NSArray *forecasts; + +@end + +#pragma mark - AMapRoadTrafficSearchRequest + +@interface AMapRoadTrafficSearchBaseRequest : AMapSearchObject + +///道路等级,1:高速(京藏高速)2:城市快速路、国道(西三环、103国道) 3:高速辅路(G6辅路)4:主要道路(长安街、三环辅路路)5:一般道路(彩和坊路)6:无名道路。默认为5. since 5.5.0 +@property (nonatomic, assign) NSInteger level; + +///是否返回扩展信息,默认为 NO +@property (nonatomic, assign) BOOL requireExtension; + +@end + +///道路实时路况查询请求 since 5.1.0 +@interface AMapRoadTrafficSearchRequest : AMapRoadTrafficSearchBaseRequest + +///道路名称,可通过逆地理编码查询获取 +@property (nonatomic, copy) NSString *roadName; + +///城市adcode,可参考 http://a.amap.com/lbs/static/zip/AMap_adcode_citycode.zip +@property (nonatomic, copy) NSString *adcode; + +@end + +///圆形区域道路实时路况查询请求 since 5.5.0 注意:返回路况结果取决于发起请求时刻的实时路况,不保证范围内的所有路线路况都会返回,也不保证返回的路况长度一定在限制半径内 +@interface AMapRoadTrafficCircleSearchRequest : AMapRoadTrafficSearchBaseRequest + +///必填,中心点坐标。 +@property (nonatomic, copy) AMapGeoPoint *location; +///查询半径,单位:米。[0, 5000], 默认值为1000. +@property (nonatomic, assign) NSInteger radius; + +@end + +///道路实时路况查询返回 since 5.1.0 +@interface AMapRoadTrafficSearchResponse : AMapSearchObject +///路况信息 +@property (nonatomic, strong) AMapTrafficInfo *trafficInfo; + +@end + +#pragma mark - AMapNearbySearchRequest +///附近搜索请求 +@interface AMapNearbySearchRequest : AMapSearchObject +///中心点坐标 +@property (nonatomic, copy) AMapGeoPoint *center; +///查询半径,范围:[0, 10000],单位:米 [default = 1000] +@property (nonatomic, assign) NSInteger radius; +///搜索距离类型,默认为直线距离 +@property (nonatomic, assign) AMapNearbySearchType searchType; +///检索时间范围,超过24小时的数据无法返回,范围[5, 24*60*60] 单位:秒 [default = 1800] +@property (nonatomic, assign) NSInteger timeRange; +///返回条数,范围[1, 100], 默认30 +@property (nonatomic, assign) NSInteger limit; +@end + +///附近搜索返回 +@interface AMapNearbySearchResponse : AMapSearchObject +///结果总条数 +@property (nonatomic, assign) NSInteger count; +///周边用户信息 AMapNearbyUserInfo 数组 +@property (nonatomic, strong) NSArray *infos; +@end + +#pragma mark - AMapCloudSearchBaseRequest + +///企业地图搜索请求基类 +@interface AMapCloudSearchBaseRequest : AMapSearchObject +///要查询的表格ID, 必选 +@property (nonatomic, copy) NSString *tableID; +///筛选条件数组, 可选, 说明:\n 1.支持建立索引的字段根据多个条件筛选,多个条件用双&符号连接;\n 2.判断符合支持:>= 大于等于,<= 小于等于,>大于,<小于,= 精确匹配(text索引不可用);\n 3.示例规则:key1=value1&&key2=value2&&lastloctime>=1469817532,示例:"name=王师傅|张师傅&&lastloctime>=1469817532 +@property (nonatomic, strong) NSArray *filter; +///排序字段名, 可选.\n 说明:\n 1.支持按建立了排序筛选索引的整数或小数字段进行排序:sortFields = "字段名";\n 2.系统预设的字段(忽略sortType):_distance:坐标与中心点距离升序排序,仅在周边检索时有效(若其它请求使用会异常返回);_weight:权重降序排序,当存在keywords时有效;\n; +@property (nonatomic, copy) NSString *sortFields; +///可选, 排序方式(默认升序) +@property (nonatomic, assign) AMapCloudSortType sortType; +///可选, 每页记录数(每页最大记录数100, 默认20) +@property (nonatomic, assign) NSInteger offset; +///可选, 当前页数(>=1, 默认1) +@property (nonatomic, assign) NSInteger page; +@end + +#pragma mark - AMapCloudPlaceAroundSearchRequest + +///企业地图周边搜请求 +@interface AMapCloudPOIAroundSearchRequest : AMapCloudSearchBaseRequest +///必填,中心点坐标。 +@property (nonatomic, copy) AMapGeoPoint *center; +///可选,查询半径(默认值为3000),单位:米 +@property (nonatomic, assign) NSInteger radius; +///可选,搜索关键词。\n 说明:1. 只支持建立过文本索引的字段查询/n 2.支持关键字模糊检索,即对建立【文本索引字段】对应列内容进行模糊检索;如keywords=工商银行,检索返回已建立文本索引列值中包含“工商”或者“银行”或者“工商银行”关键字的POI结果集。/n 3.支持关键字多值模糊检索;如keywords=招商银行&&华夏银行&&工商银行,检索返回已建立索引列值中包含“招商银行”或者“华夏银行”或者“工商银行”的POI结果集,不会返回检索词切分后,如仅包含“招商”或者“银行”的POI集 +@property (nonatomic, copy) NSString *keywords; +@end + +///企业地图polygon区域查询请求 +@interface AMapCloudPOIPolygonSearchRequest : AMapCloudSearchBaseRequest +///必填,多边形。 +@property (nonatomic, copy) AMapGeoPolygon *polygon; +///可选,搜索关键词。\n 说明:1. 只支持建立过文本索引的字段查询/n 2.支持关键字模糊检索,即对建立【文本索引字段】对应列内容进行模糊检索;如keywords=工商银行,检索返回已建立文本索引列值中包含“工商”或者“银行”或者“工商银行”关键字的POI结果集。/n 3.支持关键字多值模糊检索;如keywords=招商银行&&华夏银行&&工商银行,检索返回已建立索引列值中包含“招商银行”或者“华夏银行”或者“工商银行”的POI结果集,不会返回检索词切分后,如仅包含“招商”或者“银行”的POI集 +@property (nonatomic, copy) NSString *keywords; +@end + +///企业地图ID查询请求 +@interface AMapCloudPOIIDSearchRequest : AMapCloudSearchBaseRequest +///必填,POI的ID +@property (nonatomic, assign) NSInteger uid; +@end + +///企业地图本地查询请求 +@interface AMapCloudPOILocalSearchRequest : AMapCloudSearchBaseRequest +///可选,搜索关键词。\n 说明:1. 只支持建立过文本索引的字段查询/n 2.支持关键字模糊检索,即对建立【文本索引字段】对应列内容进行模糊检索;如keywords=工商银行,检索返回已建立文本索引列值中包含“工商”或者“银行”或者“工商银行”关键字的POI结果集。/n 3.支持关键字多值模糊检索;如keywords=招商银行&&华夏银行&&工商银行,检索返回已建立索引列值中包含“招商银行”或者“华夏银行”或者“工商银行”的POI结果集,不会返回检索词切分后,如仅包含“招商”或者“银行”的POI集 +@property (nonatomic, copy) NSString *keywords; +///必填,城市名称\n 说明:\n 1. 支持全国/省/市/区县行政区划范围的检索;\n 2. city = "全国",即对用户全表搜索;\n 3. 当city值设置非法或不正确时,按照 city = "全国"返回。 +@property (nonatomic, copy) NSString *city; +@end + +///企业地图搜索返回 +@interface AMapCloudPOISearchResponse : AMapSearchObject +///返回结果总数目 +@property (nonatomic, assign) NSInteger count; +///返回的结果, AMapCloudPOI 数组 +@property (nonatomic, strong) NSArray *POIs; + +@end + +#pragma mark - AMapShareSearchBaseRequest + +///短串分享搜索请求基类, 请使用具体的子类。 +@interface AMapShareSearchBaseRequest : AMapSearchObject +@end + +///位置短串分享请求 +@interface AMapLocationShareSearchRequest : AMapShareSearchBaseRequest +///必填, 位置坐标 +@property (nonatomic, copy) AMapGeoPoint *location; +///位置名称,请不要包含【,%&@#】等特殊符号 +@property (nonatomic, copy) NSString *name; +@end + +///兴趣点短串分享请求 +@interface AMapPOIShareSearchRequest : AMapShareSearchBaseRequest +///POI的ID,如果有ID则指定POI,否则按name查询。 +@property (nonatomic, copy) NSString *uid; +///坐标 +@property (nonatomic, copy) AMapGeoPoint *location; +///名称,请不要包含【,%&@#】等特殊符号。 +@property (nonatomic, copy) NSString *name; +///地址,请不要包含【,%&@#】等特殊符号。 +@property (nonatomic, copy) NSString *address; +@end + +///路径规划短串分享请求 +@interface AMapRouteShareSearchRequest : AMapShareSearchBaseRequest +///默认为0\n 驾车:0-速度最快(时间);\n 1-避免收费(不走收费路段的最快道路);\n 2-距离优先;\n 3-不走高速;\n 4-结合实时交通(躲避拥堵);\n 5-不走高速且避免收费;\n 6-不走高速且躲避拥堵;\n 7-躲避收费和拥堵;\n 8-不走高速且躲避收费和拥堵\n\n 公交:0-最快捷;\n 1-最经济;\n 2-最少换乘;\n 3-最少步行;\n 4-最舒适;\n 5-不乘地铁;\n\n 步行,无策略,均一样 +@property (nonatomic, assign) NSInteger strategy; +///Route的type,默认为0,超出范围为0.\n 0为驾车,\n 1为公交,\n 2为步行 +@property (nonatomic, assign) NSInteger type; +///起点坐标 +@property (nonatomic, copy) AMapGeoPoint *startCoordinate; +///终点坐标 +@property (nonatomic, copy) AMapGeoPoint *destinationCoordinate; +///起点名称,默认为“已选择的位置”,请不要包含【,%&@#】等特殊符号 +@property (nonatomic, copy) NSString *startName; +///终点名称,默认为“已选择的位置”,请不要包含【,%&@#】等特殊符号 +@property (nonatomic, copy) NSString *destinationName; +@end + +///导航短串分享请求 +@interface AMapNavigationShareSearchRequest : AMapShareSearchBaseRequest + +///默认为0,超出范围为0\n 驾车:0-速度最快(时间);\n 1-避免收费(不走收费路段的最快道路);\n 2-距离优先;\n 3-不走高速;\n 4-结合实时交通(躲避拥堵);\n 5-不走高速且避免收费;\n 6-不走高速且躲避拥堵;\n 7-躲避收费和拥堵;\n 8-不走高速且躲避收费和拥堵 +@property (nonatomic, assign) NSInteger strategy; +///起点坐标,若跳转到高德地图,默认更换为定位坐标 +@property (nonatomic, copy) AMapGeoPoint *startCoordinate; +///终点坐标 +@property (nonatomic, copy) AMapGeoPoint *destinationCoordinate; +@end + +///导航短串分享响应 +@interface AMapShareSearchResponse : AMapSearchObject +///转换后的短串 +@property (nonatomic, copy) NSString *shareURL; +@end + +///未来路线规划(since 6.9.0) +@interface AMapFutureRouteSearchRequest : AMapRouteSearchBaseRequest +///出发时间 单位为秒 +@property (nonatomic, copy) NSString *beginTime; +///时间间隔 单位为秒 +@property (nonatomic, assign) NSInteger interval; +///时间点个数,最多48个 +@property (nonatomic, assign) NSInteger timeCount; +/** + 未来路线规划策略,默认策略为0。 + 1,返回的结果考虑路况,尽量躲避拥堵而规划路径,与高德地图的“躲避拥堵”策略一致 + 2,返回的结果不走高速,与高德地图“不走高速”策略一致 + 3,返回的结果尽可能规划收费较低甚至免费的路径,与高德地图“避免收费”策略一致 + 4,返回的结果考虑路况,尽量躲避拥堵而规划路径,并且不走高速,与高德地图的“躲避拥堵&不走高速”策略一致 + 5,返回的结果尽量不走高速,并且尽量规划收费较低甚至免费的路径结果,与高德地图的“避免收费&不走高速”策略一致 + 6,返回路径规划结果会尽量的躲避拥堵,并且规划收费较低甚至免费的路径结果,与高德地图的“躲避拥堵&避免收费”策略一致 + 7,返回的结果尽量躲避拥堵,规划收费较低甚至免费的路径结果,并且尽量不走高速路,与高德地图的“避免拥堵&避免收费&不走高速”策略一致 + 8,返回的结果会优先选择高速路,与高德地图的“高速优先”策略一致 + 9,返回的结果会优先考虑高速路,并且会考虑路况躲避拥堵,与高德地图的“躲避拥堵&高速优先”策略一致 + 10,不考虑路况,返回速度最优、耗时最短的路线,但是此路线不一定距离最短 + 11,避让拥堵&速度优先&避免收费 + */ +@property (nonatomic, assign) NSInteger strategy; +///出发点 POI ID +@property (nonatomic, copy) NSString *originId; +///目的地 POI ID +@property (nonatomic, copy) NSString *destinationId; +///出发点POI类型编码 +@property (nonatomic, copy) NSString *origintype; +///目的地POI类型编码 +@property (nonatomic, copy) NSString *destinationtype; +///终点的父POI ID +@property (nonatomic, copy) NSString *parentId; + +/////是否返回扩展信息,默认为 NO +//@property (nonatomic, assign) BOOL requireExtension; +///车牌省份,用汉字填入车牌省份缩写。用于判断是否限行 +@property (nonatomic, copy) NSString *plateProvince; +///车牌详情,填入除省份及标点之外的字母和数字(需大写)。用于判断是否限行。 +@property (nonatomic, copy) NSString *plateNumber; +/** + 驾车路径规划车辆类型,默认策略为0。 + 0:普通汽车(默认值); + 1:纯电动车; + 2:插电混动车 + */ +@property (nonatomic, assign) NSInteger cartype; +@end + +///未来路线规划(since 6.9.0) +@interface AMapFutureRouteSearchResponse : AMapSearchObject +///路径规划方案,只会返回AMapPath中的distance、totalTrafficLights、steps +@property (nonatomic, strong) NSArray *paths; +///不同时间的规划以及信息列表 +@property (nonatomic, strong) NSArray *timeInfos; +@end diff --git a/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchVersion.h b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchVersion.h new file mode 100644 index 0000000..de30a64 --- /dev/null +++ b/Pods/AMapSearch/AMapSearchKit.framework/Headers/AMapSearchVersion.h @@ -0,0 +1,26 @@ +// +// AMapSearchVersion.h +// AMapSearchKit +// +// Created by xiaoming han on 15/10/27. +// Copyright © 2015年 Amap. All rights reserved. +// + +#import +#import + +#ifndef AMapSearchVersion_h +#define AMapSearchVersion_h + +#define AMapSearchVersionNumber 70600 +#define AMapSearchMinRequiredFoundationVersion 10603 + +// 依赖库版本检测 +#if AMapFoundationVersionNumber < AMapSearchMinRequiredFoundationVersion +#error "The AMapFoundationKit version is less than minimum required, please update! Any questions please to visit http://lbs.amap.com" +#endif + +FOUNDATION_EXTERN NSString * const AMapSearchVersion; +FOUNDATION_EXTERN NSString * const AMapSearchName; + +#endif /* AMapSearchVersion_h */ diff --git a/Pods/AMapSearch/AMapSearchKit.framework/Modules/module.modulemap b/Pods/AMapSearch/AMapSearchKit.framework/Modules/module.modulemap new file mode 100644 index 0000000..c09b8b1 --- /dev/null +++ b/Pods/AMapSearch/AMapSearchKit.framework/Modules/module.modulemap @@ -0,0 +1,6 @@ +framework module AMapSearchKit { + umbrella header "AMapSearchKit.h" + + export * + module * { export * } +} diff --git a/Pods/AMapSearch/AMapSearchKit.framework/version.txt b/Pods/AMapSearch/AMapSearchKit.framework/version.txt new file mode 100644 index 0000000..33915d2 --- /dev/null +++ b/Pods/AMapSearch/AMapSearchKit.framework/version.txt @@ -0,0 +1 @@ +7.6.0+sea.c2b61ae diff --git a/Pods/Bugly/Bugly.framework/Bugly b/Pods/Bugly/Bugly.framework/Bugly index 05dd8e6..56c16f9 100644 Binary files a/Pods/Bugly/Bugly.framework/Bugly and b/Pods/Bugly/Bugly.framework/Bugly differ diff --git a/Pods/Bugly/Bugly.framework/Headers/Bugly.h b/Pods/Bugly/Bugly.framework/Headers/Bugly.h index ba33306..050c037 100644 --- a/Pods/Bugly/Bugly.framework/Headers/Bugly.h +++ b/Pods/Bugly/Bugly.framework/Headers/Bugly.h @@ -1,7 +1,7 @@ // // Bugly.h // -// Version: 2.5(0) +// Version: 2.5(71) // // Copyright (c) 2017年 Tencent. All rights reserved. // @@ -16,7 +16,7 @@ BLY_START_NONNULL @interface Bugly : NSObject /** - * 初始化Bugly,使用默认BuglyConfig + * 初始化Bugly,使用默认BuglyConfigs * * @param appId 注册Bugly分配的应用唯一标识 */ @@ -65,6 +65,13 @@ BLY_START_NONNULL + (void)setUserValue:(NSString *)value forKey:(NSString *)key; +/** + * 获取USER ID + * + * @return USER ID + */ ++ (NSString *)buglyUserIdentifier; + /** * 获取关键数据 * @@ -131,6 +138,13 @@ BLY_START_NONNULL */ + (NSString *)sdkVersion; +/** + * APP 版本信息 + * + * @return SDK版本号 + */ ++ (NSString *)appVersion; + /** * App 是否发生了连续闪退 * 如果 启动SDK 且 5秒内 闪退,且次数达到 3次 则判定为连续闪退 @@ -139,6 +153,11 @@ BLY_START_NONNULL */ + (BOOL)isAppCrashedOnStartUpExceedTheLimit; +/** + * 关闭bugly监控 + */ ++ (void)closeCrashReport; + BLY_END_NONNULL @end diff --git a/Pods/Bugly/Bugly.framework/Headers/BuglyConfig.h b/Pods/Bugly/Bugly.framework/Headers/BuglyConfig.h index 0e0fea1..306b228 100644 --- a/Pods/Bugly/Bugly.framework/Headers/BuglyConfig.h +++ b/Pods/Bugly/Bugly.framework/Headers/BuglyConfig.h @@ -39,6 +39,16 @@ BLY_START_NONNULL */ - (NSString * BLY_NULLABLE)attachmentForException:(NSException * BLY_NULLABLE)exception; + +/** + * 策略激活时回调 + * + * @param tacticInfo + * + * @return app是否弹框展示 + */ +- (BOOL) h5AlertForTactic:(NSDictionary *)tacticInfo; + @end @interface BuglyConfig : NSObject @@ -122,5 +132,10 @@ BLY_START_NONNULL */ @property (nonatomic, assign) NSUInteger crashAbortTimeout; +/** + * 设置自定义联网、crash上报域名 + */ +@property (nonatomic, copy) NSString *crashServerUrl; + @end BLY_END_NONNULL diff --git a/Pods/CocoaLumberjack/LICENSE b/Pods/CocoaLumberjack/LICENSE new file mode 100644 index 0000000..029cd9e --- /dev/null +++ b/Pods/CocoaLumberjack/LICENSE @@ -0,0 +1,14 @@ +BSD 3-Clause License + +Copyright (c) 2010-2020, Deusty, LLC +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of Deusty nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Deusty, LLC. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Pods/CocoaLumberjack/README.md b/Pods/CocoaLumberjack/README.md new file mode 100644 index 0000000..dd3d483 --- /dev/null +++ b/Pods/CocoaLumberjack/README.md @@ -0,0 +1,240 @@ +

+ +

+ +CocoaLumberjack +=============== +![Unit Tests](https://github.com/CocoaLumberjack/CocoaLumberjack/workflows/Unit%20Tests/badge.svg) +[![Pod Version](http://img.shields.io/cocoapods/v/CocoaLumberjack.svg?style=flat)](http://cocoadocs.org/docsets/CocoaLumberjack/) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![Pod Platform](http://img.shields.io/cocoapods/p/CocoaLumberjack.svg?style=flat)](http://cocoadocs.org/docsets/CocoaLumberjack/) +[![Pod License](http://img.shields.io/cocoapods/l/CocoaLumberjack.svg?style=flat)](http://opensource.org/licenses/BSD-3-Clause) +[![codecov](https://codecov.io/gh/CocoaLumberjack/CocoaLumberjack/branch/master/graph/badge.svg)](https://codecov.io/gh/CocoaLumberjack/CocoaLumberjack) +[![codebeat badge](https://codebeat.co/badges/840b714a-c8f3-4936-ada4-363473cd4e6b)](https://codebeat.co/projects/github-com-cocoalumberjack-cocoalumberjack-master) + + +**CocoaLumberjack** is a fast & simple, yet powerful & flexible logging framework for macOS, iOS, tvOS and watchOS. + +### How to get started + +First, install CocoaLumberjack via [CocoaPods](http://cocoapods.org), [Carthage](https://github.com/Carthage/Carthage), [Swift Package Manager](https://swift.org/package-manager/) or manually. +Then use `DDOSLogger` for iOS 10 and later, or `DDTTYLogger` and `DDASLLogger` for earlier versions to begin logging messages. + +#### CocoaPods + +```ruby +platform :ios, '9.0' + +target 'SampleTarget' do + use_frameworks! + pod 'CocoaLumberjack/Swift' +end +``` +Note: `Swift` is a subspec which will include all the Obj-C code plus the Swift one, so this is sufficient. +For more details about how to use Swift with Lumberjack, see [this conversation](https://github.com/CocoaLumberjack/CocoaLumberjack/issues/405). + +For Objective-C use the following: +```ruby +platform :ios, '9.0' + +target 'SampleTarget' do + pod 'CocoaLumberjack' +end +``` + +#### Carthage + +Carthage is a lightweight dependency manager for Swift and Objective-C. It leverages CocoaTouch modules and is less invasive than CocoaPods. + +To install with Carthage, follow the instruction on [Carthage](https://github.com/Carthage/Carthage) + +Cartfile +``` +github "CocoaLumberjack/CocoaLumberjack" +``` + + +#### Swift Package Manager + +As of CocoaLumberjack 3.6.0, you can use the Swift Package Manager as integration method. +If you want to use the Swift Package Manager as integration method, either use Xcode to add the package dependency or add the following dependency to your Package.swift: + +```swift +.package(url: "https://github.com/CocoaLumberjack/CocoaLumberjack.git", from: "3.7.0"), +``` + +Note that you may need to add both products, `CocoaLumberjack` and `CocoaLumberjackSwift` to your target since SPM sometimes fails to detect that `CocoaLumerjackSwift` depends on `CocoaLumberjack`. + +#### Install manually + +If you want to install CocoaLumberjack manually, read the [manual installation](https://raw.githubusercontent.com/CocoaLumberjack/CocoaLumberjack/master/Documentation/GettingStarted.md#manual-installation) guide for more information. + +#### Swift Usage + +Usually, you can simply `import CocoaLumberjackSwift`. If you installed CocoaLumberjack using CocoaPods, you need to use `import CocoaLumberjack` instead. + +```swift +DDLog.add(DDOSLogger.sharedInstance) // Uses os_log + +let fileLogger: DDFileLogger = DDFileLogger() // File Logger +fileLogger.rollingFrequency = 60 * 60 * 24 // 24 hours +fileLogger.logFileManager.maximumNumberOfLogFiles = 7 +DDLog.add(fileLogger) + +... + +DDLogVerbose("Verbose") +DDLogDebug("Debug") +DDLogInfo("Info") +DDLogWarn("Warn") +DDLogError("Error") +``` + +#### Obj-C usage + +If you're using Lumberjack as a framework, you can `@import CocoaLumberjack;`. +Otherwise, `#import ` + +```objc +[DDLog addLogger:[DDOSLogger sharedInstance]]; // Uses os_log + +DDFileLogger *fileLogger = [[DDFileLogger alloc] init]; // File Logger +fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling +fileLogger.logFileManager.maximumNumberOfLogFiles = 7; +[DDLog addLogger:fileLogger]; + +... + +DDLogVerbose(@"Verbose"); +DDLogDebug(@"Debug"); +DDLogInfo(@"Info"); +DDLogWarn(@"Warn"); +DDLogError(@"Error"); +``` + + +### [swift-log](https://github.com/apple/swift-log) backend + +CocoaLumberjack also ships with a backend implementation for [swift-log](https://github.com/apple/swift-log). +Simply add CocoaLumberjack as dependency to your SPM target (see above) and also add the `CocoaLumberjackSwiftLogBackend` product as dependency to your target. + +You can then use `DDLogHandler` as backend for swift-log, which will forward all messages to CocoaLumberjack's `DDLog`. You will still configure the loggers and log formatters you want via `DDLog`, but writing log messages will be done using `Logger` from swift-log. + +In your own log formatters, you can make use of the `swiftLogInfo` property on `DDLogMessage` to retrieve the details of a message that is logged via swift-log. + + +#### More information + +- read the [Getting started](https://raw.githubusercontent.com/CocoaLumberjack/CocoaLumberjack/master/Documentation/GettingStarted.md) guide, check out the [FAQ](https://raw.githubusercontent.com/CocoaLumberjack/CocoaLumberjack/master/Documentation/FAQ.md) section or the other [docs](Documentation/) +- if you find issues or want to suggest improvements, create an issue or a pull request +- for all kinds of questions involving CocoaLumberjack, use the [Google group](http://groups.google.com/group/cocoalumberjack) or StackOverflow (use [#lumberjack](http://stackoverflow.com/questions/tagged/lumberjack)). + + +### CocoaLumberjack 3 + +#### Migrating to 3.x + +* To be determined + +### Features + +#### Lumberjack is Fast & Simple, yet Powerful & Flexible. + +It is similar in concept to other popular logging frameworks such as log4j, yet is designed specifically for Objective-C, and takes advantage of features such as multi-threading, grand central dispatch (if available), lockless atomic operations, and the dynamic nature of the Objective-C runtime. + +#### Lumberjack is Fast + +In most cases it is an order of magnitude faster than NSLog. + +#### Lumberjack is Simple + +It takes as little as a single line of code to configure lumberjack when your application launches. Then simply replace your NSLog statements with DDLog statements and that's about it. (And the DDLog macros have the exact same format and syntax as NSLog, so it's super easy.) + +#### Lumberjack is Powerful: + +One log statement can be sent to multiple loggers, meaning you can log to a file and the console simultaneously. Want more? Create your own loggers (it's easy) and send your log statements over the network. Or to a database or distributed file system. The sky is the limit. + +#### Lumberjack is Flexible: + +Configure your logging however you want. Change log levels per file (perfect for debugging). Change log levels per logger (verbose console, but concise log file). Change log levels per xcode configuration (verbose debug, but concise release). Have your log statements compiled out of the release build. Customize the number of log levels for your application. Add your own fine-grained logging. Dynamically change log levels during runtime. Choose how & when you want your log files to be rolled. Upload your log files to a central server. Compress archived log files to save disk space... + +### This framework is for you if: + +- You're looking for a way to track down that impossible-to-reproduce bug that keeps popping up in the field. +- You're frustrated with the super short console log on the iPhone. +- You're looking to take your application to the next level in terms of support and stability. +- You're looking for an enterprise level logging solution for your application (Mac or iPhone). + +### Documentation + +- **[Get started using Lumberjack](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/GettingStarted.md)**
+- [Different log levels for Debug and Release builds](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/XcodeTricks.md)
+- [Different log levels for each logger](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/PerLoggerLogLevels.md)
+- [Use colors in the Xcode debugging console](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/XcodeColors.md)
+- [Write your own custom formatters](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/CustomFormatters.md)
+- [FAQ](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/FAQ.md)
+- [Analysis of performance with benchmarks](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/Performance.md)
+- [Common issues you may encounter and their solutions](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/ProblemSolution.md)
+- [AppCode support](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/Documentation/AppCode-support.md) +- **[Full Lumberjack documentation](Documentation/)**
+ +### Requirements +The current version of Lumberjack requires: +- Xcode 12 or later +- Swift 5.3 or later +- iOS 9 or later +- macOS 10.10 or later +- watchOS 3 or later +- tvOS 9 or later + +#### Backwards compatibility +- for Xcode 11 and Swift up to 5.2, use the 3.6.2 version +- for Xcode 10 and Swift 4.2, use the 3.5.2 version +- for iOS 8, use the 3.6.1 version +- for iOS 6, iOS 7, OS X 10.8, OS X 10.9 and Xcode 9, use the 3.4.2 version +- for iOS 5 and OS X 10.7, use the 3.3 version +- for Xcode 8 and Swift 3, use the 3.2 version +- for Xcode 7.3 and Swift 2.3, use the 2.4.0 version +- for Xcode 7.3 and Swift 2.2, use the 2.3.0 version +- for Xcode 7.2 and 7.1, use the 2.2.0 version +- for Xcode 7.0 or earlier, use the 2.1.0 version +- for Xcode 6 or earlier, use the 2.0.x version +- for OS X < 10.7 support, use the 1.6.0 version + +### Communication + +- If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/lumberjack). (Tag 'lumberjack') +- If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/lumberjack). +- If you **found a bug**, open an issue. +- If you **have a feature request**, open an issue. +- If you **want to contribute**, submit a pull request. + +### Author +- [Robbie Hanson](https://github.com/robbiehanson) +- Love the project? Wanna buy me a coffee? (or a beer :D) [![donation](http://www.paypal.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UZRA26JPJB3DA) + +### Collaborators +- [Ernesto Rivera](https://github.com/rivera-ernesto) +- [Dmitry Vorobyov](https://github.com/dvor) +- [Bogdan Poplauschi](https://github.com/bpoplauschi) +- [C.W. Betts](https://github.com/MaddTheSane) +- [Koichi Yokota (sushichop)](https://github.com/sushichop) +- [Nick Brook](https://github.com/nrbrook) +- [Florian Friedrich](https://github.com/ffried) +- [Stephan Diederich](https://github.com/diederich) +- [Kent Sutherland](https://github.com/ksuther) +- [Dmitry Lobanov](https://github.com/lolgear) +- [Hakon Hanesand](https://github.com/hhanesand) + +### License +- CocoaLumberjack is available under the BSD 3 license. See the [LICENSE file](https://github.com/CocoaLumberjack/CocoaLumberjack/blob/master/LICENSE). + +### Extensions +- [LogIO-CocoaLumberjack](https://github.com/s4nchez/LogIO-CocoaLumberjack) A log.io logger for CocoaLumberjack +- [XCDLumberjackNSLogger](https://github.com/0xced/XCDLumberjackNSLogger) CocoaLumberjack logger which sends logs to NSLogger + +### Architecture + +

+ +

diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/CLI/CLIColor.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/CLI/CLIColor.m new file mode 100644 index 0000000..b8c4b93 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/CLI/CLIColor.m @@ -0,0 +1,55 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#if TARGET_OS_OSX + +#import + +@interface CLIColor () { + CGFloat _red, _green, _blue, _alpha; +} + +@end + + +@implementation CLIColor + ++ (instancetype)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha { + CLIColor *color = [CLIColor new]; + color->_red = red; + color->_green = green; + color->_blue = blue; + color->_alpha = alpha; + return color; +} + +- (void)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha { + if (red) { + *red = _red; + } + if (green) { + *green = _green; + } + if (blue) { + *blue = _blue; + } + if (alpha) { + *alpha = _alpha; + } +} + +@end + +#endif diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDASLLogCapture.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDASLLogCapture.m new file mode 100644 index 0000000..b15ef34 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDASLLogCapture.m @@ -0,0 +1,203 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#if !TARGET_OS_WATCH + +#include +#include +#include +#include + +#import + +// Disable legacy macros +#ifndef DD_LEGACY_MACROS + #define DD_LEGACY_MACROS 0 +#endif + +static BOOL _cancel = YES; +static DDLogLevel _captureLevel = DDLogLevelVerbose; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" +@implementation DDASLLogCapture +#pragma clang diagnostic pop + ++ (void)start { + // Ignore subsequent calls + if (!_cancel) { + return; + } + + _cancel = NO; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { + [self captureAslLogs]; + }); +} + ++ (void)stop { + _cancel = YES; +} + ++ (DDLogLevel)captureLevel { + return _captureLevel; +} + ++ (void)setCaptureLevel:(DDLogLevel)level { + _captureLevel = level; +} + +#pragma mark - Private methods + ++ (void)configureAslQuery:(aslmsg)query { + const char param[] = "7"; // ASL_LEVEL_DEBUG, which is everything. We'll rely on regular DDlog log level to filter + + asl_set_query(query, ASL_KEY_LEVEL, param, ASL_QUERY_OP_LESS_EQUAL | ASL_QUERY_OP_NUMERIC); + + // Don't retrieve logs from our own DDASLLogger + asl_set_query(query, kDDASLKeyDDLog, kDDASLDDLogValue, ASL_QUERY_OP_NOT_EQUAL); + +#if !TARGET_OS_IPHONE || (defined(TARGET_SIMULATOR) && TARGET_SIMULATOR) + int processId = [[NSProcessInfo processInfo] processIdentifier]; + char pid[16]; + snprintf(pid, sizeof(pid), "%d", processId); + asl_set_query(query, ASL_KEY_PID, pid, ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_NUMERIC); +#endif +} + ++ (void)aslMessageReceived:(aslmsg)msg { + const char* messageCString = asl_get( msg, ASL_KEY_MSG ); + if ( messageCString == NULL ) + return; + + DDLogFlag flag; + BOOL async; + + const char* levelCString = asl_get(msg, ASL_KEY_LEVEL); + switch (levelCString? atoi(levelCString) : 0) { + // By default all NSLog's with a ASL_LEVEL_WARNING level + case ASL_LEVEL_EMERG : + case ASL_LEVEL_ALERT : + case ASL_LEVEL_CRIT : flag = DDLogFlagError; async = NO; break; + case ASL_LEVEL_ERR : flag = DDLogFlagWarning; async = YES; break; + case ASL_LEVEL_WARNING : flag = DDLogFlagInfo; async = YES; break; + case ASL_LEVEL_NOTICE : flag = DDLogFlagDebug; async = YES; break; + case ASL_LEVEL_INFO : + case ASL_LEVEL_DEBUG : + default : flag = DDLogFlagVerbose; async = YES; break; + } + + if (!(_captureLevel & flag)) { + return; + } + + // NSString * sender = [NSString stringWithCString:asl_get(msg, ASL_KEY_SENDER) encoding:NSUTF8StringEncoding]; + NSString *message = @(messageCString); + + const char* secondsCString = asl_get( msg, ASL_KEY_TIME ); + const char* nanoCString = asl_get( msg, ASL_KEY_TIME_NSEC ); + NSTimeInterval seconds = secondsCString ? strtod(secondsCString, NULL) : [NSDate timeIntervalSinceReferenceDate] - NSTimeIntervalSince1970; + double nanoSeconds = nanoCString? strtod(nanoCString, NULL) : 0; + NSTimeInterval totalSeconds = seconds + (nanoSeconds / 1e9); + + NSDate *timeStamp = [NSDate dateWithTimeIntervalSince1970:totalSeconds]; + + DDLogMessage *logMessage = [[DDLogMessage alloc] initWithMessage:message + level:_captureLevel + flag:flag + context:0 + file:@"DDASLLogCapture" + function:nil + line:0 + tag:nil + options:0 + timestamp:timeStamp]; + + [DDLog log:async message:logMessage]; +} + ++ (void)captureAslLogs { + @autoreleasepool + { + /* + We use ASL_KEY_MSG_ID to see each message once, but there's no + obvious way to get the "next" ID. To bootstrap the process, we'll + search by timestamp until we've seen a message. + */ + + struct timeval timeval = { + .tv_sec = 0 + }; + gettimeofday(&timeval, NULL); + unsigned long long startTime = (unsigned long long)timeval.tv_sec; + __block unsigned long long lastSeenID = 0; + + /* + syslogd posts kNotifyASLDBUpdate (com.apple.system.logger.message) + through the notify API when it saves messages to the ASL database. + There is some coalescing - currently it is sent at most twice per + second - but there is no documented guarantee about this. In any + case, there may be multiple messages per notification. + + Notify notifications don't carry any payload, so we need to search + for the messages. + */ + int notifyToken = 0; // Can be used to unregister with notify_cancel(). + notify_register_dispatch(kNotifyASLDBUpdate, ¬ifyToken, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(int token) + { + // At least one message has been posted; build a search query. + @autoreleasepool + { + aslmsg query = asl_new(ASL_TYPE_QUERY); + char stringValue[64]; + + if (lastSeenID > 0) { + snprintf(stringValue, sizeof stringValue, "%llu", lastSeenID); + asl_set_query(query, ASL_KEY_MSG_ID, stringValue, ASL_QUERY_OP_GREATER | ASL_QUERY_OP_NUMERIC); + } else { + snprintf(stringValue, sizeof stringValue, "%llu", startTime); + asl_set_query(query, ASL_KEY_TIME, stringValue, ASL_QUERY_OP_GREATER_EQUAL | ASL_QUERY_OP_NUMERIC); + } + + [self configureAslQuery:query]; + + // Iterate over new messages. + aslmsg msg; + aslresponse response = asl_search(NULL, query); + + while ((msg = asl_next(response))) + { + [self aslMessageReceived:msg]; + + // Keep track of which messages we've seen. + lastSeenID = (unsigned long long)atoll(asl_get(msg, ASL_KEY_MSG_ID)); + } + asl_release(response); + asl_free(query); + + if (_cancel) { + notify_cancel(token); + return; + } + + } + }); + } +} + +@end + +#endif diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDASLLogger.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDASLLogger.m new file mode 100644 index 0000000..450f486 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDASLLogger.m @@ -0,0 +1,131 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#if !TARGET_OS_WATCH + +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +#import + +#import + +const char* const kDDASLKeyDDLog = "DDLog"; +const char* const kDDASLDDLogValue = "1"; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated" +static DDASLLogger *sharedInstance; +#pragma clang diagnostic pop + +@interface DDASLLogger () { + aslclient _client; +} + +@end + + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" +@implementation DDASLLogger +#pragma clang diagnostic pop + ++ (instancetype)sharedInstance { + static dispatch_once_t DDASLLoggerOnceToken; + + dispatch_once(&DDASLLoggerOnceToken, ^{ + sharedInstance = [[[self class] alloc] init]; + }); + + return sharedInstance; +} + +- (instancetype)init { + if (sharedInstance != nil) { + return nil; + } + + if ((self = [super init])) { + // A default asl client is provided for the main thread, + // but background threads need to create their own client. + + _client = asl_open(NULL, "com.apple.console", 0); + } + + return self; +} + +- (DDLoggerName)loggerName { + return DDLoggerNameASL; +} + +- (void)logMessage:(DDLogMessage *)logMessage { + // Skip captured log messages + if ([logMessage->_fileName isEqualToString:@"DDASLLogCapture"]) { + return; + } + + NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message; + + if (message) { + const char *msg = [message UTF8String]; + + size_t aslLogLevel; + switch (logMessage->_flag) { + // Note: By default ASL will filter anything above level 5 (Notice). + // So our mappings shouldn't go above that level. + case DDLogFlagError : aslLogLevel = ASL_LEVEL_CRIT; break; + case DDLogFlagWarning : aslLogLevel = ASL_LEVEL_ERR; break; + case DDLogFlagInfo : aslLogLevel = ASL_LEVEL_WARNING; break; // Regular NSLog's level + case DDLogFlagDebug : + case DDLogFlagVerbose : + default : aslLogLevel = ASL_LEVEL_NOTICE; break; + } + + static char const *const level_strings[] = { "0", "1", "2", "3", "4", "5", "6", "7" }; + + // NSLog uses the current euid to set the ASL_KEY_READ_UID. + uid_t const readUID = geteuid(); + + char readUIDString[16]; +#ifndef NS_BLOCK_ASSERTIONS + size_t l = (size_t)snprintf(readUIDString, sizeof(readUIDString), "%d", readUID); +#else + snprintf(readUIDString, sizeof(readUIDString), "%d", readUID); +#endif + + NSAssert(l < sizeof(readUIDString), + @"Formatted euid is too long."); + NSAssert(aslLogLevel < (sizeof(level_strings) / sizeof(level_strings[0])), + @"Unhandled ASL log level."); + + aslmsg m = asl_new(ASL_TYPE_MSG); + if (m != NULL) { + if (asl_set(m, ASL_KEY_LEVEL, level_strings[aslLogLevel]) == 0 && + asl_set(m, ASL_KEY_MSG, msg) == 0 && + asl_set(m, ASL_KEY_READ_UID, readUIDString) == 0 && + asl_set(m, kDDASLKeyDDLog, kDDASLDDLogValue) == 0) { + asl_send(_client, m); + } + asl_free(m); + } + //TODO handle asl_* failures non-silently? + } +} + +@end + +#endif diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDAbstractDatabaseLogger.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDAbstractDatabaseLogger.m new file mode 100644 index 0000000..441eff7 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDAbstractDatabaseLogger.m @@ -0,0 +1,683 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +#import + +@interface DDAbstractDatabaseLogger () + +- (void)destroySaveTimer; +- (void)updateAndResumeSaveTimer; +- (void)createSuspendedSaveTimer; +- (void)destroyDeleteTimer; +- (void)updateDeleteTimer; +- (void)createAndStartDeleteTimer; + +@end + +#pragma mark - + +@implementation DDAbstractDatabaseLogger + +- (instancetype)init { + if ((self = [super init])) { + _saveThreshold = 500; + _saveInterval = 60; // 60 seconds + _maxAge = (60 * 60 * 24 * 7); // 7 days + _deleteInterval = (60 * 5); // 5 minutes + } + + return self; +} + +- (void)dealloc { + [self destroySaveTimer]; + [self destroyDeleteTimer]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Override Me +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)db_log:(__unused DDLogMessage *)logMessage { + // Override me and add your implementation. + // + // Return YES if an item was added to the buffer. + // Return NO if the logMessage was ignored. + + return NO; +} + +- (void)db_save { + // Override me and add your implementation. +} + +- (void)db_delete { + // Override me and add your implementation. +} + +- (void)db_saveAndDelete { + // Override me and add your implementation. +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Private API +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)performSaveAndSuspendSaveTimer { + if (_unsavedCount > 0) { + if (_deleteOnEverySave) { + [self db_saveAndDelete]; + } else { + [self db_save]; + } + } + + _unsavedCount = 0; + _unsavedTime = 0; + + if (_saveTimer != NULL && _saveTimerSuspended == 0) { + dispatch_suspend(_saveTimer); + _saveTimerSuspended = 1; + } +} + +- (void)performDelete { + if (_maxAge > 0.0) { + [self db_delete]; + + _lastDeleteTime = dispatch_time(DISPATCH_TIME_NOW, 0); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Timers +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)destroySaveTimer { + if (_saveTimer != NULL) { + dispatch_source_cancel(_saveTimer); + + // Must activate a timer before releasing it (or it will crash) + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { + if (_saveTimerSuspended < 0) { + dispatch_activate(_saveTimer); + } else if (_saveTimerSuspended > 0) { + dispatch_resume(_saveTimer); + } + } else { + if (_saveTimerSuspended != 0) { + dispatch_resume(_saveTimer); + } + } + + #if !OS_OBJECT_USE_OBJC + dispatch_release(_saveTimer); + #endif + _saveTimer = NULL; + _saveTimerSuspended = 0; + } +} + +- (void)updateAndResumeSaveTimer { + if ((_saveTimer != NULL) && (_saveInterval > 0.0) && (_unsavedTime > 0)) { + uint64_t interval = (uint64_t)(_saveInterval * (NSTimeInterval) NSEC_PER_SEC); + dispatch_time_t startTime = dispatch_time(_unsavedTime, (int64_t)interval); + + dispatch_source_set_timer(_saveTimer, startTime, interval, 1ull * NSEC_PER_SEC); + + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) { + if (_saveTimerSuspended < 0) { + dispatch_activate(_saveTimer); + _saveTimerSuspended = 0; + } else if (_saveTimerSuspended > 0) { + dispatch_resume(_saveTimer); + _saveTimerSuspended = 0; + } + } else { + if (_saveTimerSuspended != 0) { + dispatch_resume(_saveTimer); + _saveTimerSuspended = 0; + } + } + } +} + +- (void)createSuspendedSaveTimer { + if ((_saveTimer == NULL) && (_saveInterval > 0.0)) { + _saveTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.loggerQueue); + + dispatch_source_set_event_handler(_saveTimer, ^{ @autoreleasepool { + [self performSaveAndSuspendSaveTimer]; + } }); + + _saveTimerSuspended = -1; + } +} + +- (void)destroyDeleteTimer { + if (_deleteTimer != NULL) { + dispatch_source_cancel(_deleteTimer); + #if !OS_OBJECT_USE_OBJC + dispatch_release(_deleteTimer); + #endif + _deleteTimer = NULL; + } +} + +- (void)updateDeleteTimer { + if ((_deleteTimer != NULL) && (_deleteInterval > 0.0) && (_maxAge > 0.0)) { + int64_t interval = (int64_t)(_deleteInterval * (NSTimeInterval) NSEC_PER_SEC); + dispatch_time_t startTime; + + if (_lastDeleteTime > 0) { + startTime = dispatch_time(_lastDeleteTime, interval); + } else { + startTime = dispatch_time(DISPATCH_TIME_NOW, interval); + } + + dispatch_source_set_timer(_deleteTimer, startTime, (uint64_t)interval, 1ull * NSEC_PER_SEC); + } +} + +- (void)createAndStartDeleteTimer { + if ((_deleteTimer == NULL) && (_deleteInterval > 0.0) && (_maxAge > 0.0)) { + _deleteTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.loggerQueue); + + if (_deleteTimer != NULL) { + dispatch_source_set_event_handler(_deleteTimer, ^{ @autoreleasepool { + [self performDelete]; + } }); + + [self updateDeleteTimer]; + + // We are sure that -updateDeleteTimer did call dispatch_source_set_timer() + // since it has the same guards on _deleteInterval and _maxAge + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) + dispatch_activate(_deleteTimer); + else + dispatch_resume(_deleteTimer); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Configuration +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (NSUInteger)saveThreshold { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSUInteger result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, ^{ + result = self->_saveThreshold; + }); + }); + + return result; +} + +- (void)setSaveThreshold:(NSUInteger)threshold { + dispatch_block_t block = ^{ + @autoreleasepool { + if (self->_saveThreshold != threshold) { + self->_saveThreshold = threshold; + + // Since the saveThreshold has changed, + // we check to see if the current unsavedCount has surpassed the new threshold. + // + // If it has, we immediately save the log. + + if ((self->_unsavedCount >= self->_saveThreshold) && (self->_saveThreshold > 0)) { + [self performSaveAndSuspendSaveTimer]; + } + } + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (NSTimeInterval)saveInterval { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSTimeInterval result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, ^{ + result = self->_saveInterval; + }); + }); + + return result; +} + +- (void)setSaveInterval:(NSTimeInterval)interval { + dispatch_block_t block = ^{ + @autoreleasepool { + // C99 recommended floating point comparison macro + // Read: isLessThanOrGreaterThan(floatA, floatB) + + if (/* saveInterval != interval */ islessgreater(self->_saveInterval, interval)) { + self->_saveInterval = interval; + + // There are several cases we need to handle here. + // + // 1. If the saveInterval was previously enabled and it just got disabled, + // then we need to stop the saveTimer. (And we might as well release it.) + // + // 2. If the saveInterval was previously disabled and it just got enabled, + // then we need to setup the saveTimer. (Plus we might need to do an immediate save.) + // + // 3. If the saveInterval increased, then we need to reset the timer so that it fires at the later date. + // + // 4. If the saveInterval decreased, then we need to reset the timer so that it fires at an earlier date. + // (Plus we might need to do an immediate save.) + + if (self->_saveInterval > 0.0) { + if (self->_saveTimer == NULL) { + // Handles #2 + // + // Since the saveTimer uses the unsavedTime to calculate it's first fireDate, + // if a save is needed the timer will fire immediately. + + [self createSuspendedSaveTimer]; + [self updateAndResumeSaveTimer]; + } else { + // Handles #3 + // Handles #4 + // + // Since the saveTimer uses the unsavedTime to calculate it's first fireDate, + // if a save is needed the timer will fire immediately. + + [self updateAndResumeSaveTimer]; + } + } else if (self->_saveTimer) { + // Handles #1 + + [self destroySaveTimer]; + } + } + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (NSTimeInterval)maxAge { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSTimeInterval result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, ^{ + result = self->_maxAge; + }); + }); + + return result; +} + +- (void)setMaxAge:(NSTimeInterval)interval { + dispatch_block_t block = ^{ + @autoreleasepool { + // C99 recommended floating point comparison macro + // Read: isLessThanOrGreaterThan(floatA, floatB) + + if (/* maxAge != interval */ islessgreater(self->_maxAge, interval)) { + NSTimeInterval oldMaxAge = self->_maxAge; + NSTimeInterval newMaxAge = interval; + + self->_maxAge = interval; + + // There are several cases we need to handle here. + // + // 1. If the maxAge was previously enabled and it just got disabled, + // then we need to stop the deleteTimer. (And we might as well release it.) + // + // 2. If the maxAge was previously disabled and it just got enabled, + // then we need to setup the deleteTimer. (Plus we might need to do an immediate delete.) + // + // 3. If the maxAge was increased, + // then we don't need to do anything. + // + // 4. If the maxAge was decreased, + // then we should do an immediate delete. + + BOOL shouldDeleteNow = NO; + + if (oldMaxAge > 0.0) { + if (newMaxAge <= 0.0) { + // Handles #1 + + [self destroyDeleteTimer]; + } else if (oldMaxAge > newMaxAge) { + // Handles #4 + shouldDeleteNow = YES; + } + } else if (newMaxAge > 0.0) { + // Handles #2 + shouldDeleteNow = YES; + } + + if (shouldDeleteNow) { + [self performDelete]; + + if (self->_deleteTimer) { + [self updateDeleteTimer]; + } else { + [self createAndStartDeleteTimer]; + } + } + } + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (NSTimeInterval)deleteInterval { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block NSTimeInterval result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, ^{ + result = self->_deleteInterval; + }); + }); + + return result; +} + +- (void)setDeleteInterval:(NSTimeInterval)interval { + dispatch_block_t block = ^{ + @autoreleasepool { + // C99 recommended floating point comparison macro + // Read: isLessThanOrGreaterThan(floatA, floatB) + + if (/* deleteInterval != interval */ islessgreater(self->_deleteInterval, interval)) { + self->_deleteInterval = interval; + + // There are several cases we need to handle here. + // + // 1. If the deleteInterval was previously enabled and it just got disabled, + // then we need to stop the deleteTimer. (And we might as well release it.) + // + // 2. If the deleteInterval was previously disabled and it just got enabled, + // then we need to setup the deleteTimer. (Plus we might need to do an immediate delete.) + // + // 3. If the deleteInterval increased, then we need to reset the timer so that it fires at the later date. + // + // 4. If the deleteInterval decreased, then we need to reset the timer so that it fires at an earlier date. + // (Plus we might need to do an immediate delete.) + + if (self->_deleteInterval > 0.0) { + if (self->_deleteTimer == NULL) { + // Handles #2 + // + // Since the deleteTimer uses the lastDeleteTime to calculate it's first fireDate, + // if a delete is needed the timer will fire immediately. + + [self createAndStartDeleteTimer]; + } else { + // Handles #3 + // Handles #4 + // + // Since the deleteTimer uses the lastDeleteTime to calculate it's first fireDate, + // if a save is needed the timer will fire immediately. + + [self updateDeleteTimer]; + } + } else if (self->_deleteTimer) { + // Handles #1 + + [self destroyDeleteTimer]; + } + } + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (BOOL)deleteOnEverySave { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block BOOL result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, ^{ + result = self->_deleteOnEverySave; + }); + }); + + return result; +} + +- (void)setDeleteOnEverySave:(BOOL)flag { + dispatch_block_t block = ^{ + self->_deleteOnEverySave = flag; + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Public API +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)savePendingLogEntries { + dispatch_block_t block = ^{ + @autoreleasepool { + [self performSaveAndSuspendSaveTimer]; + } + }; + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_async(self.loggerQueue, block); + } +} + +- (void)deleteOldLogEntries { + dispatch_block_t block = ^{ + @autoreleasepool { + [self performDelete]; + } + }; + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_async(self.loggerQueue, block); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark DDLogger +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)didAddLogger { + // If you override me be sure to invoke [super didAddLogger]; + + [self createSuspendedSaveTimer]; + + [self createAndStartDeleteTimer]; +} + +- (void)willRemoveLogger { + // If you override me be sure to invoke [super willRemoveLogger]; + + [self performSaveAndSuspendSaveTimer]; + + [self destroySaveTimer]; + [self destroyDeleteTimer]; +} + +- (void)logMessage:(DDLogMessage *)logMessage { + if ([self db_log:logMessage]) { + BOOL firstUnsavedEntry = (++_unsavedCount == 1); + + if ((_unsavedCount >= _saveThreshold) && (_saveThreshold > 0)) { + [self performSaveAndSuspendSaveTimer]; + } else if (firstUnsavedEntry) { + _unsavedTime = dispatch_time(DISPATCH_TIME_NOW, 0); + [self updateAndResumeSaveTimer]; + } + } +} + +- (void)flush { + // This method is invoked by DDLog's flushLog method. + // + // It is called automatically when the application quits, + // or if the developer invokes DDLog's flushLog method prior to crashing or something. + + [self performSaveAndSuspendSaveTimer]; +} + +@end diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDFileLogger+Internal.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDFileLogger+Internal.h new file mode 100644 index 0000000..82d4608 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDFileLogger+Internal.h @@ -0,0 +1,31 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface DDFileLogger (Internal) + +- (void)logData:(NSData *)data; + +// Will assert if used outside logger's queue. +- (void)lt_logData:(NSData *)data; + +- (nullable NSData *)lt_dataForMessage:(DDLogMessage *)message; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDFileLogger.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDFileLogger.m new file mode 100644 index 0000000..d291836 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDFileLogger.m @@ -0,0 +1,1760 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +#import + +#import "DDFileLogger+Internal.h" + +// We probably shouldn't be using DDLog() statements within the DDLog implementation. +// But we still want to leave our log statements for any future debugging, +// and to allow other developers to trace the implementation (which is a great learning tool). +// +// So we use primitive logging macros around NSLog. +// We maintain the NS prefix on the macros to be explicit about the fact that we're using NSLog. + +#ifndef DD_NSLOG_LEVEL + #define DD_NSLOG_LEVEL 2 +#endif + +#define NSLogError(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 1) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogWarn(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 2) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogInfo(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 3) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogDebug(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 4) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogVerbose(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 5) NSLog((frmt), ##__VA_ARGS__); } while(0) + + +#if TARGET_OS_IPHONE +BOOL doesAppRunInBackground(void); +#endif + +unsigned long long const kDDDefaultLogMaxFileSize = 1024 * 1024; // 1 MB +NSTimeInterval const kDDDefaultLogRollingFrequency = 60 * 60 * 24; // 24 Hours +NSUInteger const kDDDefaultLogMaxNumLogFiles = 5; // 5 Files +unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20 MB + +NSTimeInterval const kDDRollingLeeway = 1.0; // 1s + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface DDLogFileManagerDefault () { + NSDateFormatter *_fileDateFormatter; + NSUInteger _maximumNumberOfLogFiles; + unsigned long long _logFilesDiskQuota; + NSString *_logsDirectory; +#if TARGET_OS_IPHONE + NSFileProtectionType _defaultFileProtectionLevel; +#endif +} + +@end + +@implementation DDLogFileManagerDefault + +@synthesize maximumNumberOfLogFiles = _maximumNumberOfLogFiles; +@synthesize logFilesDiskQuota = _logFilesDiskQuota; + ++ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey { + if ([theKey isEqualToString:@"maximumNumberOfLogFiles"] || [theKey isEqualToString:@"logFilesDiskQuota"]) { + return NO; + } else { + return [super automaticallyNotifiesObserversForKey:theKey]; + } +} + +- (instancetype)init { + return [self initWithLogsDirectory:nil]; +} + +- (instancetype)initWithLogsDirectory:(nullable NSString *)aLogsDirectory { + if ((self = [super init])) { + _maximumNumberOfLogFiles = kDDDefaultLogMaxNumLogFiles; + _logFilesDiskQuota = kDDDefaultLogFilesDiskQuota; + + _fileDateFormatter = [[NSDateFormatter alloc] init]; + [_fileDateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; + [_fileDateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; + [_fileDateFormatter setDateFormat: @"yyyy'-'MM'-'dd'--'HH'-'mm'-'ss'-'SSS'"]; + + if (aLogsDirectory.length > 0) { + _logsDirectory = [aLogsDirectory copy]; + } else { + _logsDirectory = [[self defaultLogsDirectory] copy]; + } + + NSKeyValueObservingOptions kvoOptions = NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew; + + [self addObserver:self forKeyPath:NSStringFromSelector(@selector(maximumNumberOfLogFiles)) options:kvoOptions context:nil]; + [self addObserver:self forKeyPath:NSStringFromSelector(@selector(logFilesDiskQuota)) options:kvoOptions context:nil]; + + NSLogVerbose(@"DDFileLogManagerDefault: logsDirectory:\n%@", [self logsDirectory]); + NSLogVerbose(@"DDFileLogManagerDefault: sortedLogFileNames:\n%@", [self sortedLogFileNames]); + } + + return self; +} + +#if TARGET_OS_IPHONE +- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory + defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel { + + if ((self = [self initWithLogsDirectory:logsDirectory])) { + if ([fileProtectionLevel isEqualToString:NSFileProtectionNone] || + [fileProtectionLevel isEqualToString:NSFileProtectionComplete] || + [fileProtectionLevel isEqualToString:NSFileProtectionCompleteUnlessOpen] || + [fileProtectionLevel isEqualToString:NSFileProtectionCompleteUntilFirstUserAuthentication]) { + _defaultFileProtectionLevel = fileProtectionLevel; + } + } + + return self; +} + +#endif + +- (void)dealloc { + // try-catch because the observer might be removed or never added. In this case, removeObserver throws an exception + @try { + [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(maximumNumberOfLogFiles))]; + [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(logFilesDiskQuota))]; + } @catch (NSException *exception) { + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Configuration +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(__unused id)object + change:(NSDictionary *)change + context:(__unused void *)context { + NSNumber *old = change[NSKeyValueChangeOldKey]; + NSNumber *new = change[NSKeyValueChangeNewKey]; + + if ([old isEqual:new]) { + return; + } + + if ([keyPath isEqualToString:NSStringFromSelector(@selector(maximumNumberOfLogFiles))] || + [keyPath isEqualToString:NSStringFromSelector(@selector(logFilesDiskQuota))]) { + NSLogInfo(@"DDFileLogManagerDefault: Responding to configuration change: %@", keyPath); + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + @autoreleasepool { + // See method header for queue reasoning. + [self deleteOldLogFiles]; + } + }); + } +} + +#if TARGET_OS_IPHONE +- (NSFileProtectionType)logFileProtection { + if (_defaultFileProtectionLevel.length > 0) { + return _defaultFileProtectionLevel; + } else if (doesAppRunInBackground()) { + return NSFileProtectionCompleteUntilFirstUserAuthentication; + } else { + return NSFileProtectionCompleteUnlessOpen; + } +} +#endif + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark File Deleting +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Deletes archived log files that exceed the maximumNumberOfLogFiles or logFilesDiskQuota configuration values. + * Method may take a while to execute since we're performing IO. It's not critical that this is synchronized with + * log output, since the files we're deleting are all archived and not in use, therefore this method is called on a + * background queue. + **/ +- (void)deleteOldLogFiles { + NSLogVerbose(@"DDLogFileManagerDefault: deleteOldLogFiles"); + + NSArray *sortedLogFileInfos = [self sortedLogFileInfos]; + NSUInteger firstIndexToDelete = NSNotFound; + + const unsigned long long diskQuota = self.logFilesDiskQuota; + const NSUInteger maxNumLogFiles = self.maximumNumberOfLogFiles; + + if (diskQuota) { + unsigned long long used = 0; + + for (NSUInteger i = 0; i < sortedLogFileInfos.count; i++) { + DDLogFileInfo *info = sortedLogFileInfos[i]; + used += info.fileSize; + + if (used > diskQuota) { + firstIndexToDelete = i; + break; + } + } + } + + if (maxNumLogFiles) { + if (firstIndexToDelete == NSNotFound) { + firstIndexToDelete = maxNumLogFiles; + } else { + firstIndexToDelete = MIN(firstIndexToDelete, maxNumLogFiles); + } + } + + if (firstIndexToDelete == 0) { + // Do we consider the first file? + // We are only supposed to be deleting archived files. + // In most cases, the first file is likely the log file that is currently being written to. + // So in most cases, we do not want to consider this file for deletion. + + if (sortedLogFileInfos.count > 0) { + DDLogFileInfo *logFileInfo = sortedLogFileInfos[0]; + + if (!logFileInfo.isArchived) { + // Don't delete active file. + ++firstIndexToDelete; + } + } + } + + if (firstIndexToDelete != NSNotFound) { + // removing all log files starting with firstIndexToDelete + + for (NSUInteger i = firstIndexToDelete; i < sortedLogFileInfos.count; i++) { + DDLogFileInfo *logFileInfo = sortedLogFileInfos[i]; + + NSError *error = nil; + BOOL success = [[NSFileManager defaultManager] removeItemAtPath:logFileInfo.filePath error:&error]; + if (success) { + NSLogInfo(@"DDLogFileManagerDefault: Deleting file: %@", logFileInfo.fileName); + } else { + NSLogError(@"DDLogFileManagerDefault: Error deleting file %@", error); + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Log Files +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Returns the path to the default logs directory. + * If the logs directory doesn't exist, this method automatically creates it. + **/ +- (NSString *)defaultLogsDirectory { + +#if TARGET_OS_IPHONE + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + NSString *baseDir = paths.firstObject; + NSString *logsDirectory = [baseDir stringByAppendingPathComponent:@"Logs"]; +#else + NSString *appName = [[NSProcessInfo processInfo] processName]; + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); + NSString *basePath = ([paths count] > 0) ? paths[0] : NSTemporaryDirectory(); + NSString *logsDirectory = [[basePath stringByAppendingPathComponent:@"Logs"] stringByAppendingPathComponent:appName]; +#endif + + return logsDirectory; +} + +- (NSString *)logsDirectory { + // We could do this check once, during initialization, and not bother again. + // But this way the code continues to work if the directory gets deleted while the code is running. + + NSAssert(_logsDirectory.length > 0, @"Directory must be set."); + + NSError *err = nil; + BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:_logsDirectory + withIntermediateDirectories:YES + attributes:nil + error:&err]; + if (success == NO) { + NSLogError(@"DDFileLogManagerDefault: Error creating logsDirectory: %@", err); + } + + return _logsDirectory; +} + +- (BOOL)isLogFile:(NSString *)fileName { + NSString *appName = [self applicationName]; + + // We need to add a space to the name as otherwise we could match applications that have the name prefix. + BOOL hasProperPrefix = [fileName hasPrefix:[appName stringByAppendingString:@" "]]; + BOOL hasProperSuffix = [fileName hasSuffix:@".log"]; + + return (hasProperPrefix && hasProperSuffix); +} + +// if you change formatter, then change sortedLogFileInfos method also accordingly +- (NSDateFormatter *)logFileDateFormatter { + return _fileDateFormatter; +} + +- (NSArray *)unsortedLogFilePaths { + NSString *logsDirectory = [self logsDirectory]; + NSArray *fileNames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:logsDirectory error:nil]; + + NSMutableArray *unsortedLogFilePaths = [NSMutableArray arrayWithCapacity:[fileNames count]]; + + for (NSString *fileName in fileNames) { + // Filter out any files that aren't log files. (Just for extra safety) + +#if TARGET_IPHONE_SIMULATOR + // This is only used on the iPhone simulator for backward compatibility reason. + // + // In case of iPhone simulator there can be 'archived' extension. isLogFile: + // method knows nothing about it. Thus removing it for this method. + NSString *theFileName = [fileName stringByReplacingOccurrencesOfString:@".archived" + withString:@""]; + + if ([self isLogFile:theFileName]) +#else + + if ([self isLogFile:fileName]) +#endif + { + NSString *filePath = [logsDirectory stringByAppendingPathComponent:fileName]; + + [unsortedLogFilePaths addObject:filePath]; + } + } + + return unsortedLogFilePaths; +} + +- (NSArray *)unsortedLogFileNames { + NSArray *unsortedLogFilePaths = [self unsortedLogFilePaths]; + + NSMutableArray *unsortedLogFileNames = [NSMutableArray arrayWithCapacity:[unsortedLogFilePaths count]]; + + for (NSString *filePath in unsortedLogFilePaths) { + [unsortedLogFileNames addObject:[filePath lastPathComponent]]; + } + + return unsortedLogFileNames; +} + +- (NSArray *)unsortedLogFileInfos { + NSArray *unsortedLogFilePaths = [self unsortedLogFilePaths]; + + NSMutableArray *unsortedLogFileInfos = [NSMutableArray arrayWithCapacity:[unsortedLogFilePaths count]]; + + for (NSString *filePath in unsortedLogFilePaths) { + DDLogFileInfo *logFileInfo = [[DDLogFileInfo alloc] initWithFilePath:filePath]; + + [unsortedLogFileInfos addObject:logFileInfo]; + } + + return unsortedLogFileInfos; +} + +- (NSArray *)sortedLogFilePaths { + NSArray *sortedLogFileInfos = [self sortedLogFileInfos]; + + NSMutableArray *sortedLogFilePaths = [NSMutableArray arrayWithCapacity:[sortedLogFileInfos count]]; + + for (DDLogFileInfo *logFileInfo in sortedLogFileInfos) { + [sortedLogFilePaths addObject:[logFileInfo filePath]]; + } + + return sortedLogFilePaths; +} + +- (NSArray *)sortedLogFileNames { + NSArray *sortedLogFileInfos = [self sortedLogFileInfos]; + + NSMutableArray *sortedLogFileNames = [NSMutableArray arrayWithCapacity:[sortedLogFileInfos count]]; + + for (DDLogFileInfo *logFileInfo in sortedLogFileInfos) { + [sortedLogFileNames addObject:[logFileInfo fileName]]; + } + + return sortedLogFileNames; +} + +- (NSArray *)sortedLogFileInfos { + return [[self unsortedLogFileInfos] sortedArrayUsingComparator:^NSComparisonResult(DDLogFileInfo *obj1, + DDLogFileInfo *obj2) { + NSDate *date1 = [NSDate new]; + NSDate *date2 = [NSDate new]; + + NSArray *arrayComponent = [[obj1 fileName] componentsSeparatedByString:@" "]; + if (arrayComponent.count > 0) { + NSString *stringDate = arrayComponent.lastObject; + stringDate = [stringDate stringByReplacingOccurrencesOfString:@".log" withString:@""]; +#if TARGET_IPHONE_SIMULATOR + // This is only used on the iPhone simulator for backward compatibility reason. + stringDate = [stringDate stringByReplacingOccurrencesOfString:@".archived" withString:@""]; +#endif + date1 = [[self logFileDateFormatter] dateFromString:stringDate] ?: [obj1 creationDate]; + } + + arrayComponent = [[obj2 fileName] componentsSeparatedByString:@" "]; + if (arrayComponent.count > 0) { + NSString *stringDate = arrayComponent.lastObject; + stringDate = [stringDate stringByReplacingOccurrencesOfString:@".log" withString:@""]; +#if TARGET_IPHONE_SIMULATOR + // This is only used on the iPhone simulator for backward compatibility reason. + stringDate = [stringDate stringByReplacingOccurrencesOfString:@".archived" withString:@""]; +#endif + date2 = [[self logFileDateFormatter] dateFromString:stringDate] ?: [obj2 creationDate]; + } + + return [date2 compare:date1 ?: [NSDate new]]; + }]; + +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Creation +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//if you change newLogFileName , then change isLogFile method also accordingly +- (NSString *)newLogFileName { + NSString *appName = [self applicationName]; + + NSDateFormatter *dateFormatter = [self logFileDateFormatter]; + NSString *formattedDate = [dateFormatter stringFromDate:[NSDate date]]; + + return [NSString stringWithFormat:@"%@ %@.log", appName, formattedDate]; +} + +- (nullable NSString *)logFileHeader { + return nil; +} + +- (NSData *)logFileHeaderData { + NSString *fileHeaderStr = [self logFileHeader]; + + if (fileHeaderStr.length == 0) { + return nil; + } + + if (![fileHeaderStr hasSuffix:@"\n"]) { + fileHeaderStr = [fileHeaderStr stringByAppendingString:@"\n"]; + } + + return [fileHeaderStr dataUsingEncoding:NSUTF8StringEncoding]; +} + +- (NSString *)createNewLogFileWithError:(NSError *__autoreleasing _Nullable *)error { + static NSUInteger MAX_ALLOWED_ERROR = 5; + + NSString *fileName = [self newLogFileName]; + NSString *logsDirectory = [self logsDirectory]; + NSData *fileHeader = [self logFileHeaderData]; + if (fileHeader == nil) { + fileHeader = [NSData new]; + } + + NSUInteger attempt = 1; + NSUInteger criticalErrors = 0; + NSError *lastCriticalError; + + do { + if (criticalErrors >= MAX_ALLOWED_ERROR) { + NSLogError(@"DDLogFileManagerDefault: Bailing file creation, encountered %ld errors.", + (unsigned long)criticalErrors); + *error = lastCriticalError; + return nil; + } + + NSString *actualFileName = fileName; + if (attempt > 1) { + NSString *extension = [actualFileName pathExtension]; + + actualFileName = [actualFileName stringByDeletingPathExtension]; + actualFileName = [actualFileName stringByAppendingFormat:@" %lu", (unsigned long)attempt]; + + if (extension.length) { + actualFileName = [actualFileName stringByAppendingPathExtension:extension]; + } + } + + NSString *filePath = [logsDirectory stringByAppendingPathComponent:actualFileName]; + + NSError *currentError = nil; + BOOL success = [fileHeader writeToFile:filePath options:NSDataWritingAtomic error:¤tError]; + +#if TARGET_OS_IPHONE + if (success) { + // When creating log file on iOS we're setting NSFileProtectionKey attribute to NSFileProtectionCompleteUnlessOpen. + // + // But in case if app is able to launch from background we need to have an ability to open log file any time we + // want (even if device is locked). Thats why that attribute have to be changed to + // NSFileProtectionCompleteUntilFirstUserAuthentication. + NSDictionary *attributes = @{NSFileProtectionKey: [self logFileProtection]}; + success = [[NSFileManager defaultManager] setAttributes:attributes + ofItemAtPath:filePath + error:¤tError]; + } +#endif + + if (success) { + NSLogVerbose(@"DDLogFileManagerDefault: Created new log file: %@", actualFileName); + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + // Since we just created a new log file, we may need to delete some old log files + [self deleteOldLogFiles]; + }); + return filePath; + } else if (currentError.code == NSFileWriteFileExistsError) { + attempt++; + continue; + } else { + NSLogError(@"DDLogFileManagerDefault: Critical error while creating log file: %@", currentError); + criticalErrors++; + lastCriticalError = currentError; + continue; + } + + return filePath; + } while (YES); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Utility +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (NSString *)applicationName { + static NSString *_appName; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + _appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"]; + + if (_appName.length == 0) { + _appName = [[NSProcessInfo processInfo] processName]; + } + + if (_appName.length == 0) { + _appName = @""; + } + }); + + return _appName; +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface DDLogFileFormatterDefault () { + NSDateFormatter *_dateFormatter; +} + +@end + +@implementation DDLogFileFormatterDefault + +- (instancetype)init { + return [self initWithDateFormatter:nil]; +} + +- (instancetype)initWithDateFormatter:(nullable NSDateFormatter *)aDateFormatter { + if ((self = [super init])) { + if (aDateFormatter) { + _dateFormatter = aDateFormatter; + } else { + _dateFormatter = [[NSDateFormatter alloc] init]; + [_dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; // 10.4+ style + [_dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; + [_dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; + [_dateFormatter setDateFormat:@"yyyy/MM/dd HH:mm:ss:SSS"]; + } + } + + return self; +} + +- (NSString *)formatLogMessage:(DDLogMessage *)logMessage { + NSString *dateAndTime = [_dateFormatter stringFromDate:logMessage->_timestamp]; + + return [NSString stringWithFormat:@"%@ %@", dateAndTime, logMessage->_message]; +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface DDFileLogger () { + id _logFileManager; + + DDLogFileInfo *_currentLogFileInfo; + NSFileHandle *_currentLogFileHandle; + + dispatch_source_t _currentLogFileVnode; + + NSTimeInterval _rollingFrequency; + dispatch_source_t _rollingTimer; + + unsigned long long _maximumFileSize; + + dispatch_queue_t _completionQueue; +} + +@end + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wincomplete-implementation" +@implementation DDFileLogger +#pragma clang diagnostic pop + +- (instancetype)init { + DDLogFileManagerDefault *defaultLogFileManager = [[DDLogFileManagerDefault alloc] init]; + return [self initWithLogFileManager:defaultLogFileManager completionQueue:nil]; +} + +- (instancetype)initWithLogFileManager:(id)logFileManager { + return [self initWithLogFileManager:logFileManager completionQueue:nil]; +} + +- (instancetype)initWithLogFileManager:(id )aLogFileManager + completionQueue:(nullable dispatch_queue_t)dispatchQueue { + if ((self = [super init])) { + _completionQueue = dispatchQueue ?: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + + _maximumFileSize = kDDDefaultLogMaxFileSize; + _rollingFrequency = kDDDefaultLogRollingFrequency; + _automaticallyAppendNewlineForCustomFormatters = YES; + + _logFileManager = aLogFileManager; + _logFormatter = [DDLogFileFormatterDefault new]; + } + + return self; +} + +- (void)lt_cleanup { + NSAssert([self isOnInternalLoggerQueue], @"lt_ methods should be on logger queue."); + + [_currentLogFileHandle synchronizeFile]; + [_currentLogFileHandle closeFile]; + + if (_currentLogFileVnode) { + dispatch_source_cancel(_currentLogFileVnode); + _currentLogFileVnode = NULL; + } + + if (_rollingTimer) { + dispatch_source_cancel(_rollingTimer); + _rollingTimer = NULL; + } +} + +- (void)dealloc { + if (self.isOnInternalLoggerQueue) { + [self lt_cleanup]; + } else { + dispatch_sync(self.loggerQueue, ^{ + [self lt_cleanup]; + }); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Properties +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (unsigned long long)maximumFileSize { + __block unsigned long long result; + + dispatch_block_t block = ^{ + result = self->_maximumFileSize; + }; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the maximumFileSize variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, block); + }); + + return result; +} + +- (void)setMaximumFileSize:(unsigned long long)newMaximumFileSize { + dispatch_block_t block = ^{ + @autoreleasepool { + self->_maximumFileSize = newMaximumFileSize; + [self lt_maybeRollLogFileDueToSize]; + } + }; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the maximumFileSize variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); +} + +- (NSTimeInterval)rollingFrequency { + __block NSTimeInterval result; + + dispatch_block_t block = ^{ + result = self->_rollingFrequency; + }; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation should access the rollingFrequency variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, block); + }); + + return result; +} + +- (void)setRollingFrequency:(NSTimeInterval)newRollingFrequency { + dispatch_block_t block = ^{ + @autoreleasepool { + self->_rollingFrequency = newRollingFrequency; + [self lt_maybeRollLogFileDueToAge]; + } + }; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation should access the rollingFrequency variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark File Rolling +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)lt_scheduleTimerToRollLogFileDueToAge { + NSAssert([self isOnInternalLoggerQueue], @"lt_ methods should be on logger queue."); + + if (_rollingTimer) { + dispatch_source_cancel(_rollingTimer); + _rollingTimer = NULL; + } + + if (_currentLogFileInfo == nil || _rollingFrequency <= 0.0) { + return; + } + + NSDate *logFileCreationDate = [_currentLogFileInfo creationDate]; + NSTimeInterval frequency = MIN(_rollingFrequency, DBL_MAX - [logFileCreationDate timeIntervalSinceReferenceDate]); + NSDate *logFileRollingDate = [logFileCreationDate dateByAddingTimeInterval:frequency]; + + NSLogVerbose(@"DDFileLogger: scheduleTimerToRollLogFileDueToAge"); + NSLogVerbose(@"DDFileLogger: logFileCreationDate : %@", logFileCreationDate); + NSLogVerbose(@"DDFileLogger: actual rollingFrequency: %f", frequency); + NSLogVerbose(@"DDFileLogger: logFileRollingDate : %@", logFileRollingDate); + + _rollingTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _loggerQueue); + + __weak __auto_type weakSelf = self; + dispatch_source_set_event_handler(_rollingTimer, ^{ @autoreleasepool { + [weakSelf lt_maybeRollLogFileDueToAge]; + } }); + + #if !OS_OBJECT_USE_OBJC + dispatch_source_t theRollingTimer = _rollingTimer; + dispatch_source_set_cancel_handler(_rollingTimer, ^{ + dispatch_release(theRollingTimer); + }); + #endif + + static NSTimeInterval const kDDMaxTimerDelay = LLONG_MAX / NSEC_PER_SEC; + int64_t delay = (int64_t)(MIN([logFileRollingDate timeIntervalSinceNow], kDDMaxTimerDelay) * (NSTimeInterval) NSEC_PER_SEC); + dispatch_time_t fireTime = dispatch_time(DISPATCH_TIME_NOW, delay); + + dispatch_source_set_timer(_rollingTimer, fireTime, DISPATCH_TIME_FOREVER, (uint64_t)kDDRollingLeeway * NSEC_PER_SEC); + + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) + dispatch_activate(_rollingTimer); + else + dispatch_resume(_rollingTimer); +} + +- (void)rollLogFile { + [self rollLogFileWithCompletionBlock:nil]; +} + +- (void)rollLogFileWithCompletionBlock:(nullable void (^)(void))completionBlock { + // This method is public. + // We need to execute the rolling on our logging thread/queue. + + dispatch_block_t block = ^{ + @autoreleasepool { + [self lt_rollLogFileNow]; + + if (completionBlock) { + dispatch_async(self->_completionQueue, ^{ + completionBlock(); + }); + } + } + }; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (void)lt_rollLogFileNow { + NSAssert([self isOnInternalLoggerQueue], @"lt_ methods should be on logger queue."); + NSLogVerbose(@"DDFileLogger: rollLogFileNow"); + + if (_currentLogFileHandle == nil) { + return; + } + + [_currentLogFileHandle synchronizeFile]; + [_currentLogFileHandle closeFile]; + _currentLogFileHandle = nil; + + _currentLogFileInfo.isArchived = YES; + + const BOOL logFileManagerRespondsToNewArchiveSelector = [_logFileManager respondsToSelector:@selector(didArchiveLogFile:wasRolled:)]; + const BOOL logFileManagerRespondsToSelector = (logFileManagerRespondsToNewArchiveSelector + || [_logFileManager respondsToSelector:@selector(didRollAndArchiveLogFile:)]); + NSString *archivedFilePath = (logFileManagerRespondsToSelector) ? [_currentLogFileInfo.filePath copy] : nil; + _currentLogFileInfo = nil; + + if (logFileManagerRespondsToSelector) { + dispatch_block_t block; + if (logFileManagerRespondsToNewArchiveSelector) { + block = ^{ + [self->_logFileManager didArchiveLogFile:archivedFilePath wasRolled:YES]; + }; + } else { + block = ^{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [self->_logFileManager didRollAndArchiveLogFile:archivedFilePath]; +#pragma clang diagnostic pop + }; + } + dispatch_async(_completionQueue, block); + } + + if (_currentLogFileVnode) { + dispatch_source_cancel(_currentLogFileVnode); + _currentLogFileVnode = nil; + } + + if (_rollingTimer) { + dispatch_source_cancel(_rollingTimer); + _rollingTimer = nil; + } +} + +- (void)lt_maybeRollLogFileDueToAge { + NSAssert([self isOnInternalLoggerQueue], @"lt_ methods should be on logger queue."); + + if (_rollingFrequency > 0.0 && (_currentLogFileInfo.age + kDDRollingLeeway) >= _rollingFrequency) { + NSLogVerbose(@"DDFileLogger: Rolling log file due to age..."); + [self lt_rollLogFileNow]; + } else { + [self lt_scheduleTimerToRollLogFileDueToAge]; + } +} + +- (void)lt_maybeRollLogFileDueToSize { + NSAssert([self isOnInternalLoggerQueue], @"lt_ methods should be on logger queue."); + + // This method is called from logMessage. + // Keep it FAST. + + // Note: Use direct access to maximumFileSize variable. + // We specifically wrote our own getter/setter method to allow us to do this (for performance reasons). + + if (_maximumFileSize > 0) { + unsigned long long fileSize = [_currentLogFileHandle offsetInFile]; + + if (fileSize >= _maximumFileSize) { + NSLogVerbose(@"DDFileLogger: Rolling log file due to size (%qu)...", fileSize); + + [self lt_rollLogFileNow]; + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark File Logging +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)lt_shouldLogFileBeArchived:(DDLogFileInfo *)mostRecentLogFileInfo { + NSAssert([self isOnInternalLoggerQueue], @"lt_ methods should be on logger queue."); + + if (mostRecentLogFileInfo.isArchived) { + return NO; + } else if ([self shouldArchiveRecentLogFileInfo:mostRecentLogFileInfo]) { + return YES; + } else if (_maximumFileSize > 0 && mostRecentLogFileInfo.fileSize >= _maximumFileSize) { + return YES; + } else if (_rollingFrequency > 0.0 && mostRecentLogFileInfo.age >= _rollingFrequency) { + return YES; + } + +#if TARGET_OS_IPHONE + // When creating log file on iOS we're setting NSFileProtectionKey attribute to NSFileProtectionCompleteUnlessOpen. + // + // But in case if app is able to launch from background we need to have an ability to open log file any time we + // want (even if device is locked). Thats why that attribute have to be changed to + // NSFileProtectionCompleteUntilFirstUserAuthentication. + // + // If previous log was created when app wasn't running in background, but now it is - we archive it and create + // a new one. + // + // If user has overwritten to NSFileProtectionNone there is no neeed to create a new one. + if (doesAppRunInBackground()) { + NSFileProtectionType key = mostRecentLogFileInfo.fileAttributes[NSFileProtectionKey]; + BOOL isUntilFirstAuth = [key isEqualToString:NSFileProtectionCompleteUntilFirstUserAuthentication]; + BOOL isNone = [key isEqualToString:NSFileProtectionNone]; + + if (key != nil && !isUntilFirstAuth && !isNone) { + return YES; + } + } +#endif + + return NO; +} + +/** + * Returns the log file that should be used. + * If there is an existing log file that is suitable, within the + * constraints of maximumFileSize and rollingFrequency, then it is returned. + * + * Otherwise a new file is created and returned. + **/ +- (DDLogFileInfo *)currentLogFileInfo { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + // Do not access this method on any Lumberjack queue, will deadlock. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + __block DDLogFileInfo *info = nil; + dispatch_block_t block = ^{ + info = [self lt_currentLogFileInfo]; + }; + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self->_loggerQueue, block); + }); + + return info; +} + +- (DDLogFileInfo *)lt_currentLogFileInfo { + NSAssert([self isOnInternalLoggerQueue], @"lt_ methods should be on logger queue."); + + // Get the current log file info ivar (might be nil). + DDLogFileInfo *newCurrentLogFile = _currentLogFileInfo; + + // Check if we're resuming and if so, get the first of the sorted log file infos. + BOOL isResuming = newCurrentLogFile == nil; + if (isResuming) { + NSArray *sortedLogFileInfos = [_logFileManager sortedLogFileInfos]; + newCurrentLogFile = sortedLogFileInfos.firstObject; + } + + // Check if the file we've found is still valid. Otherwise create a new one. + if (newCurrentLogFile != nil && [self lt_shouldUseLogFile:newCurrentLogFile isResuming:isResuming]) { + if (isResuming) { + NSLogVerbose(@"DDFileLogger: Resuming logging with file %@", newCurrentLogFile.fileName); + } + _currentLogFileInfo = newCurrentLogFile; + } else { + NSString *currentLogFilePath; + if ([_logFileManager respondsToSelector:@selector(createNewLogFileWithError:)]) { + __autoreleasing NSError *error; + currentLogFilePath = [_logFileManager createNewLogFileWithError:&error]; + if (!currentLogFilePath) { + NSLogError(@"DDFileLogger: Failed to create new log file: %@", error); + } + } else { + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + NSAssert([_logFileManager respondsToSelector:@selector(createNewLogFile)], + @"Invalid log file manager! Responds neither to `-createNewLogFileWithError:` nor `-createNewLogFile`!"); + currentLogFilePath = [_logFileManager createNewLogFile]; + #pragma clang diagnostic pop + } + // Use static factory method here, since it checks for nil (and is unavailable to Swift). + _currentLogFileInfo = [DDLogFileInfo logFileWithPath:currentLogFilePath]; + } + + return _currentLogFileInfo; +} + +- (BOOL)lt_shouldUseLogFile:(nonnull DDLogFileInfo *)logFileInfo isResuming:(BOOL)isResuming { + NSAssert([self isOnInternalLoggerQueue], @"lt_ methods should be on logger queue."); + NSParameterAssert(logFileInfo); + + // Check if the log file is archived. We must not use archived log files. + if (logFileInfo.isArchived) { + return NO; + } + + // If we're resuming, we need to check if the log file is allowed for reuse or needs to be archived. + if (isResuming && (_doNotReuseLogFiles || [self lt_shouldLogFileBeArchived:logFileInfo])) { + logFileInfo.isArchived = YES; + + const BOOL logFileManagerRespondsToNewArchiveSelector = [_logFileManager respondsToSelector:@selector(didArchiveLogFile:wasRolled:)]; + if (logFileManagerRespondsToNewArchiveSelector || [_logFileManager respondsToSelector:@selector(didArchiveLogFile:)]) { + NSString *archivedFilePath = [logFileInfo.filePath copy]; + dispatch_block_t block; + if (logFileManagerRespondsToNewArchiveSelector) { + block = ^{ + [self->_logFileManager didArchiveLogFile:archivedFilePath wasRolled:NO]; + }; + } else { + block = ^{ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + [self->_logFileManager didArchiveLogFile:archivedFilePath]; + #pragma clang diagnostic pop + }; + } + dispatch_async(_completionQueue, block); + } + + return NO; + } + + // All checks have passed. It's valid. + return YES; +} + +- (void)lt_monitorCurrentLogFileForExternalChanges { + NSAssert([self isOnInternalLoggerQueue], @"lt_ methods should be on logger queue."); + NSAssert(_currentLogFileHandle, @"Can not monitor without handle."); + + dispatch_source_vnode_flags_t flags = DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE; + _currentLogFileVnode = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, + (uintptr_t)[_currentLogFileHandle fileDescriptor], + flags, + _loggerQueue); + + __weak __auto_type weakSelf = self; + dispatch_source_set_event_handler(_currentLogFileVnode, ^{ @autoreleasepool { + NSLogInfo(@"DDFileLogger: Current logfile was moved. Rolling it and creating a new one"); + [weakSelf lt_rollLogFileNow]; + } }); + +#if !OS_OBJECT_USE_OBJC + dispatch_source_t vnode = _currentLogFileVnode; + dispatch_source_set_cancel_handler(_currentLogFileVnode, ^{ + dispatch_release(vnode); + }); +#endif + + if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)) + dispatch_activate(_currentLogFileVnode); + else + dispatch_resume(_currentLogFileVnode); +} + +- (NSFileHandle *)lt_currentLogFileHandle { + NSAssert([self isOnInternalLoggerQueue], @"lt_ methods should be on logger queue."); + + if (!_currentLogFileHandle) { + NSString *logFilePath = [[self lt_currentLogFileInfo] filePath]; + _currentLogFileHandle = [NSFileHandle fileHandleForWritingAtPath:logFilePath]; + [_currentLogFileHandle seekToEndOfFile]; + + if (_currentLogFileHandle) { + [self lt_scheduleTimerToRollLogFileDueToAge]; + [self lt_monitorCurrentLogFileForExternalChanges]; + } + } + + return _currentLogFileHandle; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark DDLogger Protocol +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static int exception_count = 0; + +- (void)logMessage:(DDLogMessage *)logMessage { + // Don't need to check for isOnInternalLoggerQueue, -lt_dataForMessage: will do it for us. + NSData *data = [self lt_dataForMessage:logMessage]; + + if (data.length == 0) { + return; + } + + [self lt_logData:data]; +} + +- (void)willLogMessage:(DDLogFileInfo *)logFileInfo { + +} + +- (void)didLogMessage:(DDLogFileInfo *)logFileInfo { + [self lt_maybeRollLogFileDueToSize]; +} + +- (BOOL)shouldArchiveRecentLogFileInfo:(__unused DDLogFileInfo *)recentLogFileInfo { + return NO; +} + +- (void)willRemoveLogger { + [self lt_rollLogFileNow]; +} + +- (void)flush { + // This method is public. + // We need to execute the rolling on our logging thread/queue. + + dispatch_block_t block = ^{ + @autoreleasepool { + [self lt_flush]; + } + }; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, block); + }); + } +} + +- (void)lt_flush { + NSAssert([self isOnInternalLoggerQueue], @"flush should only be executed on internal queue."); + [_currentLogFileHandle synchronizeFile]; +} + +- (DDLoggerName)loggerName { + return DDLoggerNameFile; +} + +@end + +@implementation DDFileLogger (Internal) + +- (void)logData:(NSData *)data { + // This method is public. + // We need to execute the rolling on our logging thread/queue. + + dispatch_block_t block = ^{ + @autoreleasepool { + [self lt_logData:data]; + } + }; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, block); + }); + } +} + +- (void)dummyMethod {} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { + if (aSelector == @selector(willLogMessage) || aSelector == @selector(didLogMessage)) { + // Ignore calls to deprecated methods. + return [self methodSignatureForSelector:@selector(dummyMethod)]; + } + + return [super methodSignatureForSelector:aSelector]; +} + +- (void)forwardInvocation:(NSInvocation *)anInvocation { + if (anInvocation.selector != @selector(dummyMethod)) { + [super forwardInvocation:anInvocation]; + } +} + +- (void)lt_logData:(NSData *)data { + static BOOL implementsDeprecatedWillLog = NO; + static BOOL implementsDeprecatedDidLog = NO; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + implementsDeprecatedWillLog = [self respondsToSelector:@selector(willLogMessage)]; + implementsDeprecatedDidLog = [self respondsToSelector:@selector(didLogMessage)]; + }); + + NSAssert([self isOnInternalLoggerQueue], @"logMessage should only be executed on internal queue."); + + if (data.length == 0) { + return; + } + + @try { + if (implementsDeprecatedWillLog) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [self willLogMessage]; +#pragma clang diagnostic pop + } else { + [self willLogMessage:_currentLogFileInfo]; + } + + NSFileHandle *handle = [self lt_currentLogFileHandle]; + [handle seekToEndOfFile]; + [handle writeData:data]; + + if (implementsDeprecatedDidLog) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [self didLogMessage]; +#pragma clang diagnostic pop + } else { + [self didLogMessage:_currentLogFileInfo]; + } + + } @catch (NSException *exception) { + exception_count++; + + if (exception_count <= 10) { + NSLogError(@"DDFileLogger.logMessage: %@", exception); + + if (exception_count == 10) { + NSLogError(@"DDFileLogger.logMessage: Too many exceptions -- will not log any more of them."); + } + } + } +} + +- (NSData *)lt_dataForMessage:(DDLogMessage *)logMessage { + NSAssert([self isOnInternalLoggerQueue], @"logMessage should only be executed on internal queue."); + + NSString *message = logMessage->_message; + BOOL isFormatted = NO; + + if (_logFormatter != nil) { + message = [_logFormatter formatLogMessage:logMessage]; + isFormatted = message != logMessage->_message; + } + + if (message.length == 0) { + return nil; + } + + BOOL shouldFormat = !isFormatted || _automaticallyAppendNewlineForCustomFormatters; + if (shouldFormat && ![message hasSuffix:@"\n"]) { + message = [message stringByAppendingString:@"\n"]; + } + + return [message dataUsingEncoding:NSUTF8StringEncoding]; +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static NSString * const kDDXAttrArchivedName = @"lumberjack.log.archived"; + +@interface DDLogFileInfo () { + __strong NSString *_filePath; + __strong NSString *_fileName; + + __strong NSDictionary *_fileAttributes; + + __strong NSDate *_creationDate; + __strong NSDate *_modificationDate; + + unsigned long long _fileSize; +} + +#if TARGET_IPHONE_SIMULATOR + +// Old implementation of extended attributes on the simulator. + +- (BOOL)_hasExtensionAttributeWithName:(NSString *)attrName; +- (void)_removeExtensionAttributeWithName:(NSString *)attrName; + +#endif + +@end + + +@implementation DDLogFileInfo + +@synthesize filePath; + +@dynamic fileName; +@dynamic fileAttributes; +@dynamic creationDate; +@dynamic modificationDate; +@dynamic fileSize; +@dynamic age; + +@dynamic isArchived; + +#pragma mark Lifecycle + ++ (instancetype)logFileWithPath:(NSString *)aFilePath { + if (!aFilePath) return nil; + return [[self alloc] initWithFilePath:aFilePath]; +} + +- (instancetype)initWithFilePath:(NSString *)aFilePath { + NSParameterAssert(aFilePath); + if ((self = [super init])) { + filePath = [aFilePath copy]; + } + + return self; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Standard Info +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (NSDictionary *)fileAttributes { + if (_fileAttributes == nil && filePath != nil) { + NSError *error = nil; + _fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error]; + + if (error) { + NSLogError(@"DDLogFileInfo: Failed to read file attributes: %@", error); + } + } + + return _fileAttributes ?: @{}; +} + +- (NSString *)fileName { + if (_fileName == nil) { + _fileName = [filePath lastPathComponent]; + } + + return _fileName; +} + +- (NSDate *)modificationDate { + if (_modificationDate == nil) { + _modificationDate = self.fileAttributes[NSFileModificationDate]; + } + + return _modificationDate; +} + +- (NSDate *)creationDate { + if (_creationDate == nil) { + _creationDate = self.fileAttributes[NSFileCreationDate]; + } + + return _creationDate; +} + +- (unsigned long long)fileSize { + if (_fileSize == 0) { + _fileSize = [self.fileAttributes[NSFileSize] unsignedLongLongValue]; + } + + return _fileSize; +} + +- (NSTimeInterval)age { + return -[[self creationDate] timeIntervalSinceNow]; +} + +- (NSString *)description { + return [@{ @"filePath": self.filePath ? : @"", + @"fileName": self.fileName ? : @"", + @"fileAttributes": self.fileAttributes ? : @"", + @"creationDate": self.creationDate ? : @"", + @"modificationDate": self.modificationDate ? : @"", + @"fileSize": @(self.fileSize), + @"age": @(self.age), + @"isArchived": @(self.isArchived) } description]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Archiving +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)isArchived { + return [self hasExtendedAttributeWithName:kDDXAttrArchivedName]; +} + +- (void)setIsArchived:(BOOL)flag { + if (flag) { + [self addExtendedAttributeWithName:kDDXAttrArchivedName]; + } else { + [self removeExtendedAttributeWithName:kDDXAttrArchivedName]; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Changes +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)reset { + _fileName = nil; + _fileAttributes = nil; + _creationDate = nil; + _modificationDate = nil; +} + +- (void)renameFile:(NSString *)newFileName { + // This method is only used on the iPhone simulator, where normal extended attributes are broken. + // See full explanation in the header file. + + if (![newFileName isEqualToString:[self fileName]]) { + NSFileManager* fileManager = [NSFileManager defaultManager]; + NSString *fileDir = [filePath stringByDeletingLastPathComponent]; + NSString *newFilePath = [fileDir stringByAppendingPathComponent:newFileName]; + + // We only want to assert when we're not using the simulator, as we're "archiving" a log file with this method in the sim + // (in which case the file might not exist anymore and neither does it parent folder). +#if defined(DEBUG) && (!defined(TARGET_IPHONE_SIMULATOR) || !TARGET_IPHONE_SIMULATOR) + BOOL directory = NO; + [fileManager fileExistsAtPath:fileDir isDirectory:&directory]; + NSAssert(directory, @"Containing directory must exist."); +#endif + + NSError *error = nil; + + BOOL success = [fileManager removeItemAtPath:newFilePath error:&error]; + if (!success && error.code != NSFileNoSuchFileError) { + NSLogError(@"DDLogFileInfo: Error deleting archive (%@): %@", self.fileName, error); + } + + success = [fileManager moveItemAtPath:filePath toPath:newFilePath error:&error]; + + // When a log file is deleted, moved or renamed on the simulator, we attempt to rename it as a + // result of "archiving" it, but since the file doesn't exist anymore, needless error logs are printed + // We therefore ignore this error, and assert that the directory we are copying into exists (which + // is the only other case where this error code can come up). +#if TARGET_IPHONE_SIMULATOR + if (!success && error.code != NSFileNoSuchFileError) +#else + if (!success) +#endif + { + NSLogError(@"DDLogFileInfo: Error renaming file (%@): %@", self.fileName, error); + } + + filePath = newFilePath; + [self reset]; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Attribute Management +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#if TARGET_IPHONE_SIMULATOR + +// Old implementation of extended attributes on the simulator. + +// Extended attributes were not working properly on the simulator +// due to misuse of setxattr() function. +// Now that this is fixed in the new implementation, we want to keep +// backward compatibility with previous simulator installations. + +static NSString * const kDDExtensionSeparator = @"."; + +static NSString *_xattrToExtensionName(NSString *attrName) { + static NSDictionary* _xattrToExtensionNameMap; + static dispatch_once_t _token; + dispatch_once(&_token, ^{ + _xattrToExtensionNameMap = @{ kDDXAttrArchivedName: @"archived" }; + }); + return [_xattrToExtensionNameMap objectForKey:attrName]; +} + +- (BOOL)_hasExtensionAttributeWithName:(NSString *)attrName { + // This method is only used on the iPhone simulator for backward compatibility reason. + + // Split the file name into components. File name may have various format, but generally + // structure is same: + // + // . and .archived. + // or + // and .archived + // + // So we want to search for the attrName in the components (ignoring the first array index). + + NSArray *components = [[self fileName] componentsSeparatedByString:kDDExtensionSeparator]; + + // Watch out for file names without an extension + + for (NSUInteger i = 1; i < components.count; i++) { + NSString *attr = components[i]; + + if ([attrName isEqualToString:attr]) { + return YES; + } + } + + return NO; +} + +- (void)_removeExtensionAttributeWithName:(NSString *)attrName { + // This method is only used on the iPhone simulator for backward compatibility reason. + + if ([attrName length] == 0) { + return; + } + + // Example: + // attrName = "archived" + // + // "mylog.archived.txt" -> "mylog.txt" + // "mylog.archived" -> "mylog" + + NSArray *components = [[self fileName] componentsSeparatedByString:kDDExtensionSeparator]; + + NSUInteger count = [components count]; + + NSUInteger estimatedNewLength = [[self fileName] length]; + NSMutableString *newFileName = [NSMutableString stringWithCapacity:estimatedNewLength]; + + if (count > 0) { + [newFileName appendString:components.firstObject]; + } + + BOOL found = NO; + + NSUInteger i; + + for (i = 1; i < count; i++) { + NSString *attr = components[i]; + + if ([attrName isEqualToString:attr]) { + found = YES; + } else { + [newFileName appendString:kDDExtensionSeparator]; + [newFileName appendString:attr]; + } + } + + if (found) { + [self renameFile:newFileName]; + } +} + +#endif /* if TARGET_IPHONE_SIMULATOR */ + +- (BOOL)hasExtendedAttributeWithName:(NSString *)attrName { + const char *path = [filePath fileSystemRepresentation]; + const char *name = [attrName UTF8String]; + BOOL hasExtendedAttribute = NO; + char buffer[1]; + + ssize_t result = getxattr(path, name, buffer, 1, 0, 0); + + // Fast path + if (result > 0 && buffer[0] == '\1') { + hasExtendedAttribute = YES; + } + // Maintain backward compatibility, but fix it for future checks + else if (result >= 0) { + hasExtendedAttribute = YES; + + [self addExtendedAttributeWithName:attrName]; + } +#if TARGET_IPHONE_SIMULATOR + else if ([self _hasExtensionAttributeWithName:_xattrToExtensionName(attrName)]) { + hasExtendedAttribute = YES; + + [self addExtendedAttributeWithName:attrName]; + } +#endif + + return hasExtendedAttribute; +} + +- (void)addExtendedAttributeWithName:(NSString *)attrName { + const char *path = [filePath fileSystemRepresentation]; + const char *name = [attrName UTF8String]; + + int result = setxattr(path, name, "\1", 1, 0, 0); + + if (result < 0) { + NSLogError(@"DDLogFileInfo: setxattr(%@, %@): error = %s", + attrName, + filePath, + strerror(errno)); + } +#if TARGET_IPHONE_SIMULATOR + else { + [self _removeExtensionAttributeWithName:_xattrToExtensionName(attrName)]; + } +#endif +} + +- (void)removeExtendedAttributeWithName:(NSString *)attrName { + const char *path = [filePath fileSystemRepresentation]; + const char *name = [attrName UTF8String]; + + int result = removexattr(path, name, 0); + + if (result < 0 && errno != ENOATTR) { + NSLogError(@"DDLogFileInfo: removexattr(%@, %@): error = %s", + attrName, + self.fileName, + strerror(errno)); + } + +#if TARGET_IPHONE_SIMULATOR + [self _removeExtensionAttributeWithName:_xattrToExtensionName(attrName)]; +#endif +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Comparisons +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (BOOL)isEqual:(id)object { + if ([object isKindOfClass:[self class]]) { + DDLogFileInfo *another = (DDLogFileInfo *)object; + + return [filePath isEqualToString:[another filePath]]; + } + + return NO; +} + +- (NSUInteger)hash { + return [filePath hash]; +} + +- (NSComparisonResult)reverseCompareByCreationDate:(DDLogFileInfo *)another { + __auto_type us = [self creationDate]; + __auto_type them = [another creationDate]; + return [them compare:us]; +} + +- (NSComparisonResult)reverseCompareByModificationDate:(DDLogFileInfo *)another { + __auto_type us = [self modificationDate]; + __auto_type them = [another modificationDate]; + return [them compare:us]; +} + +@end + +#if TARGET_OS_IPHONE +/** + * When creating log file on iOS we're setting NSFileProtectionKey attribute to NSFileProtectionCompleteUnlessOpen. + * + * But in case if app is able to launch from background we need to have an ability to open log file any time we + * want (even if device is locked). Thats why that attribute have to be changed to + * NSFileProtectionCompleteUntilFirstUserAuthentication. + */ +BOOL doesAppRunInBackground() { + BOOL answer = NO; + + NSArray *backgroundModes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"]; + + for (NSString *mode in backgroundModes) { + if (mode.length > 0) { + answer = YES; + break; + } + } + + return answer; +} + +#endif diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDLog.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDLog.m new file mode 100644 index 0000000..3253b50 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDLog.m @@ -0,0 +1,1337 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +#import +#import +#import + +#if TARGET_OS_IOS + #import + #import +#elif !defined(DD_CLI) && __has_include() + #import +#endif + +// Disable legacy macros +#ifndef DD_LEGACY_MACROS + #define DD_LEGACY_MACROS 0 +#endif + +#import + +// We probably shouldn't be using DDLog() statements within the DDLog implementation. +// But we still want to leave our log statements for any future debugging, +// and to allow other developers to trace the implementation (which is a great learning tool). +// +// So we use a primitive logging macro around NSLog. +// We maintain the NS prefix on the macros to be explicit about the fact that we're using NSLog. + +#ifndef DD_DEBUG + #define DD_DEBUG 0 +#endif + +#define NSLogDebug(frmt, ...) do{ if(DD_DEBUG) NSLog((frmt), ##__VA_ARGS__); } while(0) + +// Specifies the maximum queue size of the logging thread. +// +// Since most logging is asynchronous, its possible for rogue threads to flood the logging queue. +// That is, to issue an abundance of log statements faster than the logging thread can keep up. +// Typically such a scenario occurs when log statements are added haphazardly within large loops, +// but may also be possible if relatively slow loggers are being used. +// +// This property caps the queue size at a given number of outstanding log statements. +// If a thread attempts to issue a log statement when the queue is already maxed out, +// the issuing thread will block until the queue size drops below the max again. + +#ifndef DDLOG_MAX_QUEUE_SIZE + #define DDLOG_MAX_QUEUE_SIZE 1000 // Should not exceed INT32_MAX +#endif + +// The "global logging queue" refers to [DDLog loggingQueue]. +// It is the queue that all log statements go through. +// +// The logging queue sets a flag via dispatch_queue_set_specific using this key. +// We can check for this key via dispatch_get_specific() to see if we're on the "global logging queue". + +static void *const GlobalLoggingQueueIdentityKey = (void *)&GlobalLoggingQueueIdentityKey; + +@interface DDLoggerNode : NSObject +{ + // Direct accessors to be used only for performance + @public + id _logger; + DDLogLevel _level; + dispatch_queue_t _loggerQueue; +} + +@property (nonatomic, readonly) id logger; +@property (nonatomic, readonly) DDLogLevel level; +@property (nonatomic, readonly) dispatch_queue_t loggerQueue; + ++ (instancetype)nodeWithLogger:(id )logger + loggerQueue:(dispatch_queue_t)loggerQueue + level:(DDLogLevel)level; + +@end + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface DDLog () + +// An array used to manage all the individual loggers. +// The array is only modified on the loggingQueue/loggingThread. +@property (nonatomic, strong) NSMutableArray *_loggers; + +@end + +@implementation DDLog + +// All logging statements are added to the same queue to ensure FIFO operation. +static dispatch_queue_t _loggingQueue; + +// Individual loggers are executed concurrently per log statement. +// Each logger has it's own associated queue, and a dispatch group is used for synchronization. +static dispatch_group_t _loggingGroup; + +// In order to prevent to queue from growing infinitely large, +// a maximum size is enforced (DDLOG_MAX_QUEUE_SIZE). +static dispatch_semaphore_t _queueSemaphore; + +// Minor optimization for uniprocessor machines +static NSUInteger _numProcessors; + +/** + * Returns the singleton `DDLog`. + * The instance is used by `DDLog` class methods. + * + * @return The singleton `DDLog`. + */ ++ (instancetype)sharedInstance { + static id sharedInstance = nil; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[self alloc] init]; + }); + + return sharedInstance; +} + +/** + * The runtime sends initialize to each class in a program exactly one time just before the class, + * or any class that inherits from it, is sent its first message from within the program. (Thus the + * method may never be invoked if the class is not used.) The runtime sends the initialize message to + * classes in a thread-safe manner. Superclasses receive this message before their subclasses. + * + * This method may also be called directly, hence the safety mechanism. + **/ ++ (void)initialize { + static dispatch_once_t DDLogOnceToken; + + dispatch_once(&DDLogOnceToken, ^{ + NSLogDebug(@"DDLog: Using grand central dispatch"); + + _loggingQueue = dispatch_queue_create("cocoa.lumberjack", NULL); + _loggingGroup = dispatch_group_create(); + + void *nonNullValue = GlobalLoggingQueueIdentityKey; // Whatever, just not null + dispatch_queue_set_specific(_loggingQueue, GlobalLoggingQueueIdentityKey, nonNullValue, NULL); + + _queueSemaphore = dispatch_semaphore_create(DDLOG_MAX_QUEUE_SIZE); + + // Figure out how many processors are available. + // This may be used later for an optimization on uniprocessor machines. + + _numProcessors = MAX([NSProcessInfo processInfo].processorCount, (NSUInteger) 1); + + NSLogDebug(@"DDLog: numProcessors = %@", @(_numProcessors)); + }); +} + +/** + * The `DDLog` initializer. + * Static variables are set only once. + * + * @return An initialized `DDLog` instance. + */ +- (instancetype)init { + self = [super init]; + + if (self) { + self._loggers = [[NSMutableArray alloc] initWithCapacity:4]; + +#if TARGET_OS_IOS + NSString *notificationName = UIApplicationWillTerminateNotification; +#else + NSString *notificationName = nil; + + // On Command Line Tool apps AppKit may not be available +#if !defined(DD_CLI) && __has_include() + if (NSApp) { + notificationName = NSApplicationWillTerminateNotification; + } +#endif + + if (!notificationName) { + // If there is no NSApp -> we are running Command Line Tool app. + // In this case terminate notification wouldn't be fired, so we use workaround. + __weak __auto_type weakSelf = self; + atexit_b (^{ + [weakSelf applicationWillTerminate:nil]; + }); + } + +#endif /* if TARGET_OS_IOS */ + + if (notificationName) { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationWillTerminate:) + name:notificationName + object:nil]; + } + } + + return self; +} + +/** + * Provides access to the logging queue. + **/ ++ (dispatch_queue_t)loggingQueue { + return _loggingQueue; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Notifications +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)applicationWillTerminate:(NSNotification * __attribute__((unused)))notification { + [self flushLog]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Logger Management +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ++ (void)addLogger:(id )logger { + [self.sharedInstance addLogger:logger]; +} + +- (void)addLogger:(id )logger { + [self addLogger:logger withLevel:DDLogLevelAll]; // DDLogLevelAll has all bits set +} + ++ (void)addLogger:(id )logger withLevel:(DDLogLevel)level { + [self.sharedInstance addLogger:logger withLevel:level]; +} + +- (void)addLogger:(id )logger withLevel:(DDLogLevel)level { + if (!logger) { + return; + } + + dispatch_async(_loggingQueue, ^{ @autoreleasepool { + [self lt_addLogger:logger level:level]; + } }); +} + ++ (void)removeLogger:(id )logger { + [self.sharedInstance removeLogger:logger]; +} + +- (void)removeLogger:(id )logger { + if (!logger) { + return; + } + + dispatch_async(_loggingQueue, ^{ @autoreleasepool { + [self lt_removeLogger:logger]; + } }); +} + ++ (void)removeAllLoggers { + [self.sharedInstance removeAllLoggers]; +} + +- (void)removeAllLoggers { + dispatch_async(_loggingQueue, ^{ @autoreleasepool { + [self lt_removeAllLoggers]; + } }); +} + ++ (NSArray> *)allLoggers { + return [self.sharedInstance allLoggers]; +} + +- (NSArray> *)allLoggers { + __block NSArray *theLoggers; + + dispatch_sync(_loggingQueue, ^{ @autoreleasepool { + theLoggers = [self lt_allLoggers]; + } }); + + return theLoggers; +} + ++ (NSArray *)allLoggersWithLevel { + return [self.sharedInstance allLoggersWithLevel]; +} + +- (NSArray *)allLoggersWithLevel { + __block NSArray *theLoggersWithLevel; + + dispatch_sync(_loggingQueue, ^{ @autoreleasepool { + theLoggersWithLevel = [self lt_allLoggersWithLevel]; + } }); + + return theLoggersWithLevel; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - Master Logging +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)queueLogMessage:(DDLogMessage *)logMessage asynchronously:(BOOL)asyncFlag { + // We have a tricky situation here... + // + // In the common case, when the queueSize is below the maximumQueueSize, + // we want to simply enqueue the logMessage. And we want to do this as fast as possible, + // which means we don't want to block and we don't want to use any locks. + // + // However, if the queueSize gets too big, we want to block. + // But we have very strict requirements as to when we block, and how long we block. + // + // The following example should help illustrate our requirements: + // + // Imagine that the maximum queue size is configured to be 5, + // and that there are already 5 log messages queued. + // Let us call these 5 queued log messages A, B, C, D, and E. (A is next to be executed) + // + // Now if our thread issues a log statement (let us call the log message F), + // it should block before the message is added to the queue. + // Furthermore, it should be unblocked immediately after A has been unqueued. + // + // The requirements are strict in this manner so that we block only as long as necessary, + // and so that blocked threads are unblocked in the order in which they were blocked. + // + // Returning to our previous example, let us assume that log messages A through E are still queued. + // Our aforementioned thread is blocked attempting to queue log message F. + // Now assume we have another separate thread that attempts to issue log message G. + // It should block until log messages A and B have been unqueued. + + + // We are using a counting semaphore provided by GCD. + // The semaphore is initialized with our DDLOG_MAX_QUEUE_SIZE value. + // Every time we want to queue a log message we decrement this value. + // If the resulting value is less than zero, + // the semaphore function waits in FIFO order for a signal to occur before returning. + // + // A dispatch semaphore is an efficient implementation of a traditional counting semaphore. + // Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked. + // If the calling semaphore does not need to block, no kernel call is made. + + dispatch_block_t logBlock = ^{ + dispatch_semaphore_wait(_queueSemaphore, DISPATCH_TIME_FOREVER); + // We're now sure we won't overflow the queue. + // It is time to queue our log message. + @autoreleasepool { + [self lt_log:logMessage]; + } + }; + + if (asyncFlag) { + dispatch_async(_loggingQueue, logBlock); + } else if (dispatch_get_specific(GlobalLoggingQueueIdentityKey)) { + // We've logged an error message while on the logging queue... + logBlock(); + } else { + dispatch_sync(_loggingQueue, logBlock); + } +} + ++ (void)log:(BOOL)asynchronous + level:(DDLogLevel)level + flag:(DDLogFlag)flag + context:(NSInteger)context + file:(const char *)file + function:(const char *)function + line:(NSUInteger)line + tag:(id)tag + format:(NSString *)format, ... { + va_list args; + + if (format) { + va_start(args, format); + + NSString *message = [[NSString alloc] initWithFormat:format arguments:args]; + + va_end(args); + + va_start(args, format); + + [self log:asynchronous + message:message + level:level + flag:flag + context:context + file:file + function:function + line:line + tag:tag]; + + va_end(args); + } +} + +- (void)log:(BOOL)asynchronous + level:(DDLogLevel)level + flag:(DDLogFlag)flag + context:(NSInteger)context + file:(const char *)file + function:(const char *)function + line:(NSUInteger)line + tag:(id)tag + format:(NSString *)format, ... { + va_list args; + + if (format) { + va_start(args, format); + + NSString *message = [[NSString alloc] initWithFormat:format arguments:args]; + + va_end(args); + + va_start(args, format); + + [self log:asynchronous + message:message + level:level + flag:flag + context:context + file:file + function:function + line:line + tag:tag]; + + va_end(args); + } +} + ++ (void)log:(BOOL)asynchronous + level:(DDLogLevel)level + flag:(DDLogFlag)flag + context:(NSInteger)context + file:(const char *)file + function:(const char *)function + line:(NSUInteger)line + tag:(id)tag + format:(NSString *)format + args:(va_list)args { + [self.sharedInstance log:asynchronous level:level flag:flag context:context file:file function:function line:line tag:tag format:format args:args]; +} + +- (void)log:(BOOL)asynchronous + level:(DDLogLevel)level + flag:(DDLogFlag)flag + context:(NSInteger)context + file:(const char *)file + function:(const char *)function + line:(NSUInteger)line + tag:(id)tag + format:(NSString *)format + args:(va_list)args { + if (format) { + NSString *message = [[NSString alloc] initWithFormat:format arguments:args]; + [self log:asynchronous + message:message + level:level + flag:flag + context:context + file:file + function:function + line:line + tag:tag]; + } +} + ++ (void)log:(BOOL)asynchronous + message:(NSString *)message + level:(DDLogLevel)level + flag:(DDLogFlag)flag + context:(NSInteger)context + file:(const char *)file + function:(const char *)function + line:(NSUInteger)line + tag:(id)tag { + [self.sharedInstance log:asynchronous message:message level:level flag:flag context:context file:file function:function line:line tag:tag]; +} + +- (void)log:(BOOL)asynchronous + message:(NSString *)message + level:(DDLogLevel)level + flag:(DDLogFlag)flag + context:(NSInteger)context + file:(const char *)file + function:(const char *)function + line:(NSUInteger)line + tag:(id)tag { + DDLogMessage *logMessage = [[DDLogMessage alloc] initWithMessage:message + level:level + flag:flag + context:context + file:[NSString stringWithFormat:@"%s", file] + function:[NSString stringWithFormat:@"%s", function] + line:line + tag:tag + options:(DDLogMessageOptions)0 + timestamp:nil]; + + [self queueLogMessage:logMessage asynchronously:asynchronous]; +} + ++ (void)log:(BOOL)asynchronous message:(DDLogMessage *)logMessage { + [self.sharedInstance log:asynchronous message:logMessage]; +} + +- (void)log:(BOOL)asynchronous message:(DDLogMessage *)logMessage { + [self queueLogMessage:logMessage asynchronously:asynchronous]; +} + ++ (void)flushLog { + [self.sharedInstance flushLog]; +} + +- (void)flushLog { + dispatch_sync(_loggingQueue, ^{ @autoreleasepool { + [self lt_flush]; + } }); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Registered Dynamic Logging +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ++ (BOOL)isRegisteredClass:(Class)class { + SEL getterSel = @selector(ddLogLevel); + SEL setterSel = @selector(ddSetLogLevel:); + +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR + + // Issue #6 (GoogleCode) - Crashes on iOS 4.2.1 and iPhone 4 + // + // Crash caused by class_getClassMethod(2). + // + // "It's a bug with UIAccessibilitySafeCategory__NSObject so it didn't pop up until + // users had VoiceOver enabled [...]. I was able to work around it by searching the + // result of class_copyMethodList() instead of calling class_getClassMethod()" + + BOOL result = NO; + + unsigned int methodCount, i; + Method *methodList = class_copyMethodList(object_getClass(class), &methodCount); + + if (methodList != NULL) { + BOOL getterFound = NO; + BOOL setterFound = NO; + + for (i = 0; i < methodCount; ++i) { + SEL currentSel = method_getName(methodList[i]); + + if (currentSel == getterSel) { + getterFound = YES; + } else if (currentSel == setterSel) { + setterFound = YES; + } + + if (getterFound && setterFound) { + result = YES; + break; + } + } + + free(methodList); + } + + return result; + +#else /* if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR */ + + // Issue #24 (GitHub) - Crashing in in ARC+Simulator + // + // The method +[DDLog isRegisteredClass] will crash a project when using it with ARC + Simulator. + // For running in the Simulator, it needs to execute the non-iOS code. + + Method getter = class_getClassMethod(class, getterSel); + Method setter = class_getClassMethod(class, setterSel); + + if ((getter != NULL) && (setter != NULL)) { + return YES; + } + + return NO; + +#endif /* if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR */ +} + ++ (NSArray *)registeredClasses { + + // We're going to get the list of all registered classes. + // The Objective-C runtime library automatically registers all the classes defined in your source code. + // + // To do this we use the following method (documented in the Objective-C Runtime Reference): + // + // int objc_getClassList(Class *buffer, int bufferLen) + // + // We can pass (NULL, 0) to obtain the total number of + // registered class definitions without actually retrieving any class definitions. + // This allows us to allocate the minimum amount of memory needed for the application. + + NSUInteger numClasses = 0; + Class *classes = NULL; + + while (numClasses == 0) { + + numClasses = (NSUInteger)MAX(objc_getClassList(NULL, 0), 0); + + // numClasses now tells us how many classes we have (but it might change) + // So we can allocate our buffer, and get pointers to all the class definitions. + + NSUInteger bufferSize = numClasses; + + classes = numClasses ? (Class *)calloc(bufferSize, sizeof(Class)) : NULL; + if (classes == NULL) { + return @[]; //no memory or classes? + } + + numClasses = (NSUInteger)MAX(objc_getClassList(classes, (int)bufferSize),0); + + if (numClasses > bufferSize || numClasses == 0) { + //apparently more classes added between calls (or a problem); try again + free(classes); + classes = NULL; + numClasses = 0; + } + } + + // We can now loop through the classes, and test each one to see if it is a DDLogging class. + + NSMutableArray *result = [NSMutableArray arrayWithCapacity:numClasses]; + + for (NSUInteger i = 0; i < numClasses; i++) { + Class class = classes[i]; + + if ([self isRegisteredClass:class]) { + [result addObject:class]; + } + } + + free(classes); + + return result; +} + ++ (NSArray *)registeredClassNames { + NSArray *registeredClasses = [self registeredClasses]; + NSMutableArray *result = [NSMutableArray arrayWithCapacity:[registeredClasses count]]; + + for (Class class in registeredClasses) { + [result addObject:NSStringFromClass(class)]; + } + return result; +} + ++ (DDLogLevel)levelForClass:(Class)aClass { + if ([self isRegisteredClass:aClass]) { + return [aClass ddLogLevel]; + } + return (DDLogLevel)-1; +} + ++ (DDLogLevel)levelForClassWithName:(NSString *)aClassName { + Class aClass = NSClassFromString(aClassName); + + return [self levelForClass:aClass]; +} + ++ (void)setLevel:(DDLogLevel)level forClass:(Class)aClass { + if ([self isRegisteredClass:aClass]) { + [aClass ddSetLogLevel:level]; + } +} + ++ (void)setLevel:(DDLogLevel)level forClassWithName:(NSString *)aClassName { + Class aClass = NSClassFromString(aClassName); + [self setLevel:level forClass:aClass]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Logging Thread +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (void)lt_addLogger:(id )logger level:(DDLogLevel)level { + // Add to loggers array. + // Need to create loggerQueue if loggerNode doesn't provide one. + + for (DDLoggerNode *node in self._loggers) { + if (node->_logger == logger + && node->_level == level) { + // Exactly same logger already added, exit + return; + } + } + + NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), + @"This method should only be run on the logging thread/queue"); + + dispatch_queue_t loggerQueue = NULL; + if ([logger respondsToSelector:@selector(loggerQueue)]) { + // Logger may be providing its own queue + loggerQueue = logger.loggerQueue; + } + + if (loggerQueue == nil) { + // Automatically create queue for the logger. + // Use the logger name as the queue name if possible. + const char *loggerQueueName = NULL; + + if ([logger respondsToSelector:@selector(loggerName)]) { + loggerQueueName = logger.loggerName.UTF8String; + } + + loggerQueue = dispatch_queue_create(loggerQueueName, NULL); + } + + DDLoggerNode *loggerNode = [DDLoggerNode nodeWithLogger:logger loggerQueue:loggerQueue level:level]; + [self._loggers addObject:loggerNode]; + + if ([logger respondsToSelector:@selector(didAddLoggerInQueue:)]) { + dispatch_async(loggerNode->_loggerQueue, ^{ @autoreleasepool { + [logger didAddLoggerInQueue:loggerNode->_loggerQueue]; + } }); + } else if ([logger respondsToSelector:@selector(didAddLogger)]) { + dispatch_async(loggerNode->_loggerQueue, ^{ @autoreleasepool { + [logger didAddLogger]; + } }); + } +} + +- (void)lt_removeLogger:(id )logger { + // Find associated loggerNode in list of added loggers + + NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), + @"This method should only be run on the logging thread/queue"); + + DDLoggerNode *loggerNode = nil; + + for (DDLoggerNode *node in self._loggers) { + if (node->_logger == logger) { + loggerNode = node; + break; + } + } + + if (loggerNode == nil) { + NSLogDebug(@"DDLog: Request to remove logger which wasn't added"); + return; + } + + // Notify logger + if ([logger respondsToSelector:@selector(willRemoveLogger)]) { + dispatch_async(loggerNode->_loggerQueue, ^{ @autoreleasepool { + [logger willRemoveLogger]; + } }); + } + + // Remove from loggers array + [self._loggers removeObject:loggerNode]; +} + +- (void)lt_removeAllLoggers { + NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), + @"This method should only be run on the logging thread/queue"); + + // Notify all loggers + for (DDLoggerNode *loggerNode in self._loggers) { + if ([loggerNode->_logger respondsToSelector:@selector(willRemoveLogger)]) { + dispatch_async(loggerNode->_loggerQueue, ^{ @autoreleasepool { + [loggerNode->_logger willRemoveLogger]; + } }); + } + } + + // Remove all loggers from array + + [self._loggers removeAllObjects]; +} + +- (NSArray *)lt_allLoggers { + NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), + @"This method should only be run on the logging thread/queue"); + + NSMutableArray *theLoggers = [NSMutableArray new]; + + for (DDLoggerNode *loggerNode in self._loggers) { + [theLoggers addObject:loggerNode->_logger]; + } + + return [theLoggers copy]; +} + +- (NSArray *)lt_allLoggersWithLevel { + NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), + @"This method should only be run on the logging thread/queue"); + + NSMutableArray *theLoggersWithLevel = [NSMutableArray new]; + + for (DDLoggerNode *loggerNode in self._loggers) { + [theLoggersWithLevel addObject:[DDLoggerInformation informationWithLogger:loggerNode->_logger + andLevel:loggerNode->_level]]; + } + + return [theLoggersWithLevel copy]; +} + +- (void)lt_log:(DDLogMessage *)logMessage { + // Execute the given log message on each of our loggers. + + NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), + @"This method should only be run on the logging thread/queue"); + + if (_numProcessors > 1) { + // Execute each logger concurrently, each within its own queue. + // All blocks are added to same group. + // After each block has been queued, wait on group. + // + // The waiting ensures that a slow logger doesn't end up with a large queue of pending log messages. + // This would defeat the purpose of the efforts we made earlier to restrict the max queue size. + + for (DDLoggerNode *loggerNode in self._loggers) { + // skip the loggers that shouldn't write this message based on the log level + + if (!(logMessage->_flag & loggerNode->_level)) { + continue; + } + + dispatch_group_async(_loggingGroup, loggerNode->_loggerQueue, ^{ @autoreleasepool { + [loggerNode->_logger logMessage:logMessage]; + } }); + } + + dispatch_group_wait(_loggingGroup, DISPATCH_TIME_FOREVER); + } else { + // Execute each logger serially, each within its own queue. + + for (DDLoggerNode *loggerNode in self._loggers) { + // skip the loggers that shouldn't write this message based on the log level + + if (!(logMessage->_flag & loggerNode->_level)) { + continue; + } + +#if DD_DEBUG + // we must assure that we aren not on loggerNode->_loggerQueue. + if (loggerNode->_loggerQueue == NULL) { + // tell that we can't dispatch logger node on queue that is NULL. + NSLogDebug(@"DDLog: current node has loggerQueue == NULL"); + } + else { + dispatch_async(loggerNode->_loggerQueue, ^{ + if (dispatch_get_specific(GlobalLoggingQueueIdentityKey)) { + // tell that we somehow on logging queue? + NSLogDebug(@"DDLog: current node has loggerQueue == globalLoggingQueue"); + } + }); + } +#endif + // next, we must check that node is OK. + dispatch_sync(loggerNode->_loggerQueue, ^{ @autoreleasepool { + [loggerNode->_logger logMessage:logMessage]; + } }); + } + } + + // If our queue got too big, there may be blocked threads waiting to add log messages to the queue. + // Since we've now dequeued an item from the log, we may need to unblock the next thread. + + // We are using a counting semaphore provided by GCD. + // The semaphore is initialized with our DDLOG_MAX_QUEUE_SIZE value. + // When a log message is queued this value is decremented. + // When a log message is dequeued this value is incremented. + // If the value ever drops below zero, + // the queueing thread blocks and waits in FIFO order for us to signal it. + // + // A dispatch semaphore is an efficient implementation of a traditional counting semaphore. + // Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked. + // If the calling semaphore does not need to block, no kernel call is made. + + dispatch_semaphore_signal(_queueSemaphore); +} + +- (void)lt_flush { + // All log statements issued before the flush method was invoked have now been executed. + // + // Now we need to propagate the flush request to any loggers that implement the flush method. + // This is designed for loggers that buffer IO. + + NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), + @"This method should only be run on the logging thread/queue"); + + for (DDLoggerNode *loggerNode in self._loggers) { + if ([loggerNode->_logger respondsToSelector:@selector(flush)]) { + dispatch_group_async(_loggingGroup, loggerNode->_loggerQueue, ^{ @autoreleasepool { + [loggerNode->_logger flush]; + } }); + } + } + + dispatch_group_wait(_loggingGroup, DISPATCH_TIME_FOREVER); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Utilities +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +NSString * __nullable DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy) { + if (filePath == NULL) { + return nil; + } + + char *lastSlash = NULL; + char *lastDot = NULL; + + char *p = (char *)filePath; + + while (*p != '\0') { + if (*p == '/') { + lastSlash = p; + } else if (*p == '.') { + lastDot = p; + } + + p++; + } + + char *subStr; + NSUInteger subLen; + + if (lastSlash) { + if (lastDot) { + // lastSlash -> lastDot + subStr = lastSlash + 1; + subLen = (NSUInteger)(lastDot - subStr); + } else { + // lastSlash -> endOfString + subStr = lastSlash + 1; + subLen = (NSUInteger)(p - subStr); + } + } else { + if (lastDot) { + // startOfString -> lastDot + subStr = (char *)filePath; + subLen = (NSUInteger)(lastDot - subStr); + } else { + // startOfString -> endOfString + subStr = (char *)filePath; + subLen = (NSUInteger)(p - subStr); + } + } + + if (copy) { + return [[NSString alloc] initWithBytes:subStr + length:subLen + encoding:NSUTF8StringEncoding]; + } else { + // We can take advantage of the fact that __FILE__ is a string literal. + // Specifically, we don't need to waste time copying the string. + // We can just tell NSString to point to a range within the string literal. + + return [[NSString alloc] initWithBytesNoCopy:subStr + length:subLen + encoding:NSUTF8StringEncoding + freeWhenDone:NO]; + } +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDLoggerNode + +- (instancetype)initWithLogger:(id )logger loggerQueue:(dispatch_queue_t)loggerQueue level:(DDLogLevel)level { + if ((self = [super init])) { + _logger = logger; + + if (loggerQueue) { + _loggerQueue = loggerQueue; + #if !OS_OBJECT_USE_OBJC + dispatch_retain(loggerQueue); + #endif + } + + _level = level; + } + return self; +} + ++ (instancetype)nodeWithLogger:(id )logger loggerQueue:(dispatch_queue_t)loggerQueue level:(DDLogLevel)level { + return [[self alloc] initWithLogger:logger loggerQueue:loggerQueue level:level]; +} + +- (void)dealloc { + #if !OS_OBJECT_USE_OBJC + if (_loggerQueue) { + dispatch_release(_loggerQueue); + } + #endif +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDLogMessage + +- (instancetype)init { + self = [super init]; + return self; +} + +- (instancetype)initWithMessage:(NSString *)message + level:(DDLogLevel)level + flag:(DDLogFlag)flag + context:(NSInteger)context + file:(NSString *)file + function:(NSString *)function + line:(NSUInteger)line + tag:(id)tag + options:(DDLogMessageOptions)options + timestamp:(NSDate *)timestamp { + if ((self = [super init])) { + BOOL copyMessage = (options & DDLogMessageDontCopyMessage) == 0; + _message = copyMessage ? [message copy] : message; + _level = level; + _flag = flag; + _context = context; + + BOOL copyFile = (options & DDLogMessageCopyFile) != 0; + _file = copyFile ? [file copy] : file; + + BOOL copyFunction = (options & DDLogMessageCopyFunction) != 0; + _function = copyFunction ? [function copy] : function; + + _line = line; + _tag = tag; + _options = options; + _timestamp = timestamp ?: [NSDate new]; + + __uint64_t tid; + if (pthread_threadid_np(NULL, &tid) == 0) { + _threadID = [[NSString alloc] initWithFormat:@"%llu", tid]; + } else { + _threadID = @"missing threadId"; + } + _threadName = NSThread.currentThread.name; + + // Get the file name without extension + _fileName = [_file lastPathComponent]; + NSUInteger dotLocation = [_fileName rangeOfString:@"." options:NSBackwardsSearch].location; + if (dotLocation != NSNotFound) + { + _fileName = [_fileName substringToIndex:dotLocation]; + } + + // Try to get the current queue's label + _queueLabel = [[NSString alloc] initWithFormat:@"%s", dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)]; + _qos = (NSUInteger) qos_class_self(); + } + return self; +} + +- (BOOL)isEqual:(id)other { + if (other == self) { + return YES; + } else if (![super isEqual:other] || ![other isKindOfClass:[self class]]) { + return NO; + } else { + __auto_type otherMsg = (DDLogMessage *)other; + return [otherMsg->_message isEqualToString:_message] + && otherMsg->_level == _level + && otherMsg->_flag == _flag + && otherMsg->_context == _context + && [otherMsg->_file isEqualToString:_file] + && [otherMsg->_fileName isEqualToString:_fileName] + && [otherMsg->_function isEqualToString:_function] + && otherMsg->_line == _line + && (([otherMsg->_tag respondsToSelector:@selector(isEqual:)] && [otherMsg->_tag isEqual:_tag]) || otherMsg->_tag == _tag) + && otherMsg->_options == _options + && [otherMsg->_timestamp isEqualToDate:_timestamp] + && [otherMsg->_threadID isEqualToString:_threadID] // If the thread ID is the same, the name will likely be the same as well. + && [otherMsg->_queueLabel isEqualToString:_queueLabel] + && otherMsg->_qos == _qos; + } +} + +- (NSUInteger)hash { + return [super hash] + ^ _message.hash + ^ _level + ^ _flag + ^ _context + ^ _file.hash + ^ _fileName.hash + ^ _function.hash + ^ _line + ^ ([_tag respondsToSelector:@selector(hash)] ? [_tag hash] : 0) + ^ _options + ^ _timestamp.hash + ^ _threadID.hash + ^ _queueLabel.hash + ^ _qos; +} + +- (id)copyWithZone:(NSZone * __attribute__((unused)))zone { + DDLogMessage *newMessage = [DDLogMessage new]; + + newMessage->_message = _message; + newMessage->_level = _level; + newMessage->_flag = _flag; + newMessage->_context = _context; + newMessage->_file = _file; + newMessage->_fileName = _fileName; + newMessage->_function = _function; + newMessage->_line = _line; + newMessage->_tag = _tag; + newMessage->_options = _options; + newMessage->_timestamp = _timestamp; + newMessage->_threadID = _threadID; + newMessage->_threadName = _threadName; + newMessage->_queueLabel = _queueLabel; + newMessage->_qos = _qos; + + return newMessage; +} + +@end + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDAbstractLogger + +- (instancetype)init { + if ((self = [super init])) { + const char *loggerQueueName = NULL; + + if ([self respondsToSelector:@selector(loggerName)]) { + loggerQueueName = self.loggerName.UTF8String; + } + + _loggerQueue = dispatch_queue_create(loggerQueueName, NULL); + + // We're going to use dispatch_queue_set_specific() to "mark" our loggerQueue. + // Later we can use dispatch_get_specific() to determine if we're executing on our loggerQueue. + // The documentation states: + // + // > Keys are only compared as pointers and are never dereferenced. + // > Thus, you can use a pointer to a static variable for a specific subsystem or + // > any other value that allows you to identify the value uniquely. + // > Specifying a pointer to a string constant is not recommended. + // + // So we're going to use the very convenient key of "self", + // which also works when multiple logger classes extend this class, as each will have a different "self" key. + // + // This is used primarily for thread-safety assertions (via the isOnInternalLoggerQueue method below). + + void *key = (__bridge void *)self; + void *nonNullValue = (__bridge void *)self; + + dispatch_queue_set_specific(_loggerQueue, key, nonNullValue, NULL); + } + + return self; +} + +- (void)dealloc { + #if !OS_OBJECT_USE_OBJC + + if (_loggerQueue) { + dispatch_release(_loggerQueue); + } + + #endif +} + +- (void)logMessage:(DDLogMessage * __attribute__((unused)))logMessage { + // Override me +} + +- (id )logFormatter { + // This method must be thread safe and intuitive. + // Therefore if somebody executes the following code: + // + // [logger setLogFormatter:myFormatter]; + // formatter = [logger logFormatter]; + // + // They would expect formatter to equal myFormatter. + // This functionality must be ensured by the getter and setter method. + // + // The thread safety must not come at a cost to the performance of the logMessage method. + // This method is likely called sporadically, while the logMessage method is called repeatedly. + // This means, the implementation of this method: + // - Must NOT require the logMessage method to acquire a lock. + // - Must NOT require the logMessage method to access an atomic property (also a lock of sorts). + // + // Thread safety is ensured by executing access to the formatter variable on the loggerQueue. + // This is the same queue that the logMessage method operates on. + // + // Note: The last time I benchmarked the performance of direct access vs atomic property access, + // direct access was over twice as fast on the desktop and over 6 times as fast on the iPhone. + // + // Furthermore, consider the following code: + // + // DDLogVerbose(@"log msg 1"); + // DDLogVerbose(@"log msg 2"); + // [logger setFormatter:myFormatter]; + // DDLogVerbose(@"log msg 3"); + // + // Our intuitive requirement means that the new formatter will only apply to the 3rd log message. + // This must remain true even when using asynchronous logging. + // We must keep in mind the various queue's that are in play here: + // + // loggerQueue : Our own private internal queue that the logMessage method runs on. + // Operations are added to this queue from the global loggingQueue. + // + // globalLoggingQueue : The queue that all log messages go through before they arrive in our loggerQueue. + // + // All log statements go through the serial globalLoggingQueue before they arrive at our loggerQueue. + // Thus this method also goes through the serial globalLoggingQueue to ensure intuitive operation. + + // IMPORTANT NOTE: + // + // Methods within the DDLogger implementation MUST access the formatter ivar directly. + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block id result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self->_loggerQueue, ^{ + result = self->_logFormatter; + }); + }); + + return result; +} + +- (void)setLogFormatter:(id )logFormatter { + // The design of this method is documented extensively in the logFormatter message (above in code). + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_block_t block = ^{ + @autoreleasepool { + if (self->_logFormatter != logFormatter) { + if ([self->_logFormatter respondsToSelector:@selector(willRemoveFromLogger:)]) { + [self->_logFormatter willRemoveFromLogger:self]; + } + + self->_logFormatter = logFormatter; + + if ([self->_logFormatter respondsToSelector:@selector(didAddToLogger:inQueue:)]) { + [self->_logFormatter didAddToLogger:self inQueue:self->_loggerQueue]; + } else if ([self->_logFormatter respondsToSelector:@selector(didAddToLogger:)]) { + [self->_logFormatter didAddToLogger:self]; + } + } + } + }; + + dispatch_async(DDLog.loggingQueue, ^{ + dispatch_async(self->_loggerQueue, block); + }); +} + +- (dispatch_queue_t)loggerQueue { + return _loggerQueue; +} + +- (NSString *)loggerName { + return NSStringFromClass([self class]); +} + +- (BOOL)isOnGlobalLoggingQueue { + return (dispatch_get_specific(GlobalLoggingQueueIdentityKey) != NULL); +} + +- (BOOL)isOnInternalLoggerQueue { + void *key = (__bridge void *)self; + + return (dispatch_get_specific(key) != NULL); +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface DDLoggerInformation() +{ + // Direct accessors to be used only for performance + @public + id _logger; + DDLogLevel _level; +} + +@end + +@implementation DDLoggerInformation + +- (instancetype)initWithLogger:(id )logger andLevel:(DDLogLevel)level { + if ((self = [super init])) { + _logger = logger; + _level = level; + } + return self; +} + ++ (instancetype)informationWithLogger:(id )logger andLevel:(DDLogLevel)level { + return [[self alloc] initWithLogger:logger andLevel:level]; +} + +@end diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDLoggerNames.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDLoggerNames.m new file mode 100644 index 0000000..c4ef29f --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDLoggerNames.m @@ -0,0 +1,21 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#import + +DDLoggerName const DDLoggerNameASL = @"cocoa.lumberjack.aslLogger"; +DDLoggerName const DDLoggerNameTTY = @"cocoa.lumberjack.ttyLogger"; +DDLoggerName const DDLoggerNameOS = @"cocoa.lumberjack.osLogger"; +DDLoggerName const DDLoggerNameFile = @"cocoa.lumberjack.fileLogger"; diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDOSLogger.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDOSLogger.m new file mode 100644 index 0000000..b144953 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDOSLogger.m @@ -0,0 +1,118 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#import + +#import + +@interface DDOSLogger () { + NSString *_subsystem; + NSString *_category; +} + +@property (copy, nonatomic, readonly, nullable) NSString *subsystem; +@property (copy, nonatomic, readonly, nullable) NSString *category; +@property (strong, nonatomic, readwrite, nonnull) os_log_t logger; + +@end + +@implementation DDOSLogger + +@synthesize subsystem = _subsystem; +@synthesize category = _category; + +#pragma mark - Initialization + +/** + * Assertion + * Swift: (String, String)? + */ +- (instancetype)initWithSubsystem:(NSString *)subsystem category:(NSString *)category { + NSAssert((subsystem == nil) == (category == nil), @"Either both subsystem and category or neither should be nil."); + if (self = [super init]) { + _subsystem = [subsystem copy]; + _category = [category copy]; + } + return self; +} + +static DDOSLogger *sharedInstance; + +- (instancetype)init { + return [self initWithSubsystem:nil category:nil]; +} + ++ (instancetype)sharedInstance { + static dispatch_once_t DDOSLoggerOnceToken; + + dispatch_once(&DDOSLoggerOnceToken, ^{ + sharedInstance = [[[self class] alloc] init]; + }); + + return sharedInstance; +} + +#pragma mark - os_log + +- (os_log_t)getLogger { + if (self.subsystem == nil || self.category == nil) { + return OS_LOG_DEFAULT; + } + return os_log_create(self.subsystem.UTF8String, self.category.UTF8String); +} + +- (os_log_t)logger { + if (_logger == nil) { + _logger = [self getLogger]; + } + return _logger; +} + +#pragma mark - DDLogger + +- (DDLoggerName)loggerName { + return DDLoggerNameOS; +} + +- (void)logMessage:(DDLogMessage *)logMessage { + // Skip captured log messages + if ([logMessage->_fileName isEqualToString:@"DDASLLogCapture"]) { + return; + } + + if (@available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)) { + NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message; + if (message != nil) { + const char *msg = [message UTF8String]; + __auto_type logger = [self logger]; + switch (logMessage->_flag) { + case DDLogFlagError : + os_log_error(logger, "%{public}s", msg); + break; + case DDLogFlagWarning: + case DDLogFlagInfo : + os_log_info(logger, "%{public}s", msg); + break; + case DDLogFlagDebug : + case DDLogFlagVerbose: + default : + os_log_debug(logger, "%{public}s", msg); + break; + } + } + } +} + +@end diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDTTYLogger.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDTTYLogger.m new file mode 100644 index 0000000..9ff79c5 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/DDTTYLogger.m @@ -0,0 +1,1491 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +#import + +#import + +// We probably shouldn't be using DDLog() statements within the DDLog implementation. +// But we still want to leave our log statements for any future debugging, +// and to allow other developers to trace the implementation (which is a great learning tool). +// +// So we use primitive logging macros around NSLog. +// We maintain the NS prefix on the macros to be explicit about the fact that we're using NSLog. + +#ifndef DD_NSLOG_LEVEL + #define DD_NSLOG_LEVEL 2 +#endif + +#define NSLogError(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 1) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogWarn(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 2) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogInfo(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 3) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogDebug(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 4) NSLog((frmt), ##__VA_ARGS__); } while(0) +#define NSLogVerbose(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 5) NSLog((frmt), ##__VA_ARGS__); } while(0) + +// Xcode does NOT natively support colors in the Xcode debugging console. +// You'll need to install the XcodeColors plugin to see colors in the Xcode console. +// https://github.com/robbiehanson/XcodeColors +// +// The following is documentation from the XcodeColors project: +// +// +// How to apply color formatting to your log statements: +// +// To set the foreground color: +// Insert the ESCAPE_SEQ into your string, followed by "fg124,12,255;" where r=124, g=12, b=255. +// +// To set the background color: +// Insert the ESCAPE_SEQ into your string, followed by "bg12,24,36;" where r=12, g=24, b=36. +// +// To reset the foreground color (to default value): +// Insert the ESCAPE_SEQ into your string, followed by "fg;" +// +// To reset the background color (to default value): +// Insert the ESCAPE_SEQ into your string, followed by "bg;" +// +// To reset the foreground and background color (to default values) in one operation: +// Insert the ESCAPE_SEQ into your string, followed by ";" + +#define XCODE_COLORS_ESCAPE_SEQ "\033[" + +#define XCODE_COLORS_RESET_FG XCODE_COLORS_ESCAPE_SEQ "fg;" // Clear any foreground color +#define XCODE_COLORS_RESET_BG XCODE_COLORS_ESCAPE_SEQ "bg;" // Clear any background color +#define XCODE_COLORS_RESET XCODE_COLORS_ESCAPE_SEQ ";" // Clear any foreground or background color + +// If running in a shell, not all RGB colors will be supported. +// In this case we automatically map to the closest available color. +// In order to provide this mapping, we have a hard-coded set of the standard RGB values available in the shell. +// However, not every shell is the same, and Apple likes to think different even when it comes to shell colors. +// +// Map to standard Terminal.app colors (1), or +// map to standard xterm colors (0). + +#define MAP_TO_TERMINAL_APP_COLORS 1 + +typedef struct { + uint8_t r; + uint8_t g; + uint8_t b; +} DDRGBColor; + +@interface DDTTYLoggerColorProfile : NSObject { + @public + DDLogFlag mask; + NSInteger context; + + uint8_t fg_r; + uint8_t fg_g; + uint8_t fg_b; + + uint8_t bg_r; + uint8_t bg_g; + uint8_t bg_b; + + NSUInteger fgCodeIndex; + NSString *fgCodeRaw; + + NSUInteger bgCodeIndex; + NSString *bgCodeRaw; + + char fgCode[24]; + size_t fgCodeLen; + + char bgCode[24]; + size_t bgCodeLen; + + char resetCode[8]; + size_t resetCodeLen; +} + +- (nullable instancetype)initWithForegroundColor:(nullable DDColor *)fgColor backgroundColor:(nullable DDColor *)bgColor flag:(DDLogFlag)mask context:(NSInteger)ctxt; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface DDTTYLogger () { + NSString *_appName; + char *_app; + size_t _appLen; + + NSString *_processID; + char *_pid; + size_t _pidLen; + + BOOL _colorsEnabled; + NSMutableArray *_colorProfilesArray; + NSMutableDictionary *_colorProfilesDict; +} + +@end + + +@implementation DDTTYLogger + +static BOOL isaColorTTY; +static BOOL isaColor256TTY; +static BOOL isaXcodeColorTTY; + +static NSArray *codes_fg = nil; +static NSArray *codes_bg = nil; +static NSArray *colors = nil; + +static DDTTYLogger *sharedInstance; + +/** + * Initializes the colors array, as well as the codes_fg and codes_bg arrays, for 16 color mode. + * + * This method is used when the application is running from within a shell that only supports 16 color mode. + * This method is not invoked if the application is running within Xcode, or via normal UI app launch. + **/ ++ (void)initialize_colors_16 { + if (codes_fg || codes_bg || colors) { + return; + } + + NSMutableArray *m_colors = [NSMutableArray arrayWithCapacity:16]; + + // In a standard shell only 16 colors are supported. + // + // More information about ansi escape codes can be found online. + // http://en.wikipedia.org/wiki/ANSI_escape_code + codes_fg = @[ + @"30m", // normal - black + @"31m", // normal - red + @"32m", // normal - green + @"33m", // normal - yellow + @"34m", // normal - blue + @"35m", // normal - magenta + @"36m", // normal - cyan + @"37m", // normal - gray + @"1;30m", // bright - darkgray + @"1;31m", // bright - red + @"1;32m", // bright - green + @"1;33m", // bright - yellow + @"1;34m", // bright - blue + @"1;35m", // bright - magenta + @"1;36m", // bright - cyan + @"1;37m", // bright - white + ]; + + codes_bg = @[ + @"40m", // normal - black + @"41m", // normal - red + @"42m", // normal - green + @"43m", // normal - yellow + @"44m", // normal - blue + @"45m", // normal - magenta + @"46m", // normal - cyan + @"47m", // normal - gray + @"1;40m", // bright - darkgray + @"1;41m", // bright - red + @"1;42m", // bright - green + @"1;43m", // bright - yellow + @"1;44m", // bright - blue + @"1;45m", // bright - magenta + @"1;46m", // bright - cyan + @"1;47m", // bright - white + ]; + + +#if MAP_TO_TERMINAL_APP_COLORS + + // Standard Terminal.app colors: + // + // These are the default colors used by Apple's Terminal.app. + DDRGBColor rgbColors[] = { + { 0, 0, 0}, // normal - black + {194, 54, 33}, // normal - red + { 37, 188, 36}, // normal - green + {173, 173, 39}, // normal - yellow + { 73, 46, 225}, // normal - blue + {211, 56, 211}, // normal - magenta + { 51, 187, 200}, // normal - cyan + {203, 204, 205}, // normal - gray + {129, 131, 131}, // bright - darkgray + {252, 57, 31}, // bright - red + { 49, 231, 34}, // bright - green + {234, 236, 35}, // bright - yellow + { 88, 51, 255}, // bright - blue + {249, 53, 248}, // bright - magenta + { 20, 240, 240}, // bright - cyan + {233, 235, 235}, // bright - white + }; + +#else /* if MAP_TO_TERMINAL_APP_COLORS */ + + // Standard xterm colors: + // + // These are the default colors used by most xterm shells. + + DDRGBColor rgbColors[] = { + { 0, 0, 0}, // normal - black + {205, 0, 0}, // normal - red + { 0, 205, 0}, // normal - green + {205, 205, 0}, // normal - yellow + { 0, 0, 238}, // normal - blue + {205, 0, 205}, // normal - magenta + { 0, 205, 205}, // normal - cyan + {229, 229, 229}, // normal - gray + {127, 127, 127}, // bright - darkgray + {255, 0, 0}, // bright - red + { 0, 255, 0}, // bright - green + {255, 255, 0}, // bright - yellow + { 92, 92, 255}, // bright - blue + {255, 0, 255}, // bright - magenta + { 0, 255, 255}, // bright - cyan + {255, 255, 255}, // bright - white + }; +#endif /* if MAP_TO_TERMINAL_APP_COLORS */ + + for (size_t i = 0; i < sizeof(rgbColors) / sizeof(rgbColors[0]); ++i) { + [m_colors addObject:DDMakeColor(rgbColors[i].r, rgbColors[i].g, rgbColors[i].b)]; + } + colors = [m_colors copy]; + + NSAssert([codes_fg count] == [codes_bg count], @"Invalid colors/codes array(s)"); + NSAssert([codes_fg count] == [colors count], @"Invalid colors/codes array(s)"); +} + +/** + * Initializes the colors array, as well as the codes_fg and codes_bg arrays, for 256 color mode. + * + * This method is used when the application is running from within a shell that supports 256 color mode. + * This method is not invoked if the application is running within Xcode, or via normal UI app launch. + **/ ++ (void)initialize_colors_256 { + if (codes_fg || codes_bg || colors) { + return; + } + + NSMutableArray *m_codes_fg = [NSMutableArray arrayWithCapacity:(256 - 16)]; + NSMutableArray *m_codes_bg = [NSMutableArray arrayWithCapacity:(256 - 16)]; + NSMutableArray *m_colors = [NSMutableArray arrayWithCapacity:(256 - 16)]; + + #if MAP_TO_TERMINAL_APP_COLORS + + // Standard Terminal.app colors: + // + // These are the colors the Terminal.app uses in xterm-256color mode. + // In this mode, the terminal supports 256 different colors, specified by 256 color codes. + // + // The first 16 color codes map to the original 16 color codes supported by the earlier xterm-color mode. + // These are actually configurable, and thus we ignore them for the purposes of mapping, + // as we can't rely on them being constant. They are largely duplicated anyway. + // + // The next 216 color codes are designed to run the spectrum, with several shades of every color. + // While the color codes are standardized, the actual RGB values for each color code is not. + // Apple's Terminal.app uses different RGB values from that of a standard xterm. + // Apple's choices in colors are designed to be a little nicer on the eyes. + // + // The last 24 color codes represent a grayscale. + // + // Unfortunately, unlike the standard xterm color chart, + // Apple's RGB values cannot be calculated using a simple formula (at least not that I know of). + // Also, I don't know of any ways to programmatically query the shell for the RGB values. + // So this big giant color chart had to be made by hand. + // + // More information about ansi escape codes can be found online. + // http://en.wikipedia.org/wiki/ANSI_escape_code + + // Colors + DDRGBColor rgbColors[] = { + { 47, 49, 49}, + { 60, 42, 144}, + { 66, 44, 183}, + { 73, 46, 222}, + { 81, 50, 253}, + { 88, 51, 255}, + + { 42, 128, 37}, + { 42, 127, 128}, + { 44, 126, 169}, + { 56, 125, 209}, + { 59, 124, 245}, + { 66, 123, 255}, + + { 51, 163, 41}, + { 39, 162, 121}, + { 42, 161, 162}, + { 53, 160, 202}, + { 45, 159, 240}, + { 58, 158, 255}, + + { 31, 196, 37}, + { 48, 196, 115}, + { 39, 195, 155}, + { 49, 195, 195}, + { 32, 194, 235}, + { 53, 193, 255}, + + { 50, 229, 35}, + { 40, 229, 109}, + { 27, 229, 149}, + { 49, 228, 189}, + { 33, 228, 228}, + { 53, 227, 255}, + + { 27, 254, 30}, + { 30, 254, 103}, + { 45, 254, 143}, + { 38, 253, 182}, + { 38, 253, 222}, + { 42, 253, 252}, + + {140, 48, 40}, + {136, 51, 136}, + {135, 52, 177}, + {134, 52, 217}, + {135, 56, 248}, + {134, 53, 255}, + + {125, 125, 38}, + {124, 125, 125}, + {122, 124, 166}, + {123, 124, 207}, + {123, 122, 247}, + {124, 121, 255}, + + {119, 160, 35}, + {117, 160, 120}, + {117, 160, 160}, + {115, 159, 201}, + {116, 158, 240}, + {117, 157, 255}, + + {113, 195, 39}, + {110, 194, 114}, + {111, 194, 154}, + {108, 194, 194}, + {109, 193, 234}, + {108, 192, 255}, + + {105, 228, 30}, + {103, 228, 109}, + {105, 228, 148}, + {100, 227, 188}, + { 99, 227, 227}, + { 99, 226, 253}, + + { 92, 253, 34}, + { 96, 253, 103}, + { 97, 253, 142}, + { 88, 253, 182}, + { 93, 253, 221}, + { 88, 254, 251}, + + {177, 53, 34}, + {174, 54, 131}, + {172, 55, 172}, + {171, 57, 213}, + {170, 55, 249}, + {170, 57, 255}, + + {165, 123, 37}, + {163, 123, 123}, + {162, 123, 164}, + {161, 122, 205}, + {161, 121, 241}, + {161, 121, 255}, + + {158, 159, 33}, + {157, 158, 118}, + {157, 158, 159}, + {155, 157, 199}, + {155, 157, 239}, + {154, 156, 255}, + + {152, 193, 40}, + {151, 193, 113}, + {150, 193, 153}, + {150, 192, 193}, + {148, 192, 232}, + {149, 191, 253}, + + {146, 227, 28}, + {144, 227, 108}, + {144, 227, 147}, + {144, 227, 187}, + {142, 226, 227}, + {142, 225, 252}, + + {138, 253, 36}, + {137, 253, 102}, + {136, 253, 141}, + {138, 254, 181}, + {135, 255, 220}, + {133, 255, 250}, + + {214, 57, 30}, + {211, 59, 126}, + {209, 57, 168}, + {208, 55, 208}, + {207, 58, 247}, + {206, 61, 255}, + + {204, 121, 32}, + {202, 121, 121}, + {201, 121, 161}, + {200, 120, 202}, + {200, 120, 241}, + {198, 119, 255}, + + {198, 157, 37}, + {196, 157, 116}, + {195, 156, 157}, + {195, 156, 197}, + {194, 155, 236}, + {193, 155, 255}, + + {191, 192, 36}, + {190, 191, 112}, + {189, 191, 152}, + {189, 191, 191}, + {188, 190, 230}, + {187, 190, 253}, + + {185, 226, 28}, + {184, 226, 106}, + {183, 225, 146}, + {183, 225, 186}, + {182, 225, 225}, + {181, 224, 252}, + + {178, 255, 35}, + {178, 255, 101}, + {177, 254, 141}, + {176, 254, 180}, + {176, 254, 220}, + {175, 253, 249}, + + {247, 56, 30}, + {245, 57, 122}, + {243, 59, 163}, + {244, 60, 204}, + {242, 59, 241}, + {240, 55, 255}, + + {241, 119, 36}, + {240, 120, 118}, + {238, 119, 158}, + {237, 119, 199}, + {237, 118, 238}, + {236, 118, 255}, + + {235, 154, 36}, + {235, 154, 114}, + {234, 154, 154}, + {232, 154, 194}, + {232, 153, 234}, + {232, 153, 255}, + + {230, 190, 30}, + {229, 189, 110}, + {228, 189, 150}, + {227, 189, 190}, + {227, 189, 229}, + {226, 188, 255}, + + {224, 224, 35}, + {223, 224, 105}, + {222, 224, 144}, + {222, 223, 184}, + {222, 223, 224}, + {220, 223, 253}, + + {217, 253, 28}, + {217, 253, 99}, + {216, 252, 139}, + {216, 252, 179}, + {215, 252, 218}, + {215, 251, 250}, + + {255, 61, 30}, + {255, 60, 118}, + {255, 58, 159}, + {255, 56, 199}, + {255, 55, 238}, + {255, 59, 255}, + + {255, 117, 29}, + {255, 117, 115}, + {255, 117, 155}, + {255, 117, 195}, + {255, 116, 235}, + {254, 116, 255}, + + {255, 152, 27}, + {255, 152, 111}, + {254, 152, 152}, + {255, 152, 192}, + {254, 151, 231}, + {253, 151, 253}, + + {255, 187, 33}, + {253, 187, 107}, + {252, 187, 148}, + {253, 187, 187}, + {254, 187, 227}, + {252, 186, 252}, + + {252, 222, 34}, + {251, 222, 103}, + {251, 222, 143}, + {250, 222, 182}, + {251, 221, 222}, + {252, 221, 252}, + + {251, 252, 15}, + {251, 252, 97}, + {249, 252, 137}, + {247, 252, 177}, + {247, 253, 217}, + {254, 255, 255}, + + // Grayscale + + { 52, 53, 53}, + { 57, 58, 59}, + { 66, 67, 67}, + { 75, 76, 76}, + { 83, 85, 85}, + { 92, 93, 94}, + + {101, 102, 102}, + {109, 111, 111}, + {118, 119, 119}, + {126, 127, 128}, + {134, 136, 136}, + {143, 144, 145}, + + {151, 152, 153}, + {159, 161, 161}, + {167, 169, 169}, + {176, 177, 177}, + {184, 185, 186}, + {192, 193, 194}, + + {200, 201, 202}, + {208, 209, 210}, + {216, 218, 218}, + {224, 226, 226}, + {232, 234, 234}, + {240, 242, 242}, + }; + + for (size_t i = 0; i < sizeof(rgbColors) / sizeof(rgbColors[0]); ++i) { + [m_colors addObject:DDMakeColor(rgbColors[i].r, rgbColors[i].g, rgbColors[i].b)]; + } + + // Color codes + + int index = 16; + + while (index < 256) { + [m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]]; + [m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]]; + + index++; + } + + #else /* if MAP_TO_TERMINAL_APP_COLORS */ + + // Standard xterm colors: + // + // These are the colors xterm shells use in xterm-256color mode. + // In this mode, the shell supports 256 different colors, specified by 256 color codes. + // + // The first 16 color codes map to the original 16 color codes supported by the earlier xterm-color mode. + // These are generally configurable, and thus we ignore them for the purposes of mapping, + // as we can't rely on them being constant. They are largely duplicated anyway. + // + // The next 216 color codes are designed to run the spectrum, with several shades of every color. + // The last 24 color codes represent a grayscale. + // + // While the color codes are standardized, the actual RGB values for each color code is not. + // However most standard xterms follow a well known color chart, + // which can easily be calculated using the simple formula below. + // + // More information about ansi escape codes can be found online. + // http://en.wikipedia.org/wiki/ANSI_escape_code + + int index = 16; + + int r; // red + int g; // green + int b; // blue + + int ri; // r increment + int gi; // g increment + int bi; // b increment + + // Calculate xterm colors (using standard algorithm) + + int r = 0; + int g = 0; + int b = 0; + + for (ri = 0; ri < 6; ri++) { + r = (ri == 0) ? 0 : 95 + (40 * (ri - 1)); + + for (gi = 0; gi < 6; gi++) { + g = (gi == 0) ? 0 : 95 + (40 * (gi - 1)); + + for (bi = 0; bi < 6; bi++) { + b = (bi == 0) ? 0 : 95 + (40 * (bi - 1)); + + [m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]]; + [m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]]; + [m_colors addObject:DDMakeColor(r, g, b)]; + + index++; + } + } + } + + // Calculate xterm grayscale (using standard algorithm) + + r = 8; + g = 8; + b = 8; + + while (index < 256) { + [m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]]; + [m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]]; + [m_colors addObject:DDMakeColor(r, g, b)]; + + r += 10; + g += 10; + b += 10; + + index++; + } + + #endif /* if MAP_TO_TERMINAL_APP_COLORS */ + + codes_fg = [m_codes_fg copy]; + codes_bg = [m_codes_bg copy]; + colors = [m_colors copy]; + + NSAssert([codes_fg count] == [codes_bg count], @"Invalid colors/codes array(s)"); + NSAssert([codes_fg count] == [colors count], @"Invalid colors/codes array(s)"); +} + ++ (void)getRed:(CGFloat *)rPtr green:(CGFloat *)gPtr blue:(CGFloat *)bPtr fromColor:(DDColor *)color { + #if TARGET_OS_IPHONE + + // iOS + + BOOL done = NO; + + if ([color respondsToSelector:@selector(getRed:green:blue:alpha:)]) { + done = [color getRed:rPtr green:gPtr blue:bPtr alpha:NULL]; + } + + if (!done) { + // The method getRed:green:blue:alpha: was only available starting iOS 5. + // So in iOS 4 and earlier, we have to jump through hoops. + + CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); + + unsigned char pixel[4]; + CGContextRef context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, rgbColorSpace, (CGBitmapInfo)(kCGBitmapAlphaInfoMask & kCGImageAlphaNoneSkipLast)); + + CGContextSetFillColorWithColor(context, [color CGColor]); + CGContextFillRect(context, CGRectMake(0, 0, 1, 1)); + + if (rPtr) { + *rPtr = pixel[0] / 255.0f; + } + + if (gPtr) { + *gPtr = pixel[1] / 255.0f; + } + + if (bPtr) { + *bPtr = pixel[2] / 255.0f; + } + + CGContextRelease(context); + CGColorSpaceRelease(rgbColorSpace); + } + + #elif defined(DD_CLI) || !__has_include() + + // OS X without AppKit + + [color getRed:rPtr green:gPtr blue:bPtr alpha:NULL]; + + #else /* if TARGET_OS_IPHONE */ + + // OS X with AppKit + + NSColor *safeColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; + + [safeColor getRed:rPtr green:gPtr blue:bPtr alpha:NULL]; + #endif /* if TARGET_OS_IPHONE */ +} + +/** + * Maps the given color to the closest available color supported by the shell. + * The shell may support 256 colors, or only 16. + * + * This method loops through the known supported color set, and calculates the closest color. + * The array index of that color, within the colors array, is then returned. + * This array index may also be used as the index within the codes_fg and codes_bg arrays. + **/ ++ (NSUInteger)codeIndexForColor:(DDColor *)inColor { + CGFloat inR, inG, inB; + + [self getRed:&inR green:&inG blue:&inB fromColor:inColor]; + + NSUInteger bestIndex = 0; + CGFloat lowestDistance = 100.0f; + + NSUInteger i = 0; + + for (DDColor *color in colors) { + // Calculate Euclidean distance (lower value means closer to given color) + + CGFloat r, g, b; + [self getRed:&r green:&g blue:&b fromColor:color]; + + #if CGFLOAT_IS_DOUBLE + CGFloat distance = sqrt(pow(r - inR, 2.0) + pow(g - inG, 2.0) + pow(b - inB, 2.0)); + #else + CGFloat distance = sqrtf(powf(r - inR, 2.0f) + powf(g - inG, 2.0f) + powf(b - inB, 2.0f)); + #endif + + NSLogVerbose(@"DDTTYLogger: %3lu : %.3f,%.3f,%.3f & %.3f,%.3f,%.3f = %.6f", + (unsigned long)i, inR, inG, inB, r, g, b, distance); + + if (distance < lowestDistance) { + bestIndex = i; + lowestDistance = distance; + + NSLogVerbose(@"DDTTYLogger: New best index = %lu", (unsigned long)bestIndex); + } + + i++; + } + + return bestIndex; +} + ++ (instancetype)sharedInstance { + static dispatch_once_t DDTTYLoggerOnceToken; + + dispatch_once(&DDTTYLoggerOnceToken, ^{ + // Xcode does NOT natively support colors in the Xcode debugging console. + // You'll need to install the XcodeColors plugin to see colors in the Xcode console. + // + // PS - Please read the header file before diving into the source code. + + char *xcode_colors = getenv("XcodeColors"); + char *term = getenv("TERM"); + + if (xcode_colors && (strcmp(xcode_colors, "YES") == 0)) { + isaXcodeColorTTY = YES; + } else if (term) { + if (strcasestr(term, "color") != NULL) { + isaColorTTY = YES; + isaColor256TTY = (strcasestr(term, "256") != NULL); + + if (isaColor256TTY) { + [self initialize_colors_256]; + } else { + [self initialize_colors_16]; + } + } + } + + NSLogInfo(@"DDTTYLogger: isaColorTTY = %@", (isaColorTTY ? @"YES" : @"NO")); + NSLogInfo(@"DDTTYLogger: isaColor256TTY: %@", (isaColor256TTY ? @"YES" : @"NO")); + NSLogInfo(@"DDTTYLogger: isaXcodeColorTTY: %@", (isaXcodeColorTTY ? @"YES" : @"NO")); + + sharedInstance = [[self alloc] init]; + }); + + return sharedInstance; +} + +- (instancetype)init { + if (sharedInstance != nil) { + return nil; + } + + if (@available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)) { + NSLogWarn(@"CocoaLumberjack: Warning: Usage of DDTTYLogger detected when DDOSLogger is available and can be used! Please consider migrating to DDOSLogger."); + } + + if ((self = [super init])) { + // Initialize 'app' variable (char *) + + _appName = [[NSProcessInfo processInfo] processName]; + + _appLen = [_appName lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + if (_appLen == 0) { + _appName = @""; + _appLen = [_appName lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + } + + _app = (char *)calloc(_appLen + 1, sizeof(char)); + + if (_app == NULL) { + return nil; + } + + BOOL processedAppName = [_appName getCString:_app maxLength:(_appLen + 1) encoding:NSUTF8StringEncoding]; + + if (NO == processedAppName) { + free(_app); + return nil; + } + + // Initialize 'pid' variable (char *) + + _processID = [NSString stringWithFormat:@"%i", (int)getpid()]; + + _pidLen = [_processID lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + _pid = (char *)calloc(_pidLen + 1, sizeof(char)); + + if (_pid == NULL) { + free(_app); + return nil; + } + + BOOL processedID = [_processID getCString:_pid maxLength:(_pidLen + 1) encoding:NSUTF8StringEncoding]; + + if (NO == processedID) { + free(_app); + free(_pid); + return nil; + } + + // Initialize color stuff + + _colorsEnabled = NO; + _colorProfilesArray = [[NSMutableArray alloc] initWithCapacity:8]; + _colorProfilesDict = [[NSMutableDictionary alloc] initWithCapacity:8]; + + _automaticallyAppendNewlineForCustomFormatters = YES; + } + + return self; +} + +- (DDLoggerName)loggerName { + return DDLoggerNameTTY; +} + +- (void)loadDefaultColorProfiles { + [self setForegroundColor:DDMakeColor(214, 57, 30) backgroundColor:nil forFlag:DDLogFlagError]; + [self setForegroundColor:DDMakeColor(204, 121, 32) backgroundColor:nil forFlag:DDLogFlagWarning]; +} + +- (BOOL)colorsEnabled { + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + __block BOOL result; + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.loggerQueue, ^{ + result = self->_colorsEnabled; + }); + }); + + return result; +} + +- (void)setColorsEnabled:(BOOL)newColorsEnabled { + dispatch_block_t block = ^{ + @autoreleasepool { + self->_colorsEnabled = newColorsEnabled; + + if ([self->_colorProfilesArray count] == 0) { + [self loadDefaultColorProfiles]; + } + } + }; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + // Note: The internal implementation MUST access the colorsEnabled variable directly, + // This method is designed explicitly for external access. + // + // Using "self." syntax to go through this method will cause immediate deadlock. + // This is the intended result. Fix it by accessing the ivar directly. + // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster. + + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax."); + + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); +} + +- (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forFlag:(DDLogFlag)mask { + [self setForegroundColor:txtColor backgroundColor:bgColor forFlag:mask context:LOG_CONTEXT_ALL]; +} + +- (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forFlag:(DDLogFlag)mask context:(NSInteger)ctxt { + dispatch_block_t block = ^{ + @autoreleasepool { + DDTTYLoggerColorProfile *newColorProfile = + [[DDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor + backgroundColor:bgColor + flag:mask + context:ctxt]; + + NSLogInfo(@"DDTTYLogger: newColorProfile: %@", newColorProfile); + + NSUInteger i = 0; + + for (DDTTYLoggerColorProfile *colorProfile in self->_colorProfilesArray) { + if ((colorProfile->mask == mask) && (colorProfile->context == ctxt)) { + break; + } + + i++; + } + + if (i < [self->_colorProfilesArray count]) { + self->_colorProfilesArray[i] = newColorProfile; + } else { + [self->_colorProfilesArray addObject:newColorProfile]; + } + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (void)setForegroundColor:(DDColor *)txtColor backgroundColor:(DDColor *)bgColor forTag:(id )tag { + NSAssert([(id < NSObject >) tag conformsToProtocol: @protocol(NSCopying)], @"Invalid tag"); + + dispatch_block_t block = ^{ + @autoreleasepool { + DDTTYLoggerColorProfile *newColorProfile = + [[DDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor + backgroundColor:bgColor + flag:(DDLogFlag)0 + context:0]; + + NSLogInfo(@"DDTTYLogger: newColorProfile: %@", newColorProfile); + + self->_colorProfilesDict[tag] = newColorProfile; + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (void)clearColorsForFlag:(DDLogFlag)mask { + [self clearColorsForFlag:mask context:0]; +} + +- (void)clearColorsForFlag:(DDLogFlag)mask context:(NSInteger)context { + dispatch_block_t block = ^{ + @autoreleasepool { + NSUInteger i = 0; + + for (DDTTYLoggerColorProfile *colorProfile in self->_colorProfilesArray) { + if ((colorProfile->mask == mask) && (colorProfile->context == context)) { + break; + } + + i++; + } + + if (i < [self->_colorProfilesArray count]) { + [self->_colorProfilesArray removeObjectAtIndex:i]; + } + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (void)clearColorsForTag:(id )tag { + NSAssert([(id < NSObject >) tag conformsToProtocol: @protocol(NSCopying)], @"Invalid tag"); + + dispatch_block_t block = ^{ + @autoreleasepool { + [self->_colorProfilesDict removeObjectForKey:tag]; + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (void)clearColorsForAllFlags { + dispatch_block_t block = ^{ + @autoreleasepool { + [self->_colorProfilesArray removeAllObjects]; + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (void)clearColorsForAllTags { + dispatch_block_t block = ^{ + @autoreleasepool { + [self->_colorProfilesDict removeAllObjects]; + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (void)clearAllColors { + dispatch_block_t block = ^{ + @autoreleasepool { + [self->_colorProfilesArray removeAllObjects]; + [self->_colorProfilesDict removeAllObjects]; + } + }; + + // The design of the setter logic below is taken from the DDAbstractLogger implementation. + // For documentation please refer to the DDAbstractLogger implementation. + + if ([self isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_async(globalLoggingQueue, ^{ + dispatch_async(self.loggerQueue, block); + }); + } +} + +- (void)logMessage:(DDLogMessage *)logMessage { + NSString *logMsg = logMessage->_message; + BOOL isFormatted = NO; + + if (_logFormatter) { + logMsg = [_logFormatter formatLogMessage:logMessage]; + isFormatted = logMsg != logMessage->_message; + } + + if (logMsg) { + // Search for a color profile associated with the log message + + DDTTYLoggerColorProfile *colorProfile = nil; + + if (_colorsEnabled) { + if (logMessage->_tag) { + colorProfile = _colorProfilesDict[logMessage->_tag]; + } + + if (colorProfile == nil) { + for (DDTTYLoggerColorProfile *cp in _colorProfilesArray) { + if (logMessage->_flag & cp->mask) { + // Color profile set for this context? + if (logMessage->_context == cp->context) { + colorProfile = cp; + + // Stop searching + break; + } + + // Check if LOG_CONTEXT_ALL was specified as a default color for this flag + if (cp->context == LOG_CONTEXT_ALL) { + colorProfile = cp; + + // We don't break to keep searching for more specific color profiles for the context + } + } + } + } + } + + // Convert log message to C string. + // + // We use the stack instead of the heap for speed if possible. + // But we're extra cautious to avoid a stack overflow. + + NSUInteger msgLen = [logMsg lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + const BOOL useStack = msgLen < (1024 * 4); + + char msgStack[useStack ? (msgLen + 1) : 1]; // Analyzer doesn't like zero-size array, hence the 1 + char *msg = useStack ? msgStack : (char *)calloc(msgLen + 1, sizeof(char)); + + if (msg == NULL) { + return; + } + + BOOL logMsgEnc = [logMsg getCString:msg maxLength:(msgLen + 1) encoding:NSUTF8StringEncoding]; + + if (!logMsgEnc) { + if (!useStack && msg != NULL) { + free(msg); + } + + return; + } + + // Write the log message to STDERR + + if (isFormatted) { + // The log message has already been formatted. + int iovec_len = (_automaticallyAppendNewlineForCustomFormatters) ? 5 : 4; + struct iovec v[iovec_len]; + + if (colorProfile) { + v[0].iov_base = colorProfile->fgCode; + v[0].iov_len = colorProfile->fgCodeLen; + + v[1].iov_base = colorProfile->bgCode; + v[1].iov_len = colorProfile->bgCodeLen; + + v[iovec_len - 1].iov_base = colorProfile->resetCode; + v[iovec_len - 1].iov_len = colorProfile->resetCodeLen; + } else { + v[0].iov_base = ""; + v[0].iov_len = 0; + + v[1].iov_base = ""; + v[1].iov_len = 0; + + v[iovec_len - 1].iov_base = ""; + v[iovec_len - 1].iov_len = 0; + } + + v[2].iov_base = (char *)msg; + v[2].iov_len = msgLen; + + if (iovec_len == 5) { + v[3].iov_base = "\n"; + v[3].iov_len = (msg[msgLen] == '\n') ? 0 : 1; + } + + writev(STDERR_FILENO, v, iovec_len); + } else { + // The log message is unformatted, so apply standard NSLog style formatting. + + int len; + char ts[24] = ""; + size_t tsLen = 0; + + // Calculate timestamp. + // The technique below is faster than using NSDateFormatter. + if (logMessage->_timestamp) { + NSTimeInterval epoch = [logMessage->_timestamp timeIntervalSince1970]; + struct tm tm; + time_t time = (time_t)epoch; + (void)localtime_r(&time, &tm); + int milliseconds = (int)((epoch - floor(epoch)) * 1000.0); + + len = snprintf(ts, 24, "%04d-%02d-%02d %02d:%02d:%02d:%03d", // yyyy-MM-dd HH:mm:ss:SSS + tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec, milliseconds); + + tsLen = (NSUInteger)MAX(MIN(24 - 1, len), 0); + } + + // Calculate thread ID + // + // How many characters do we need for the thread id? + // logMessage->machThreadID is of type mach_port_t, which is an unsigned int. + // + // 1 hex char = 4 bits + // 8 hex chars for 32 bit, plus ending '\0' = 9 + + char tid[9]; + len = snprintf(tid, 9, "%s", [logMessage->_threadID cStringUsingEncoding:NSUTF8StringEncoding]); + + size_t tidLen = (NSUInteger)MAX(MIN(9 - 1, len), 0); + + // Here is our format: "%s %s[%i:%s] %s", timestamp, appName, processID, threadID, logMsg + + struct iovec v[13]; + + if (colorProfile) { + v[0].iov_base = colorProfile->fgCode; + v[0].iov_len = colorProfile->fgCodeLen; + + v[1].iov_base = colorProfile->bgCode; + v[1].iov_len = colorProfile->bgCodeLen; + + v[12].iov_base = colorProfile->resetCode; + v[12].iov_len = colorProfile->resetCodeLen; + } else { + v[0].iov_base = ""; + v[0].iov_len = 0; + + v[1].iov_base = ""; + v[1].iov_len = 0; + + v[12].iov_base = ""; + v[12].iov_len = 0; + } + + v[2].iov_base = ts; + v[2].iov_len = tsLen; + + v[3].iov_base = " "; + v[3].iov_len = 1; + + v[4].iov_base = _app; + v[4].iov_len = _appLen; + + v[5].iov_base = "["; + v[5].iov_len = 1; + + v[6].iov_base = _pid; + v[6].iov_len = _pidLen; + + v[7].iov_base = ":"; + v[7].iov_len = 1; + + v[8].iov_base = tid; + v[8].iov_len = MIN((size_t)8, tidLen); // snprintf doesn't return what you might think + + v[9].iov_base = "] "; + v[9].iov_len = 2; + + v[10].iov_base = (char *)msg; + v[10].iov_len = msgLen; + + v[11].iov_base = "\n"; + v[11].iov_len = (msg[msgLen] == '\n') ? 0 : 1; + + writev(STDERR_FILENO, v, 13); + } + + if (!useStack) { + free(msg); + } + } +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@implementation DDTTYLoggerColorProfile + +- (instancetype)initWithForegroundColor:(DDColor *)fgColor backgroundColor:(DDColor *)bgColor flag:(DDLogFlag)aMask context:(NSInteger)ctxt { + if ((self = [super init])) { + mask = aMask; + context = ctxt; + + CGFloat r, g, b; + + if (fgColor) { + [DDTTYLogger getRed:&r green:&g blue:&b fromColor:fgColor]; + + fg_r = (uint8_t)(r * 255.0f); + fg_g = (uint8_t)(g * 255.0f); + fg_b = (uint8_t)(b * 255.0f); + } + + if (bgColor) { + [DDTTYLogger getRed:&r green:&g blue:&b fromColor:bgColor]; + + bg_r = (uint8_t)(r * 255.0f); + bg_g = (uint8_t)(g * 255.0f); + bg_b = (uint8_t)(b * 255.0f); + } + + if (fgColor && isaColorTTY) { + // Map foreground color to closest available shell color + + fgCodeIndex = [DDTTYLogger codeIndexForColor:fgColor]; + fgCodeRaw = codes_fg[fgCodeIndex]; + + NSString *escapeSeq = @"\033["; + + NSUInteger len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + NSUInteger len2 = [fgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + BOOL escapeSeqEnc = [escapeSeq getCString:(fgCode) maxLength:(len1 + 1) encoding:NSUTF8StringEncoding]; + BOOL fgCodeRawEsc = [fgCodeRaw getCString:(fgCode + len1) maxLength:(len2 + 1) encoding:NSUTF8StringEncoding]; + + if (!escapeSeqEnc || !fgCodeRawEsc) { + return nil; + } + + fgCodeLen = len1 + len2; + } else if (fgColor && isaXcodeColorTTY) { + // Convert foreground color to color code sequence + + const char *escapeSeq = XCODE_COLORS_ESCAPE_SEQ; + + int result = snprintf(fgCode, 24, "%sfg%u,%u,%u;", escapeSeq, fg_r, fg_g, fg_b); + fgCodeLen = (NSUInteger)MAX(MIN(result, (24 - 1)), 0); + } else { + // No foreground color or no color support + + fgCode[0] = '\0'; + fgCodeLen = 0; + } + + if (bgColor && isaColorTTY) { + // Map background color to closest available shell color + + bgCodeIndex = [DDTTYLogger codeIndexForColor:bgColor]; + bgCodeRaw = codes_bg[bgCodeIndex]; + + NSString *escapeSeq = @"\033["; + + NSUInteger len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + NSUInteger len2 = [bgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + BOOL escapeSeqEnc = [escapeSeq getCString:(bgCode) maxLength:(len1 + 1) encoding:NSUTF8StringEncoding]; + BOOL bgCodeRawEsc = [bgCodeRaw getCString:(bgCode + len1) maxLength:(len2 + 1) encoding:NSUTF8StringEncoding]; + + if (!escapeSeqEnc || !bgCodeRawEsc) { + return nil; + } + + bgCodeLen = len1 + len2; + } else if (bgColor && isaXcodeColorTTY) { + // Convert background color to color code sequence + + const char *escapeSeq = XCODE_COLORS_ESCAPE_SEQ; + + int result = snprintf(bgCode, 24, "%sbg%u,%u,%u;", escapeSeq, bg_r, bg_g, bg_b); + bgCodeLen = (NSUInteger)MAX(MIN(result, (24 - 1)), 0); + } else { + // No background color or no color support + + bgCode[0] = '\0'; + bgCodeLen = 0; + } + + if (isaColorTTY) { + resetCodeLen = (NSUInteger)MAX(snprintf(resetCode, 8, "\033[0m"), 0); + } else if (isaXcodeColorTTY) { + resetCodeLen = (NSUInteger)MAX(snprintf(resetCode, 8, XCODE_COLORS_RESET), 0); + } else { + resetCode[0] = '\0'; + resetCodeLen = 0; + } + } + + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat: + @"", + self, (int)mask, (long)context, fg_r, fg_g, fg_b, bg_r, bg_g, bg_b, fgCodeRaw, bgCodeRaw]; +} + +@end diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDContextFilterLogFormatter.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDContextFilterLogFormatter.m new file mode 100755 index 0000000..4cac5e1 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDContextFilterLogFormatter.m @@ -0,0 +1,196 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +#import + +#import + +@interface DDLoggingContextSet : NSObject + +@property (readonly, copy, nonnull) NSArray *currentSet; + +- (void)addToSet:(NSInteger)loggingContext; +- (void)removeFromSet:(NSInteger)loggingContext; + +- (BOOL)isInSet:(NSInteger)loggingContext; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface DDContextWhitelistFilterLogFormatter () { + DDLoggingContextSet *_contextSet; +} +@end + + +@implementation DDContextWhitelistFilterLogFormatter + +- (instancetype)init { + if ((self = [super init])) { + _contextSet = [[DDLoggingContextSet alloc] init]; + } + + return self; +} + +- (void)addToWhitelist:(NSInteger)loggingContext { + [_contextSet addToSet:loggingContext]; +} + +- (void)removeFromWhitelist:(NSInteger)loggingContext { + [_contextSet removeFromSet:loggingContext]; +} + +- (NSArray *)whitelist { + return [_contextSet currentSet]; +} + +- (BOOL)isOnWhitelist:(NSInteger)loggingContext { + return [_contextSet isInSet:loggingContext]; +} + +- (NSString *)formatLogMessage:(DDLogMessage *)logMessage { + if ([self isOnWhitelist:logMessage->_context]) { + return logMessage->_message; + } else { + return nil; + } +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface DDContextBlacklistFilterLogFormatter () { + DDLoggingContextSet *_contextSet; +} + +@end + + +@implementation DDContextBlacklistFilterLogFormatter + +- (instancetype)init { + if ((self = [super init])) { + _contextSet = [[DDLoggingContextSet alloc] init]; + } + + return self; +} + +- (void)addToBlacklist:(NSInteger)loggingContext { + [_contextSet addToSet:loggingContext]; +} + +- (void)removeFromBlacklist:(NSInteger)loggingContext { + [_contextSet removeFromSet:loggingContext]; +} + +- (NSArray *)blacklist { + return [_contextSet currentSet]; +} + +- (BOOL)isOnBlacklist:(NSInteger)loggingContext { + return [_contextSet isInSet:loggingContext]; +} + +- (NSString *)formatLogMessage:(DDLogMessage *)logMessage { + if ([self isOnBlacklist:logMessage->_context]) { + return nil; + } else { + return logMessage->_message; + } +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +@interface DDLoggingContextSet () { + pthread_mutex_t _mutex; + NSMutableSet *_set; +} + +@end + + +@implementation DDLoggingContextSet + +- (instancetype)init { + if ((self = [super init])) { + _set = [[NSMutableSet alloc] init]; + pthread_mutex_init(&_mutex, NULL); + } + + return self; +} + +- (void)dealloc { + pthread_mutex_destroy(&_mutex); +} + +- (void)addToSet:(NSInteger)loggingContext { + pthread_mutex_lock(&_mutex); + { + [_set addObject:@(loggingContext)]; + } + pthread_mutex_unlock(&_mutex); +} + +- (void)removeFromSet:(NSInteger)loggingContext { + pthread_mutex_lock(&_mutex); + { + [_set removeObject:@(loggingContext)]; + } + pthread_mutex_unlock(&_mutex); +} + +- (NSArray *)currentSet { + NSArray *result = nil; + + pthread_mutex_lock(&_mutex); + { + result = [_set allObjects]; + } + pthread_mutex_unlock(&_mutex); + + return result; +} + +- (BOOL)isInSet:(NSInteger)loggingContext { + BOOL result = NO; + + pthread_mutex_lock(&_mutex); + { + result = [_set containsObject:@(loggingContext)]; + } + pthread_mutex_unlock(&_mutex); + + return result; +} + +@end diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDDispatchQueueLogFormatter.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDDispatchQueueLogFormatter.m new file mode 100755 index 0000000..4a9f712 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDDispatchQueueLogFormatter.m @@ -0,0 +1,269 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +#import +#import +#import + +#import + +DDQualityOfServiceName const DDQualityOfServiceUserInteractive = @"UI"; +DDQualityOfServiceName const DDQualityOfServiceUserInitiated = @"IN"; +DDQualityOfServiceName const DDQualityOfServiceDefault = @"DF"; +DDQualityOfServiceName const DDQualityOfServiceUtility = @"UT"; +DDQualityOfServiceName const DDQualityOfServiceBackground = @"BG"; +DDQualityOfServiceName const DDQualityOfServiceUnspecified = @"UN"; + +static DDQualityOfServiceName _qos_name(NSUInteger qos) { + switch ((qos_class_t) qos) { + case QOS_CLASS_USER_INTERACTIVE: return DDQualityOfServiceUserInteractive; + case QOS_CLASS_USER_INITIATED: return DDQualityOfServiceUserInitiated; + case QOS_CLASS_DEFAULT: return DDQualityOfServiceDefault; + case QOS_CLASS_UTILITY: return DDQualityOfServiceUtility; + case QOS_CLASS_BACKGROUND: return DDQualityOfServiceBackground; + default: return DDQualityOfServiceUnspecified; + } +} + +#pragma mark - DDDispatchQueueLogFormatter + +@interface DDDispatchQueueLogFormatter () { + NSDateFormatter *_dateFormatter; // Use [self stringFromDate] + + pthread_mutex_t _mutex; + + NSUInteger _minQueueLength; // _prefix == Only access via atomic property + NSUInteger _maxQueueLength; // _prefix == Only access via atomic property + NSMutableDictionary *_replacements; // _prefix == Only access from within spinlock +} +@end + + +@implementation DDDispatchQueueLogFormatter + +- (instancetype)init { + if ((self = [super init])) { + _dateFormatter = [self createDateFormatter]; + + pthread_mutex_init(&_mutex, NULL); + _replacements = [[NSMutableDictionary alloc] init]; + + // Set default replacements: + _replacements[@"com.apple.main-thread"] = @"main"; + } + + return self; +} + +- (instancetype)initWithMode:(DDDispatchQueueLogFormatterMode)mode { + return [self init]; +} + +- (void)dealloc { + pthread_mutex_destroy(&_mutex); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Configuration +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@synthesize minQueueLength = _minQueueLength; +@synthesize maxQueueLength = _maxQueueLength; + +- (NSString *)replacementStringForQueueLabel:(NSString *)longLabel { + NSString *result = nil; + + pthread_mutex_lock(&_mutex); + { + result = _replacements[longLabel]; + } + pthread_mutex_unlock(&_mutex); + + return result; +} + +- (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel { + pthread_mutex_lock(&_mutex); + { + if (shortLabel) { + _replacements[longLabel] = shortLabel; + } else { + [_replacements removeObjectForKey:longLabel]; + } + } + pthread_mutex_unlock(&_mutex); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark DDLogFormatter +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +- (NSDateFormatter *)createDateFormatter { + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + [self configureDateFormatter:formatter]; + return formatter; +} + +- (void)configureDateFormatter:(NSDateFormatter *)dateFormatter { + [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss:SSS"]; + [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; + [dateFormatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]]; +} + +- (NSString *)stringFromDate:(NSDate *)date { + return [_dateFormatter stringFromDate:date]; +} + +- (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage { + // As per the DDLogFormatter contract, this method is always invoked on the same thread/dispatch_queue + + NSUInteger minQueueLength = self.minQueueLength; + NSUInteger maxQueueLength = self.maxQueueLength; + + // Get the name of the queue, thread, or machID (whichever we are to use). + + NSString *queueThreadLabel = nil; + + BOOL useQueueLabel = YES; + BOOL useThreadName = NO; + + if (logMessage->_queueLabel) { + // If you manually create a thread, it's dispatch_queue will have one of the thread names below. + // Since all such threads have the same name, we'd prefer to use the threadName or the machThreadID. + + NSArray *names = @[ + @"com.apple.root.low-priority", + @"com.apple.root.default-priority", + @"com.apple.root.high-priority", + @"com.apple.root.low-overcommit-priority", + @"com.apple.root.default-overcommit-priority", + @"com.apple.root.high-overcommit-priority", + @"com.apple.root.default-qos.overcommit" + ]; + + for (NSString * name in names) { + if ([logMessage->_queueLabel isEqualToString:name]) { + useQueueLabel = NO; + useThreadName = [logMessage->_threadName length] > 0; + break; + } + } + } else { + useQueueLabel = NO; + useThreadName = [logMessage->_threadName length] > 0; + } + + if (useQueueLabel || useThreadName) { + NSString *fullLabel; + NSString *abrvLabel; + + if (useQueueLabel) { + fullLabel = logMessage->_queueLabel; + } else { + fullLabel = logMessage->_threadName; + } + + pthread_mutex_lock(&_mutex); + { + abrvLabel = _replacements[fullLabel]; + } + pthread_mutex_unlock(&_mutex); + + if (abrvLabel) { + queueThreadLabel = abrvLabel; + } else { + queueThreadLabel = fullLabel; + } + } else { + queueThreadLabel = logMessage->_threadID; + } + + // Now use the thread label in the output + + NSUInteger labelLength = [queueThreadLabel length]; + + // labelLength > maxQueueLength : truncate + // labelLength < minQueueLength : padding + // : exact + + if ((maxQueueLength > 0) && (labelLength > maxQueueLength)) { + // Truncate + + return [queueThreadLabel substringToIndex:maxQueueLength]; + } else if (labelLength < minQueueLength) { + // Padding + + NSUInteger numSpaces = minQueueLength - labelLength; + + char spaces[numSpaces + 1]; + memset(spaces, ' ', numSpaces); + spaces[numSpaces] = '\0'; + + return [NSString stringWithFormat:@"%@%s", queueThreadLabel, spaces]; + } else { + // Exact + + return queueThreadLabel; + } +} + +- (NSString *)formatLogMessage:(DDLogMessage *)logMessage { + NSString *timestamp = [self stringFromDate:(logMessage->_timestamp)]; + NSString *queueThreadLabel = [self queueThreadLabelForLogMessage:logMessage]; + + return [NSString stringWithFormat:@"%@ [%@ (QOS:%@)] %@", timestamp, queueThreadLabel, _qos_name(logMessage->_qos), logMessage->_message]; +} + +@end + +#pragma mark - DDAtomicCounter + +@interface DDAtomicCounter() { + atomic_int_fast32_t _value; +} +@end + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" +@implementation DDAtomicCounter +#pragma clang diagnostic pop + +- (instancetype)initWithDefaultValue:(int32_t)defaultValue { + if ((self = [super init])) { + atomic_init(&_value, defaultValue); + } + return self; +} + +- (int32_t)value { + return atomic_load_explicit(&_value, memory_order_relaxed); +} + +- (int32_t)increment { + int32_t old = atomic_fetch_add_explicit(&_value, 1, memory_order_relaxed); + return (old + 1); +} + +- (int32_t)decrement { + int32_t old = atomic_fetch_sub_explicit(&_value, 1, memory_order_relaxed); + return (old - 1); +} + +@end diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDFileLogger+Buffering.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDFileLogger+Buffering.m new file mode 100644 index 0000000..3a2796b --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDFileLogger+Buffering.m @@ -0,0 +1,204 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#import + +#import +#import "../DDFileLogger+Internal.h" + +static const NSUInteger kDDDefaultBufferSize = 4096; // 4 kB, block f_bsize on iphone7 +static const NSUInteger kDDMaxBufferSize = 1048576; // ~1 mB, f_iosize on iphone7 + +// Reads attributes from base file system to determine buffer size. +// see statfs in sys/mount.h for descriptions of f_iosize and f_bsize. +// f_bsize == "default", and f_iosize == "max" +static inline NSUInteger p_DDGetDefaultBufferSizeBytesMax(const BOOL max) { + struct statfs *mountedFileSystems = NULL; + int count = getmntinfo(&mountedFileSystems, 0); + + for (int i = 0; i < count; i++) { + struct statfs mounted = mountedFileSystems[i]; + const char *name = mounted.f_mntonname; + + // We can use 2 as max here, since any length > 1 will fail the if-statement. + if (strnlen(name, 2) == 1 && *name == '/') { + return max ? (NSUInteger)mounted.f_iosize : (NSUInteger)mounted.f_bsize; + } + } + + return max ? kDDMaxBufferSize : kDDDefaultBufferSize; +} + +static NSUInteger DDGetMaxBufferSizeBytes() { + static NSUInteger maxBufferSize = 0; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + maxBufferSize = p_DDGetDefaultBufferSizeBytesMax(YES); + }); + return maxBufferSize; +} + +static NSUInteger DDGetDefaultBufferSizeBytes() { + static NSUInteger defaultBufferSize = 0; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + defaultBufferSize = p_DDGetDefaultBufferSizeBytesMax(NO); + }); + return defaultBufferSize; +} + +@interface DDBufferedProxy : NSProxy + +@property (nonatomic) DDFileLogger *fileLogger; +@property (nonatomic) NSOutputStream *buffer; + +@property (nonatomic) NSUInteger maxBufferSizeBytes; +@property (nonatomic) NSUInteger currentBufferSizeBytes; + +@end + +@implementation DDBufferedProxy + +- (instancetype)initWithFileLogger:(DDFileLogger *)fileLogger { + _fileLogger = fileLogger; + _maxBufferSizeBytes = DDGetDefaultBufferSizeBytes(); + [self flushBuffer]; + + return self; +} + +- (void)dealloc { + dispatch_block_t block = ^{ + [self lt_sendBufferedDataToFileLogger]; + self.fileLogger = nil; + }; + + if ([self->_fileLogger isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_sync(self->_fileLogger.loggerQueue, block); + } +} + +#pragma mark - Buffering + +- (void)flushBuffer { + [_buffer close]; + _buffer = [NSOutputStream outputStreamToMemory]; + [_buffer open]; + _currentBufferSizeBytes = 0; +} + +- (void)lt_sendBufferedDataToFileLogger { + NSData *data = [_buffer propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; + [_fileLogger lt_logData:data]; + [self flushBuffer]; +} + +#pragma mark - Logging + +- (void)logMessage:(DDLogMessage *)logMessage { + // Don't need to check for isOnInternalLoggerQueue, -lt_dataForMessage: will do it for us. + NSData *data = [_fileLogger lt_dataForMessage:logMessage]; + + if (data.length == 0) { + return; + } + + [data enumerateByteRangesUsingBlock:^(const void * __nonnull bytes, NSRange byteRange, BOOL * __nonnull __unused stop) { + NSUInteger bytesLength = byteRange.length; +#ifdef NS_BLOCK_ASSERTIONS + __unused +#endif + NSInteger written = [_buffer write:bytes maxLength:bytesLength]; + NSAssert(written > 0 && (NSUInteger)written == bytesLength, @"Failed to write to memory buffer."); + + _currentBufferSizeBytes += bytesLength; + + if (_currentBufferSizeBytes >= _maxBufferSizeBytes) { + [self lt_sendBufferedDataToFileLogger]; + } + }]; +} + +- (void)flush { + // This method is public. + // We need to execute the rolling on our logging thread/queue. + + dispatch_block_t block = ^{ + @autoreleasepool { + [self lt_sendBufferedDataToFileLogger]; + [self.fileLogger flush]; + } + }; + + // The design of this method is taken from the DDAbstractLogger implementation. + // For extensive documentation please refer to the DDAbstractLogger implementation. + + if ([self.fileLogger isOnInternalLoggerQueue]) { + block(); + } else { + dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue]; + NSAssert(![self.fileLogger isOnGlobalLoggingQueue], @"Core architecture requirement failure"); + + dispatch_sync(globalLoggingQueue, ^{ + dispatch_sync(self.fileLogger.loggerQueue, block); + }); + } +} + +#pragma mark - Properties + +- (void)setMaxBufferSizeBytes:(NSUInteger)newBufferSizeBytes { + _maxBufferSizeBytes = MIN(newBufferSizeBytes, DDGetMaxBufferSizeBytes()); +} + +#pragma mark - Wrapping + +- (DDFileLogger *)wrapWithBuffer { + return (DDFileLogger *)self; +} + +- (DDFileLogger *)unwrapFromBuffer { + return (DDFileLogger *)self.fileLogger; +} + +#pragma mark - NSProxy + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel { + return [self.fileLogger methodSignatureForSelector:sel]; +} + +- (BOOL)respondsToSelector:(SEL)aSelector { + return [self.fileLogger respondsToSelector:aSelector]; +} + +- (void)forwardInvocation:(NSInvocation *)invocation { + [invocation invokeWithTarget:self.fileLogger]; +} + +@end + +@implementation DDFileLogger (Buffering) + +- (instancetype)wrapWithBuffer { + return (DDFileLogger *)[[DDBufferedProxy alloc] initWithFileLogger:self]; +} + +- (instancetype)unwrapFromBuffer { + return self; +} + +@end diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDMultiFormatter.m b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDMultiFormatter.m new file mode 100644 index 0000000..776dd6f --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Extensions/DDMultiFormatter.m @@ -0,0 +1,111 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). +#endif + +#import + +@interface DDMultiFormatter () { + dispatch_queue_t _queue; + NSMutableArray *_formatters; +} + +- (DDLogMessage *)logMessageForLine:(NSString *)line originalMessage:(DDLogMessage *)message; + +@end + + +@implementation DDMultiFormatter + +- (instancetype)init { + self = [super init]; + + if (self) { + _queue = dispatch_queue_create("cocoa.lumberjack.multiformatter", DISPATCH_QUEUE_CONCURRENT); + _formatters = [NSMutableArray new]; + } + + return self; +} + +#pragma mark Processing + +- (NSString *)formatLogMessage:(DDLogMessage *)logMessage { + __block NSString *line = logMessage->_message; + + dispatch_sync(_queue, ^{ + for (id formatter in self->_formatters) { + DDLogMessage *message = [self logMessageForLine:line originalMessage:logMessage]; + line = [formatter formatLogMessage:message]; + + if (!line) { + break; + } + } + }); + + return line; +} + +- (DDLogMessage *)logMessageForLine:(NSString *)line originalMessage:(DDLogMessage *)message { + DDLogMessage *newMessage = [message copy]; + + newMessage->_message = line; + return newMessage; +} + +#pragma mark Formatters + +- (NSArray *)formatters { + __block NSArray *formatters; + + dispatch_sync(_queue, ^{ + formatters = [self->_formatters copy]; + }); + + return formatters; +} + +- (void)addFormatter:(id)formatter { + dispatch_barrier_async(_queue, ^{ + [self->_formatters addObject:formatter]; + }); +} + +- (void)removeFormatter:(id)formatter { + dispatch_barrier_async(_queue, ^{ + [self->_formatters removeObject:formatter]; + }); +} + +- (void)removeAllFormatters { + dispatch_barrier_async(_queue, ^{ + [self->_formatters removeAllObjects]; + }); +} + +- (BOOL)isFormattingWithFormatter:(id)formatter { + __block BOOL hasFormatter; + + dispatch_sync(_queue, ^{ + hasFormatter = [self->_formatters containsObject:formatter]; + }); + + return hasFormatter; +} + +@end diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Supporting Files/CocoaLumberjack.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Supporting Files/CocoaLumberjack.h new file mode 100644 index 0000000..734d6f7 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Supporting Files/CocoaLumberjack.h @@ -0,0 +1,103 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +/** + * Welcome to CocoaLumberjack! + * + * The project page has a wealth of documentation if you have any questions. + * https://github.com/CocoaLumberjack/CocoaLumberjack + * + * If you're new to the project you may wish to read "Getting Started" at: + * Documentation/GettingStarted.md + * + * Otherwise, here is a quick refresher. + * There are three steps to using the macros: + * + * Step 1: + * Import the header in your implementation or prefix file: + * + * #import + * + * Step 2: + * Define your logging level in your implementation file: + * + * // Log levels: off, error, warn, info, verbose + * static const DDLogLevel ddLogLevel = DDLogLevelVerbose; + * + * Step 2 [3rd party frameworks]: + * + * Define your LOG_LEVEL_DEF to a different variable/function than ddLogLevel: + * + * // #undef LOG_LEVEL_DEF // Undefine first only if needed + * #define LOG_LEVEL_DEF myLibLogLevel + * + * Define your logging level in your implementation file: + * + * // Log levels: off, error, warn, info, verbose + * static const DDLogLevel myLibLogLevel = DDLogLevelVerbose; + * + * Step 3: + * Replace your NSLog statements with DDLog statements according to the severity of the message. + * + * NSLog(@"Fatal error, no dohickey found!"); -> DDLogError(@"Fatal error, no dohickey found!"); + * + * DDLog works exactly the same as NSLog. + * This means you can pass it multiple variables just like NSLog. + **/ + +#import + +//! Project version number for CocoaLumberjack. +FOUNDATION_EXPORT double CocoaLumberjackVersionNumber; + +//! Project version string for CocoaLumberjack. +FOUNDATION_EXPORT const unsigned char CocoaLumberjackVersionString[]; + +// Disable legacy macros +#ifndef DD_LEGACY_MACROS + #define DD_LEGACY_MACROS 0 +#endif + +// Core +#import + +// Main macros +#import +#import + +// Capture ASL +#import + +// Loggers +#import + +#import +#import +#import +#import + +// Extensions +#import +#import +#import +#import + +// CLI +#import + +// etc +#import +#import +#import diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Supporting Files/DDLegacyMacros.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Supporting Files/DDLegacyMacros.h new file mode 100644 index 0000000..a6f7ee0 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/Supporting Files/DDLegacyMacros.h @@ -0,0 +1,75 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +/** + * Legacy macros used for 1.9.x backwards compatibility. + * + * Imported by default when importing a DDLog.h directly and DD_LEGACY_MACROS is not defined and set to 0. + **/ +#if DD_LEGACY_MACROS + +#warning CocoaLumberjack 1.9.x legacy macros enabled. \ +Disable legacy macros by importing CocoaLumberjack.h or DDLogMacros.h instead of DDLog.h or add `#define DD_LEGACY_MACROS 0` before importing DDLog.h. + +#ifndef LOG_LEVEL_DEF + #define LOG_LEVEL_DEF ddLogLevel +#endif + +#define LOG_FLAG_ERROR DDLogFlagError +#define LOG_FLAG_WARN DDLogFlagWarning +#define LOG_FLAG_INFO DDLogFlagInfo +#define LOG_FLAG_DEBUG DDLogFlagDebug +#define LOG_FLAG_VERBOSE DDLogFlagVerbose + +#define LOG_LEVEL_OFF DDLogLevelOff +#define LOG_LEVEL_ERROR DDLogLevelError +#define LOG_LEVEL_WARN DDLogLevelWarning +#define LOG_LEVEL_INFO DDLogLevelInfo +#define LOG_LEVEL_DEBUG DDLogLevelDebug +#define LOG_LEVEL_VERBOSE DDLogLevelVerbose +#define LOG_LEVEL_ALL DDLogLevelAll + +#define LOG_ASYNC_ENABLED YES + +#define LOG_ASYNC_ERROR ( NO && LOG_ASYNC_ENABLED) +#define LOG_ASYNC_WARN (YES && LOG_ASYNC_ENABLED) +#define LOG_ASYNC_INFO (YES && LOG_ASYNC_ENABLED) +#define LOG_ASYNC_DEBUG (YES && LOG_ASYNC_ENABLED) +#define LOG_ASYNC_VERBOSE (YES && LOG_ASYNC_ENABLED) + +#define LOG_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, ...) \ + [DDLog log : isAsynchronous \ + level : lvl \ + flag : flg \ + context : ctx \ + file : __FILE__ \ + function : fnct \ + line : __LINE__ \ + tag : atag \ + format : (frmt), ## __VA_ARGS__] + +#define LOG_MAYBE(async, lvl, flg, ctx, fnct, frmt, ...) \ + do { if((lvl & flg) != 0) LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0) + +#define LOG_OBJC_MAYBE(async, lvl, flg, ctx, frmt, ...) \ + LOG_MAYBE(async, lvl, flg, ctx, __PRETTY_FUNCTION__, frmt, ## __VA_ARGS__) + +#define DDLogError(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_ERROR, LOG_LEVEL_DEF, LOG_FLAG_ERROR, 0, frmt, ##__VA_ARGS__) +#define DDLogWarn(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_WARN, LOG_LEVEL_DEF, LOG_FLAG_WARN, 0, frmt, ##__VA_ARGS__) +#define DDLogInfo(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_INFO, LOG_LEVEL_DEF, LOG_FLAG_INFO, 0, frmt, ##__VA_ARGS__) +#define DDLogDebug(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_DEBUG, LOG_LEVEL_DEF, LOG_FLAG_DEBUG, 0, frmt, ##__VA_ARGS__) +#define DDLogVerbose(frmt, ...) LOG_OBJC_MAYBE(LOG_ASYNC_VERBOSE, LOG_LEVEL_DEF, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__) + +#endif diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/CLIColor.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/CLIColor.h new file mode 100644 index 0000000..85e5991 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/CLIColor.h @@ -0,0 +1,52 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#if TARGET_OS_OSX + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class represents an NSColor replacement for CLI projects that don't link with AppKit + **/ +@interface CLIColor : NSObject + +/** + * Convenience method for creating a `CLIColor` instance from RGBA params + * + * @param red red channel, between 0 and 1 + * @param green green channel, between 0 and 1 + * @param blue blue channel, between 0 and 1 + * @param alpha alpha channel, between 0 and 1 + */ ++ (instancetype)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha; + +/** + * Get the RGBA components from a `CLIColor` + * + * @param red red channel, between 0 and 1 + * @param green green channel, between 0 and 1 + * @param blue blue channel, between 0 and 1 + * @param alpha alpha channel, between 0 and 1 + */ +- (void)getRed:(nullable CGFloat *)red green:(nullable CGFloat *)green blue:(nullable CGFloat *)blue alpha:(nullable CGFloat *)alpha NS_SWIFT_NAME(get(red:green:blue:alpha:)); + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDASLLogCapture.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDASLLogCapture.h new file mode 100644 index 0000000..fa67bc4 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDASLLogCapture.h @@ -0,0 +1,46 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#import + +@protocol DDLogger; + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class provides the ability to capture the ASL (Apple System Logs) + */ +API_DEPRECATED("Use DDOSLogger instead", macosx(10.4,10.12), ios(2.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0)) +@interface DDASLLogCapture : NSObject + +/** + * Start capturing logs + */ ++ (void)start; + +/** + * Stop capturing logs + */ ++ (void)stop; + +/** + * The current capture level. + * @note Default log level: DDLogLevelVerbose (i.e. capture all ASL messages). + */ +@property (class) DDLogLevel captureLevel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDASLLogger.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDASLLogger.h new file mode 100644 index 0000000..c1ab1be --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDASLLogger.h @@ -0,0 +1,63 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#import + +// Disable legacy macros +#ifndef DD_LEGACY_MACROS + #define DD_LEGACY_MACROS 0 +#endif + +#import + +NS_ASSUME_NONNULL_BEGIN + +// Custom key set on messages sent to ASL +extern const char* const kDDASLKeyDDLog; + +// Value set for kDDASLKeyDDLog +extern const char* const kDDASLDDLogValue; + +/** + * This class provides a logger for the Apple System Log facility. + * + * As described in the "Getting Started" page, + * the traditional NSLog() function directs its output to two places: + * + * - Apple System Log + * - StdErr (if stderr is a TTY) so log statements show up in Xcode console + * + * To duplicate NSLog() functionality you can simply add this logger and a tty logger. + * However, if you instead choose to use file logging (for faster performance), + * you may choose to use a file logger and a tty logger. + **/ +API_DEPRECATED("Use DDOSLogger instead", macosx(10.4,10.12), ios(2.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0)) +@interface DDASLLogger : DDAbstractLogger + +/** + * Singleton method + * + * @return the shared instance + */ +@property (nonatomic, class, readonly, strong) DDASLLogger *sharedInstance; + +// Inherited from DDAbstractLogger + +// - (id )logFormatter; +// - (void)setLogFormatter:(id )formatter; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDAbstractDatabaseLogger.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDAbstractDatabaseLogger.h new file mode 100644 index 0000000..e191ddc --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDAbstractDatabaseLogger.h @@ -0,0 +1,127 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +// Disable legacy macros +#ifndef DD_LEGACY_MACROS + #define DD_LEGACY_MACROS 0 +#endif + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class provides an abstract implementation of a database logger. + * + * That is, it provides the base implementation for a database logger to build atop of. + * All that is needed for a concrete database logger is to extend this class + * and override the methods in the implementation file that are prefixed with "db_". + **/ +@interface DDAbstractDatabaseLogger : DDAbstractLogger { + +@protected + NSUInteger _saveThreshold; + NSTimeInterval _saveInterval; + NSTimeInterval _maxAge; + NSTimeInterval _deleteInterval; + BOOL _deleteOnEverySave; + + NSInteger _saveTimerSuspended; + NSUInteger _unsavedCount; + dispatch_time_t _unsavedTime; + dispatch_source_t _saveTimer; + dispatch_time_t _lastDeleteTime; + dispatch_source_t _deleteTimer; +} + +/** + * Specifies how often to save the data to disk. + * Since saving is an expensive operation (disk io) it is not done after every log statement. + * These properties allow you to configure how/when the logger saves to disk. + * + * A save is done when either (whichever happens first): + * + * - The number of unsaved log entries reaches saveThreshold + * - The amount of time since the oldest unsaved log entry was created reaches saveInterval + * + * You can optionally disable the saveThreshold by setting it to zero. + * If you disable the saveThreshold you are entirely dependent on the saveInterval. + * + * You can optionally disable the saveInterval by setting it to zero (or a negative value). + * If you disable the saveInterval you are entirely dependent on the saveThreshold. + * + * It's not wise to disable both saveThreshold and saveInterval. + * + * The default saveThreshold is 500. + * The default saveInterval is 60 seconds. + **/ +@property (assign, readwrite) NSUInteger saveThreshold; + +/** + * See the description for the `saveThreshold` property + */ +@property (assign, readwrite) NSTimeInterval saveInterval; + +/** + * It is likely you don't want the log entries to persist forever. + * Doing so would allow the database to grow infinitely large over time. + * + * The maxAge property provides a way to specify how old a log statement can get + * before it should get deleted from the database. + * + * The deleteInterval specifies how often to sweep for old log entries. + * Since deleting is an expensive operation (disk io) is is done on a fixed interval. + * + * An alternative to the deleteInterval is the deleteOnEverySave option. + * This specifies that old log entries should be deleted during every save operation. + * + * You can optionally disable the maxAge by setting it to zero (or a negative value). + * If you disable the maxAge then old log statements are not deleted. + * + * You can optionally disable the deleteInterval by setting it to zero (or a negative value). + * + * If you disable both deleteInterval and deleteOnEverySave then old log statements are not deleted. + * + * It's not wise to enable both deleteInterval and deleteOnEverySave. + * + * The default maxAge is 7 days. + * The default deleteInterval is 5 minutes. + * The default deleteOnEverySave is NO. + **/ +@property (assign, readwrite) NSTimeInterval maxAge; + +/** + * See the description for the `maxAge` property + */ +@property (assign, readwrite) NSTimeInterval deleteInterval; + +/** + * See the description for the `maxAge` property + */ +@property (assign, readwrite) BOOL deleteOnEverySave; + +/** + * Forces a save of any pending log entries (flushes log entries to disk). + **/ +- (void)savePendingLogEntries; + +/** + * Removes any log entries that are older than maxAge. + **/ +- (void)deleteOldLogEntries; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDAssertMacros.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDAssertMacros.h new file mode 100644 index 0000000..4c54633 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDAssertMacros.h @@ -0,0 +1,25 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +/** + * NSAssert replacement that will output a log message even when assertions are disabled. + **/ +#define DDAssert(condition, frmt, ...) \ + if (!(condition)) { \ + NSString *description = [NSString stringWithFormat:frmt, ## __VA_ARGS__]; \ + DDLogError(@"%@", description); \ + NSAssert(NO, @"%@", description); \ + } +#define DDAssertCondition(condition) DDAssert(condition, @"Condition not satisfied: %s", #condition) diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDContextFilterLogFormatter.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDContextFilterLogFormatter.h new file mode 100644 index 0000000..e124448 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDContextFilterLogFormatter.h @@ -0,0 +1,121 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#import + +// Disable legacy macros +#ifndef DD_LEGACY_MACROS + #define DD_LEGACY_MACROS 0 +#endif + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class provides a log formatter that filters log statements from a logging context not on the whitelist. + * + * A log formatter can be added to any logger to format and/or filter its output. + * You can learn more about log formatters here: + * Documentation/CustomFormatters.md + * + * You can learn more about logging context's here: + * Documentation/CustomContext.md + * + * But here's a quick overview / refresher: + * + * Every log statement has a logging context. + * These come from the underlying logging macros defined in DDLog.h. + * The default logging context is zero. + * You can define multiple logging context's for use in your application. + * For example, logically separate parts of your app each have a different logging context. + * Also 3rd party frameworks that make use of Lumberjack generally use their own dedicated logging context. + **/ +@interface DDContextWhitelistFilterLogFormatter : NSObject + +/** + * Designated default initializer + */ +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +/** + * Add a context to the whitelist + * + * @param loggingContext the context + */ +- (void)addToWhitelist:(NSInteger)loggingContext; + +/** + * Remove context from whitelist + * + * @param loggingContext the context + */ +- (void)removeFromWhitelist:(NSInteger)loggingContext; + +/** + * Return the whitelist + */ +@property (nonatomic, readonly, copy) NSArray *whitelist; + +/** + * Check if a context is on the whitelist + * + * @param loggingContext the context + */ +- (BOOL)isOnWhitelist:(NSInteger)loggingContext; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * This class provides a log formatter that filters log statements from a logging context on the blacklist. + **/ +@interface DDContextBlacklistFilterLogFormatter : NSObject + +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +/** + * Add a context to the blacklist + * + * @param loggingContext the context + */ +- (void)addToBlacklist:(NSInteger)loggingContext; + +/** + * Remove context from blacklist + * + * @param loggingContext the context + */ +- (void)removeFromBlacklist:(NSInteger)loggingContext; + +/** + * Return the blacklist + */ +@property (readonly, copy) NSArray *blacklist; + + +/** + * Check if a context is on the blacklist + * + * @param loggingContext the context + */ +- (BOOL)isOnBlacklist:(NSInteger)loggingContext; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDDispatchQueueLogFormatter.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDDispatchQueueLogFormatter.h new file mode 100644 index 0000000..7d5aa55 --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDDispatchQueueLogFormatter.h @@ -0,0 +1,228 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#import + +// Disable legacy macros +#ifndef DD_LEGACY_MACROS + #define DD_LEGACY_MACROS 0 +#endif + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Log formatter mode + */ +__attribute__((deprecated("DDDispatchQueueLogFormatter is always shareable"))) +typedef NS_ENUM(NSUInteger, DDDispatchQueueLogFormatterMode){ + /** + * This is the default option, means the formatter can be reused between multiple loggers and therefore is thread-safe. + * There is, of course, a performance cost for the thread-safety + */ + DDDispatchQueueLogFormatterModeShareble = 0, + /** + * If the formatter will only be used by a single logger, then the thread-safety can be removed + * @note: there is an assert checking if the formatter is added to multiple loggers and the mode is non-shareble + */ + DDDispatchQueueLogFormatterModeNonShareble, +}; + +/** + * Quality of Service names. + * + * Since macOS 10.10 and iOS 8.0, pthreads, dispatch queues and NSOperations express their + * scheduling priority by using an abstract classification called Quality of Service (QOS). + * + * This formatter will add a representation of this QOS in the log message by using those + * string constants. + * For example: + * + * `2011-10-17 20:21:45.435 AppName[19928:5207 (QOS:DF)] Your log message here` + * + * Where QOS is one of: + * `- UI = User Interactive` + * `- IN = User Initiated` + * `- DF = Default` + * `- UT = Utility` + * `- BG = Background` + * `- UN = Unspecified` + * + * Note: QOS will be absent in the log messages if running on OS versions that don't support it. + **/ +typedef NSString * DDQualityOfServiceName NS_STRING_ENUM; + +FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceUserInteractive NS_SWIFT_NAME(DDQualityOfServiceName.userInteractive) API_AVAILABLE(macos(10.10), ios(8.0)); +FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceUserInitiated NS_SWIFT_NAME(DDQualityOfServiceName.userInitiated) API_AVAILABLE(macos(10.10), ios(8.0)); +FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceDefault NS_SWIFT_NAME(DDQualityOfServiceName.default) API_AVAILABLE(macos(10.10), ios(8.0)); +FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceUtility NS_SWIFT_NAME(DDQualityOfServiceName.utility) API_AVAILABLE(macos(10.10), ios(8.0)); +FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceBackground NS_SWIFT_NAME(DDQualityOfServiceName.background) API_AVAILABLE(macos(10.10), ios(8.0)); +FOUNDATION_EXPORT DDQualityOfServiceName const DDQualityOfServiceUnspecified NS_SWIFT_NAME(DDQualityOfServiceName.unspecified) API_AVAILABLE(macos(10.10), ios(8.0)); + +/** + * This class provides a log formatter that prints the dispatch_queue label instead of the mach_thread_id. + * + * A log formatter can be added to any logger to format and/or filter its output. + * You can learn more about log formatters here: + * Documentation/CustomFormatters.md + * + * A typical `NSLog` (or `DDTTYLogger`) prints detailed info as `[:]`. + * For example: + * + * `2011-10-17 20:21:45.435 AppName[19928:5207] Your log message here` + * + * Where: + * `- 19928 = process id` + * `- 5207 = thread id (mach_thread_id printed in hex)` + * + * When using grand central dispatch (GCD), this information is less useful. + * This is because a single serial dispatch queue may be run on any thread from an internally managed thread pool. + * For example: + * + * `2011-10-17 20:32:31.111 AppName[19954:4d07] Message from my_serial_dispatch_queue` + * `2011-10-17 20:32:31.112 AppName[19954:5207] Message from my_serial_dispatch_queue` + * `2011-10-17 20:32:31.113 AppName[19954:2c55] Message from my_serial_dispatch_queue` + * + * This formatter allows you to replace the standard `[box:info]` with the dispatch_queue name. + * For example: + * + * `2011-10-17 20:32:31.111 AppName[img-scaling] Message from my_serial_dispatch_queue` + * `2011-10-17 20:32:31.112 AppName[img-scaling] Message from my_serial_dispatch_queue` + * `2011-10-17 20:32:31.113 AppName[img-scaling] Message from my_serial_dispatch_queue` + * + * If the dispatch_queue doesn't have a set name, then it falls back to the thread name. + * If the current thread doesn't have a set name, then it falls back to the mach_thread_id in hex (like normal). + * + * Note: If manually creating your own background threads (via `NSThread/alloc/init` or `NSThread/detachNeThread`), + * you can use `[[NSThread currentThread] setName:(NSString *)]`. + **/ +@interface DDDispatchQueueLogFormatter : NSObject + +/** + * Standard init method. + * Configure using properties as desired. + **/ +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +/** + * Initializer with ability to set the queue mode + * + * @param mode choose between DDDispatchQueueLogFormatterModeShareble and DDDispatchQueueLogFormatterModeNonShareble, depending if the formatter is shared between several loggers or not + */ +- (instancetype)initWithMode:(DDDispatchQueueLogFormatterMode)mode __attribute__((deprecated("DDDispatchQueueLogFormatter is always shareable"))); + +/** + * The minQueueLength restricts the minimum size of the [detail box]. + * If the minQueueLength is set to 0, there is no restriction. + * + * For example, say a dispatch_queue has a label of "diskIO": + * + * If the minQueueLength is 0: [diskIO] + * If the minQueueLength is 4: [diskIO] + * If the minQueueLength is 5: [diskIO] + * If the minQueueLength is 6: [diskIO] + * If the minQueueLength is 7: [diskIO ] + * If the minQueueLength is 8: [diskIO ] + * + * The default minQueueLength is 0 (no minimum, so [detail box] won't be padded). + * + * If you want every [detail box] to have the exact same width, + * set both minQueueLength and maxQueueLength to the same value. + **/ +@property (assign, atomic) NSUInteger minQueueLength; + +/** + * The maxQueueLength restricts the number of characters that will be inside the [detail box]. + * If the maxQueueLength is 0, there is no restriction. + * + * For example, say a dispatch_queue has a label of "diskIO": + * + * If the maxQueueLength is 0: [diskIO] + * If the maxQueueLength is 4: [disk] + * If the maxQueueLength is 5: [diskI] + * If the maxQueueLength is 6: [diskIO] + * If the maxQueueLength is 7: [diskIO] + * If the maxQueueLength is 8: [diskIO] + * + * The default maxQueueLength is 0 (no maximum, so [detail box] won't be truncated). + * + * If you want every [detail box] to have the exact same width, + * set both minQueueLength and maxQueueLength to the same value. + **/ +@property (assign, atomic) NSUInteger maxQueueLength; + +/** + * Sometimes queue labels have long names like "com.apple.main-queue", + * but you'd prefer something shorter like simply "main". + * + * This method allows you to set such preferred replacements. + * The above example is set by default. + * + * To remove/undo a previous replacement, invoke this method with nil for the 'shortLabel' parameter. + **/ +- (nullable NSString *)replacementStringForQueueLabel:(NSString *)longLabel; + +/** + * See the `replacementStringForQueueLabel:` description + */ +- (void)setReplacementString:(nullable NSString *)shortLabel forQueueLabel:(NSString *)longLabel; + +@end + +/** + * Category on `DDDispatchQueueLogFormatter` to make method declarations easier to extend/modify + **/ +@interface DDDispatchQueueLogFormatter (OverridableMethods) + +/** + * Date formatter default configuration + */ +- (void)configureDateFormatter:(NSDateFormatter *)dateFormatter; + +/** + * Formatter method to transfrom from date to string + */ +- (NSString *)stringFromDate:(NSDate *)date; + +/** + * Method to compute the queue thread label + */ +- (NSString *)queueThreadLabelForLogMessage:(DDLogMessage *)logMessage; + +/** + * The actual method that formats a message (transforms a `DDLogMessage` model into a printable string) + */ +- (NSString *)formatLogMessage:(DDLogMessage *)logMessage; + +@end + +#pragma mark - DDAtomicCountable + +__attribute__((deprecated("DDAtomicCountable is useless since DDDispatchQueueLogFormatter is always shareable now"))) +@protocol DDAtomicCountable + +- (instancetype)initWithDefaultValue:(int32_t)defaultValue; +- (int32_t)increment; +- (int32_t)decrement; +- (int32_t)value; + +@end + +__attribute__((deprecated("DDAtomicCountable is deprecated"))) +@interface DDAtomicCounter: NSObject +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDFileLogger+Buffering.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDFileLogger+Buffering.h new file mode 100644 index 0000000..6dbb94b --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDFileLogger+Buffering.h @@ -0,0 +1,27 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface DDFileLogger (Buffering) + +- (instancetype)wrapWithBuffer; +- (instancetype)unwrapFromBuffer; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDFileLogger.h b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDFileLogger.h new file mode 100644 index 0000000..c165abd --- /dev/null +++ b/Pods/CocoaLumberjack/Sources/CocoaLumberjack/include/CocoaLumberjack/DDFileLogger.h @@ -0,0 +1,530 @@ +// Software License Agreement (BSD License) +// +// Copyright (c) 2010-2020, Deusty, LLC +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Neither the name of Deusty nor the names of its contributors may be used +// to endorse or promote products derived from this software without specific +// prior written permission of Deusty, LLC. + +// Disable legacy macros +#ifndef DD_LEGACY_MACROS + #define DD_LEGACY_MACROS 0 +#endif + +#import + +@class DDLogFileInfo; + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class provides a logger to write log statements to a file. + **/ + + +// Default configuration and safety/sanity values. +// +// maximumFileSize -> kDDDefaultLogMaxFileSize +// rollingFrequency -> kDDDefaultLogRollingFrequency +// maximumNumberOfLogFiles -> kDDDefaultLogMaxNumLogFiles +// logFilesDiskQuota -> kDDDefaultLogFilesDiskQuota +// +// You should carefully consider the proper configuration values for your application. + +extern unsigned long long const kDDDefaultLogMaxFileSize; +extern NSTimeInterval const kDDDefaultLogRollingFrequency; +extern NSUInteger const kDDDefaultLogMaxNumLogFiles; +extern unsigned long long const kDDDefaultLogFilesDiskQuota; + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * The LogFileManager protocol is designed to allow you to control all aspects of your log files. + * + * The primary purpose of this is to allow you to do something with the log files after they have been rolled. + * Perhaps you want to compress them to save disk space. + * Perhaps you want to upload them to an FTP server. + * Perhaps you want to run some analytics on the file. + * + * A default LogFileManager is, of course, provided. + * The default LogFileManager simply deletes old log files according to the maximumNumberOfLogFiles property. + * + * This protocol provides various methods to fetch the list of log files. + * + * There are two variants: sorted and unsorted. + * If sorting is not necessary, the unsorted variant is obviously faster. + * The sorted variant will return an array sorted by when the log files were created, + * with the most recently created log file at index 0, and the oldest log file at the end of the array. + * + * You can fetch only the log file paths (full path including name), log file names (name only), + * or an array of `DDLogFileInfo` objects. + * The `DDLogFileInfo` class is documented below, and provides a handy wrapper that + * gives you easy access to various file attributes such as the creation date or the file size. + */ +@protocol DDLogFileManager +@required + +// Public properties + +/** + * The maximum number of archived log files to keep on disk. + * For example, if this property is set to 3, + * then the LogFileManager will only keep 3 archived log files (plus the current active log file) on disk. + * Once the active log file is rolled/archived, then the oldest of the existing 3 rolled/archived log files is deleted. + * + * You may optionally disable this option by setting it to zero. + **/ +@property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles; + +/** + * The maximum space that logs can take. On rolling logfile all old log files that exceed logFilesDiskQuota will + * be deleted. + * + * You may optionally disable this option by setting it to zero. + **/ +@property (readwrite, assign, atomic) unsigned long long logFilesDiskQuota; + +// Public methods + +/** + * Returns the logs directory (path) + */ +@property (nonatomic, readonly, copy) NSString *logsDirectory; + +/** + * Returns an array of `NSString` objects, + * each of which is the filePath to an existing log file on disk. + **/ +@property (nonatomic, readonly, strong) NSArray *unsortedLogFilePaths; + +/** + * Returns an array of `NSString` objects, + * each of which is the fileName of an existing log file on disk. + **/ +@property (nonatomic, readonly, strong) NSArray *unsortedLogFileNames; + +/** + * Returns an array of `DDLogFileInfo` objects, + * each representing an existing log file on disk, + * and containing important information about the log file such as it's modification date and size. + **/ +@property (nonatomic, readonly, strong) NSArray *unsortedLogFileInfos; + +/** + * Just like the `unsortedLogFilePaths` method, but sorts the array. + * The items in the array are sorted by creation date. + * The first item in the array will be the most recently created log file. + **/ +@property (nonatomic, readonly, strong) NSArray *sortedLogFilePaths; + +/** + * Just like the `unsortedLogFileNames` method, but sorts the array. + * The items in the array are sorted by creation date. + * The first item in the array will be the most recently created log file. + **/ +@property (nonatomic, readonly, strong) NSArray *sortedLogFileNames; + +/** + * Just like the `unsortedLogFileInfos` method, but sorts the array. + * The items in the array are sorted by creation date. + * The first item in the array will be the most recently created log file. + **/ +@property (nonatomic, readonly, strong) NSArray *sortedLogFileInfos; + +// Private methods (only to be used by DDFileLogger) + +/** + * Generates a new unique log file path, and creates the corresponding log file. + * This method is executed directly on the file logger's internal queue. + * The file has to exist by the time the method returns. + **/ +- (nullable NSString *)createNewLogFileWithError:(NSError **)error; + +@optional + +// Private methods (only to be used by DDFileLogger) +/** + * Creates a new log file ignoring any errors. Deprecated in favor of `-createNewLogFileWithError:`. + * Will only be called if `-createNewLogFileWithError:` is not implemented. + **/ +- (nullable NSString *)createNewLogFile __attribute__((deprecated("Use -createNewLogFileWithError:"))) NS_SWIFT_UNAVAILABLE("Use -createNewLogFileWithError:"); + +// Notifications from DDFileLogger + +/// Called when a log file was archived. Executed on global queue with default priority. +/// @param logFilePath The path to the log file that was archived. +/// @param wasRolled Whether or not the archiving happend after rolling the log file. +- (void)didArchiveLogFile:(NSString *)logFilePath wasRolled:(BOOL)wasRolled NS_SWIFT_NAME(didArchiveLogFile(atPath:wasRolled:)); + +// Deprecated APIs +/** + * Called when a log file was archived. Executed on global queue with default priority. + */ +- (void)didArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didArchiveLogFile(atPath:)) __attribute__((deprecated("Use -didArchiveLogFile:wasRolled:"))); + +/** + * Called when the roll action was executed and the log was archived. + * Executed on global queue with default priority. + */ +- (void)didRollAndArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didRollAndArchiveLogFile(atPath:)) __attribute__((deprecated("Use -didArchiveLogFile:wasRolled:"))); + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Default log file manager. + * + * All log files are placed inside the logsDirectory. + * If a specific logsDirectory isn't specified, the default directory is used. + * On Mac, this is in `~/Library/Logs/`. + * On iPhone, this is in `~/Library/Caches/Logs`. + * + * Log files are named `"
@@ -74,6 +74,17 @@ THE SOFTWARE. Type PSGroupSpecifier + + FooterText + Copyright © 2014 AutoNavi. All Rights Reserved. + + License + Copyright + Title + AMapSearch + Type + PSGroupSpecifier + FooterText Copyright (C) 2017 Tencent Bugly, Inc. All rights reserved. @@ -85,6 +96,30 @@ THE SOFTWARE. Type PSGroupSpecifier + + FooterText + BSD 3-Clause License + +Copyright (c) 2010-2020, Deusty, LLC +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of Deusty nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission of Deusty, LLC. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + License + BSD + Title + CocoaLumberjack + Type + PSGroupSpecifier + FooterText The MIT License (MIT) @@ -177,6 +212,35 @@ SOFTWARE. Type PSGroupSpecifier + + FooterText + Copyright (c) 2013-2019 MJExtension (https://github.com/CoderMJLee/MJExtension) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + MJExtension + Type + PSGroupSpecifier + FooterText Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) @@ -264,6 +328,24 @@ THE SOFTWARE. Type PSGroupSpecifier + + FooterText + Copyright (c) 2010-2011 Matt Rajca, 2011-2015 various authors +Parts Copyright (c) Tipbit Inc + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + License + MIT + Title + SVGKit + Type + PSGroupSpecifier + FooterText The MIT License (MIT) diff --git a/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Debug-input-files.xcfilelist b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Debug-input-files.xcfilelist new file mode 100644 index 0000000..094ca42 --- /dev/null +++ b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Debug-input-files.xcfilelist @@ -0,0 +1,3 @@ +${PODS_ROOT}/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources.sh +${PODS_ROOT}/AMap3DMap/MAMapKit.framework/AMap.bundle +${PODS_ROOT}/MJRefresh/MJRefresh/MJRefresh.bundle \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Debug-output-files.xcfilelist b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Debug-output-files.xcfilelist new file mode 100644 index 0000000..08ea825 --- /dev/null +++ b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Debug-output-files.xcfilelist @@ -0,0 +1,2 @@ +${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AMap.bundle +${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MJRefresh.bundle \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Release-input-files.xcfilelist b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Release-input-files.xcfilelist new file mode 100644 index 0000000..094ca42 --- /dev/null +++ b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Release-input-files.xcfilelist @@ -0,0 +1,3 @@ +${PODS_ROOT}/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources.sh +${PODS_ROOT}/AMap3DMap/MAMapKit.framework/AMap.bundle +${PODS_ROOT}/MJRefresh/MJRefresh/MJRefresh.bundle \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Release-output-files.xcfilelist b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Release-output-files.xcfilelist new file mode 100644 index 0000000..08ea825 --- /dev/null +++ b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources-Release-output-files.xcfilelist @@ -0,0 +1,2 @@ +${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AMap.bundle +${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/MJRefresh.bundle \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources.sh b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources.sh index eff83da..2ca86ad 100755 --- a/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources.sh +++ b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun-resources.sh @@ -3,10 +3,15 @@ set -e set -u set -o pipefail +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then - # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy - # resources to, so exit 0 (signalling the script phase was successful). - exit 0 + # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy + # resources to, so exit 0 (signalling the script phase was successful). + exit 0 fi mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" @@ -92,11 +97,11 @@ EOM esac } if [[ "$CONFIGURATION" == "Debug" ]]; then - install_resource "${PODS_ROOT}/AMap2DMap/MAMapKit.framework/AMap.bundle" + install_resource "${PODS_ROOT}/AMap3DMap/MAMapKit.framework/AMap.bundle" install_resource "${PODS_ROOT}/MJRefresh/MJRefresh/MJRefresh.bundle" fi if [[ "$CONFIGURATION" == "Release" ]]; then - install_resource "${PODS_ROOT}/AMap2DMap/MAMapKit.framework/AMap.bundle" + install_resource "${PODS_ROOT}/AMap3DMap/MAMapKit.framework/AMap.bundle" install_resource "${PODS_ROOT}/MJRefresh/MJRefresh/MJRefresh.bundle" fi @@ -111,7 +116,7 @@ rm -f "$RESOURCES_TO_COPY" if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] then # Find all other xcassets (this unfortunately includes those of path pods and other targets). - OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + OTHER_XCASSETS=$(find -L "$PWD" -iname "*.xcassets" -type d) while read line; do if [[ $line != "${PODS_ROOT}*" ]]; then XCASSET_FILES+=("$line") diff --git a/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun.debug.xcconfig b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun.debug.xcconfig index 50d7052..50180d3 100644 --- a/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun.debug.xcconfig +++ b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun.debug.xcconfig @@ -1,11 +1,13 @@ ARCHS = $(ARCHS_STANDARD) -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap2DMap" "${PODS_ROOT}/AMapFoundation" "${PODS_ROOT}/AMapLocation" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/YYKit/Vendor" +CLANG_CXX_LANGUAGE_STANDARD = gnu++11 +CLANG_CXX_LIBRARY = libc++ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap3DMap" "${PODS_ROOT}/AMapFoundation" "${PODS_ROOT}/AMapLocation" "${PODS_ROOT}/AMapSearch" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/YYKit/Vendor" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/AMap2DMap" "${PODS_ROOT}/Headers/Public/AMapFoundation" "${PODS_ROOT}/Headers/Public/AMapLocation" "${PODS_ROOT}/Headers/Public/Bugly" "${PODS_ROOT}/Headers/Public/JZLocationConverter" "${PODS_ROOT}/Headers/Public/MBProgressHUD" "${PODS_ROOT}/Headers/Public/MGJRouter" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/YYKit" -LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/JZLocationConverter" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MGJRouter" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYKit" -OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/AMap2DMap" -isystem "${PODS_ROOT}/Headers/Public/AMapFoundation" -isystem "${PODS_ROOT}/Headers/Public/AMapLocation" -isystem "${PODS_ROOT}/Headers/Public/Bugly" -isystem "${PODS_ROOT}/Headers/Public/JZLocationConverter" -isystem "${PODS_ROOT}/Headers/Public/MBProgressHUD" -isystem "${PODS_ROOT}/Headers/Public/MGJRouter" -isystem "${PODS_ROOT}/Headers/Public/MJRefresh" -isystem "${PODS_ROOT}/Headers/Public/Masonry" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/YYKit" -OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking" -l"JZLocationConverter" -l"MBProgressHUD" -l"MGJRouter" -l"MJRefresh" -l"Masonry" -l"SDWebImage" -l"YYKit" -l"c++" -l"sqlite3" -l"z" -framework "AMapFoundationKit" -framework "AMapLocationKit" -framework "Accelerate" -framework "AssetsLibrary" -framework "Bugly" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "Foundation" -framework "ImageIO" -framework "MAMapKit" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebP" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/CocoaLumberjack" "${PODS_ROOT}/Headers/Public/JZLocationConverter" "${PODS_ROOT}/Headers/Public/MBProgressHUD" "${PODS_ROOT}/Headers/Public/MGJRouter" "${PODS_ROOT}/Headers/Public/MJExtension" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVGKit" "${PODS_ROOT}/Headers/Public/YYKit" $(SDKROOT)/usr/include/libxml2 +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/JZLocationConverter" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MGJRouter" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SVGKit" "${PODS_CONFIGURATION_BUILD_DIR}/YYKit" +OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking" -l"CocoaLumberjack" -l"JZLocationConverter" -l"MBProgressHUD" -l"MGJRouter" -l"MJExtension" -l"MJRefresh" -l"Masonry" -l"SDWebImage" -l"SVGKit" -l"YYKit" -l"c++" -l"sqlite3" -l"xml2" -l"z" -framework "AMapFoundationKit" -framework "AMapLocationKit" -framework "AMapSearchKit" -framework "Accelerate" -framework "AssetsLibrary" -framework "Bugly" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "Foundation" -framework "GLKit" -framework "ImageIO" -framework "MAMapKit" -framework "MobileCoreServices" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebP" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun.release.xcconfig b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun.release.xcconfig index 50d7052..50180d3 100644 --- a/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun.release.xcconfig +++ b/Pods/Target Support Files/Pods-MRMobileRun/Pods-MRMobileRun.release.xcconfig @@ -1,11 +1,13 @@ ARCHS = $(ARCHS_STANDARD) -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap2DMap" "${PODS_ROOT}/AMapFoundation" "${PODS_ROOT}/AMapLocation" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/YYKit/Vendor" +CLANG_CXX_LANGUAGE_STANDARD = gnu++11 +CLANG_CXX_LIBRARY = libc++ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/AMap3DMap" "${PODS_ROOT}/AMapFoundation" "${PODS_ROOT}/AMapLocation" "${PODS_ROOT}/AMapSearch" "${PODS_ROOT}/Bugly" "${PODS_ROOT}/YYKit/Vendor" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/AMap2DMap" "${PODS_ROOT}/Headers/Public/AMapFoundation" "${PODS_ROOT}/Headers/Public/AMapLocation" "${PODS_ROOT}/Headers/Public/Bugly" "${PODS_ROOT}/Headers/Public/JZLocationConverter" "${PODS_ROOT}/Headers/Public/MBProgressHUD" "${PODS_ROOT}/Headers/Public/MGJRouter" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/YYKit" -LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/JZLocationConverter" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MGJRouter" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/YYKit" -OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/AMap2DMap" -isystem "${PODS_ROOT}/Headers/Public/AMapFoundation" -isystem "${PODS_ROOT}/Headers/Public/AMapLocation" -isystem "${PODS_ROOT}/Headers/Public/Bugly" -isystem "${PODS_ROOT}/Headers/Public/JZLocationConverter" -isystem "${PODS_ROOT}/Headers/Public/MBProgressHUD" -isystem "${PODS_ROOT}/Headers/Public/MGJRouter" -isystem "${PODS_ROOT}/Headers/Public/MJRefresh" -isystem "${PODS_ROOT}/Headers/Public/Masonry" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/YYKit" -OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking" -l"JZLocationConverter" -l"MBProgressHUD" -l"MGJRouter" -l"MJRefresh" -l"Masonry" -l"SDWebImage" -l"YYKit" -l"c++" -l"sqlite3" -l"z" -framework "AMapFoundationKit" -framework "AMapLocationKit" -framework "Accelerate" -framework "AssetsLibrary" -framework "Bugly" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "Foundation" -framework "ImageIO" -framework "MAMapKit" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebP" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/CocoaLumberjack" "${PODS_ROOT}/Headers/Public/JZLocationConverter" "${PODS_ROOT}/Headers/Public/MBProgressHUD" "${PODS_ROOT}/Headers/Public/MGJRouter" "${PODS_ROOT}/Headers/Public/MJExtension" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Masonry" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVGKit" "${PODS_ROOT}/Headers/Public/YYKit" $(SDKROOT)/usr/include/libxml2 +LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking" "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" "${PODS_CONFIGURATION_BUILD_DIR}/JZLocationConverter" "${PODS_CONFIGURATION_BUILD_DIR}/MBProgressHUD" "${PODS_CONFIGURATION_BUILD_DIR}/MGJRouter" "${PODS_CONFIGURATION_BUILD_DIR}/MJExtension" "${PODS_CONFIGURATION_BUILD_DIR}/MJRefresh" "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" "${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage" "${PODS_CONFIGURATION_BUILD_DIR}/SVGKit" "${PODS_CONFIGURATION_BUILD_DIR}/YYKit" +OTHER_LDFLAGS = $(inherited) -ObjC -l"AFNetworking" -l"CocoaLumberjack" -l"JZLocationConverter" -l"MBProgressHUD" -l"MGJRouter" -l"MJExtension" -l"MJRefresh" -l"Masonry" -l"SDWebImage" -l"SVGKit" -l"YYKit" -l"c++" -l"sqlite3" -l"xml2" -l"z" -framework "AMapFoundationKit" -framework "AMapLocationKit" -framework "AMapSearchKit" -framework "Accelerate" -framework "AssetsLibrary" -framework "Bugly" -framework "CoreFoundation" -framework "CoreGraphics" -framework "CoreImage" -framework "CoreLocation" -framework "CoreTelephony" -framework "CoreText" -framework "ExternalAccessory" -framework "Foundation" -framework "GLKit" -framework "ImageIO" -framework "MAMapKit" -framework "MobileCoreServices" -framework "OpenGLES" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" -framework "UIKit" -framework "WebP" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig b/Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig new file mode 100644 index 0000000..ea06915 --- /dev/null +++ b/Pods/Target Support Files/SDWebImage/SDWebImage.debug.xcconfig @@ -0,0 +1,10 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/SDWebImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/SDWebImage" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SDWebImage +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig b/Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig new file mode 100644 index 0000000..ea06915 --- /dev/null +++ b/Pods/Target Support Files/SDWebImage/SDWebImage.release.xcconfig @@ -0,0 +1,10 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/SDWebImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/SDWebImage" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SDWebImage +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/SVGKit/SVGKit-dummy.m b/Pods/Target Support Files/SVGKit/SVGKit-dummy.m new file mode 100644 index 0000000..7543c92 --- /dev/null +++ b/Pods/Target Support Files/SVGKit/SVGKit-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SVGKit : NSObject +@end +@implementation PodsDummy_SVGKit +@end diff --git a/Pods/Target Support Files/SVGKit/SVGKit-prefix.pch b/Pods/Target Support Files/SVGKit/SVGKit-prefix.pch new file mode 100644 index 0000000..e16d179 --- /dev/null +++ b/Pods/Target Support Files/SVGKit/SVGKit-prefix.pch @@ -0,0 +1,43 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +// +// Prefix header for all source files of the 'SVGKit-iOS' target in the 'SVGKit-iOS' project +// + +#ifdef __OBJC__ +#import +#import +#import "SVGKDefine.h" + +// These macro is only used inside framework project, does not expose to public header and effect user's define + +#define SVGKIT_LOG_CONTEXT 556 + +#define SVGKitLogError(frmt, ...) LOG_MAYBE(NO, LOG_LEVEL_DEF, DDLogFlagError, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) +#define SVGKitLogWarn(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagWarning, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) +#define SVGKitLogInfo(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagInfo, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) +#define SVGKitLogDebug(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagDebug, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) +#define SVGKitLogVerbose(frmt, ...) LOG_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, DDLogFlagVerbose, SVGKIT_LOG_CONTEXT, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__) + +#if DEBUG +static const int ddLogLevel = DDLogLevelVerbose; +#else +static const int ddLogLevel = DDLogLevelWarning; +#endif + +#if SVGKIT_MAC +#define NSStringFromCGRect(rect) NSStringFromRect(rect) +#define NSStringFromCGSize(size) NSStringFromSize(size) +#define NSStringFromCGPoint(point) NSStringFromPoint(point) +#endif +#endif diff --git a/Pods/Target Support Files/SVGKit/SVGKit.debug.xcconfig b/Pods/Target Support Files/SVGKit/SVGKit.debug.xcconfig new file mode 100644 index 0000000..0badcdf --- /dev/null +++ b/Pods/Target Support Files/SVGKit/SVGKit.debug.xcconfig @@ -0,0 +1,12 @@ +CLANG_CXX_LANGUAGE_STANDARD = gnu++11 +CLANG_CXX_LIBRARY = libc++ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SVGKit +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/SVGKit" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/CocoaLumberjack" "${PODS_ROOT}/Headers/Public/SVGKit" $(SDKROOT)/usr/include/libxml2 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SVGKit +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/SVGKit/SVGKit.release.xcconfig b/Pods/Target Support Files/SVGKit/SVGKit.release.xcconfig new file mode 100644 index 0000000..0badcdf --- /dev/null +++ b/Pods/Target Support Files/SVGKit/SVGKit.release.xcconfig @@ -0,0 +1,12 @@ +CLANG_CXX_LANGUAGE_STANDARD = gnu++11 +CLANG_CXX_LIBRARY = libc++ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SVGKit +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/SVGKit" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/CocoaLumberjack" "${PODS_ROOT}/Headers/Public/SVGKit" $(SDKROOT)/usr/include/libxml2 +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SVGKit +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/YYKit/YYKit.debug.xcconfig b/Pods/Target Support Files/YYKit/YYKit.debug.xcconfig new file mode 100644 index 0000000..6d096a4 --- /dev/null +++ b/Pods/Target Support Files/YYKit/YYKit.debug.xcconfig @@ -0,0 +1,11 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/YYKit +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/YYKit/Vendor" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/YYKit" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/YYKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/YYKit +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/Pods/Target Support Files/YYKit/YYKit.release.xcconfig b/Pods/Target Support Files/YYKit/YYKit.release.xcconfig new file mode 100644 index 0000000..6d096a4 --- /dev/null +++ b/Pods/Target Support Files/YYKit/YYKit.release.xcconfig @@ -0,0 +1,11 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/YYKit +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/YYKit/Vendor" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/YYKit" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/YYKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/YYKit +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/SettingViewIcon/Contents.json b/SettingViewIcon/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/SettingViewIcon/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SettingViewIcon/arraw.imageset/Contents.json b/SettingViewIcon/arraw.imageset/Contents.json new file mode 100644 index 0000000..255f8c9 --- /dev/null +++ b/SettingViewIcon/arraw.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "arraw.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SettingViewIcon/arraw.imageset/arraw.png b/SettingViewIcon/arraw.imageset/arraw.png new file mode 100644 index 0000000..a7888a7 Binary files /dev/null and b/SettingViewIcon/arraw.imageset/arraw.png differ diff --git a/SettingViewIcon/setting_about.imageset/Contents.json b/SettingViewIcon/setting_about.imageset/Contents.json new file mode 100644 index 0000000..15e21be --- /dev/null +++ b/SettingViewIcon/setting_about.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "设置/反馈备份 4.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份 4@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份 4@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/SettingViewIcon/setting_about.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 4.png" "b/SettingViewIcon/setting_about.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 4.png" new file mode 100644 index 0000000..0da8a26 Binary files /dev/null and "b/SettingViewIcon/setting_about.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 4.png" differ diff --git "a/SettingViewIcon/setting_about.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 4@2x.png" "b/SettingViewIcon/setting_about.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 4@2x.png" new file mode 100644 index 0000000..577cdd3 Binary files /dev/null and "b/SettingViewIcon/setting_about.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 4@2x.png" differ diff --git "a/SettingViewIcon/setting_about.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 4@3x.png" "b/SettingViewIcon/setting_about.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 4@3x.png" new file mode 100644 index 0000000..df182b2 Binary files /dev/null and "b/SettingViewIcon/setting_about.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 4@3x.png" differ diff --git a/SettingViewIcon/setting_about_dark.imageset/3.png b/SettingViewIcon/setting_about_dark.imageset/3.png new file mode 100644 index 0000000..3765528 Binary files /dev/null and b/SettingViewIcon/setting_about_dark.imageset/3.png differ diff --git a/SettingViewIcon/setting_about_dark.imageset/Contents.json b/SettingViewIcon/setting_about_dark.imageset/Contents.json new file mode 100644 index 0000000..53eb8f1 --- /dev/null +++ b/SettingViewIcon/setting_about_dark.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "3.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SettingViewIcon/setting_authority.imageset/Contents.json b/SettingViewIcon/setting_authority.imageset/Contents.json new file mode 100644 index 0000000..42c13c7 --- /dev/null +++ b/SettingViewIcon/setting_authority.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "设置/反馈备份 5.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份 5@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份 5@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/SettingViewIcon/setting_authority.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 5.png" "b/SettingViewIcon/setting_authority.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 5.png" new file mode 100644 index 0000000..1496b4f Binary files /dev/null and "b/SettingViewIcon/setting_authority.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 5.png" differ diff --git "a/SettingViewIcon/setting_authority.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 5@2x.png" "b/SettingViewIcon/setting_authority.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 5@2x.png" new file mode 100644 index 0000000..dcc4d52 Binary files /dev/null and "b/SettingViewIcon/setting_authority.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 5@2x.png" differ diff --git "a/SettingViewIcon/setting_authority.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 5@3x.png" "b/SettingViewIcon/setting_authority.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 5@3x.png" new file mode 100644 index 0000000..46e0adc Binary files /dev/null and "b/SettingViewIcon/setting_authority.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 5@3x.png" differ diff --git a/SettingViewIcon/setting_authority_dark.imageset/4.png b/SettingViewIcon/setting_authority_dark.imageset/4.png new file mode 100644 index 0000000..214aa83 Binary files /dev/null and b/SettingViewIcon/setting_authority_dark.imageset/4.png differ diff --git a/SettingViewIcon/setting_authority_dark.imageset/Contents.json b/SettingViewIcon/setting_authority_dark.imageset/Contents.json new file mode 100644 index 0000000..6ebd06d --- /dev/null +++ b/SettingViewIcon/setting_authority_dark.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "4.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SettingViewIcon/setting_darkMode.imageset/Contents.json b/SettingViewIcon/setting_darkMode.imageset/Contents.json new file mode 100644 index 0000000..4155f02 --- /dev/null +++ b/SettingViewIcon/setting_darkMode.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "设置/反馈备份 6.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份 6@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份 6@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/SettingViewIcon/setting_darkMode.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 6.png" "b/SettingViewIcon/setting_darkMode.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 6.png" new file mode 100644 index 0000000..6c95288 Binary files /dev/null and "b/SettingViewIcon/setting_darkMode.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 6.png" differ diff --git "a/SettingViewIcon/setting_darkMode.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 6@2x.png" "b/SettingViewIcon/setting_darkMode.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 6@2x.png" new file mode 100644 index 0000000..ee9842c Binary files /dev/null and "b/SettingViewIcon/setting_darkMode.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 6@2x.png" differ diff --git "a/SettingViewIcon/setting_darkMode.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 6@3x.png" "b/SettingViewIcon/setting_darkMode.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 6@3x.png" new file mode 100644 index 0000000..e96e30c Binary files /dev/null and "b/SettingViewIcon/setting_darkMode.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 6@3x.png" differ diff --git a/SettingViewIcon/setting_darkMode_dark.imageset/6.png b/SettingViewIcon/setting_darkMode_dark.imageset/6.png new file mode 100644 index 0000000..679eb33 Binary files /dev/null and b/SettingViewIcon/setting_darkMode_dark.imageset/6.png differ diff --git a/SettingViewIcon/setting_darkMode_dark.imageset/Contents.json b/SettingViewIcon/setting_darkMode_dark.imageset/Contents.json new file mode 100644 index 0000000..a8c87a0 --- /dev/null +++ b/SettingViewIcon/setting_darkMode_dark.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "6.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SettingViewIcon/setting_icon.imageset/Contents.json b/SettingViewIcon/setting_icon.imageset/Contents.json new file mode 100644 index 0000000..39d8525 --- /dev/null +++ b/SettingViewIcon/setting_icon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "设置/反馈.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/SettingViewIcon/setting_icon.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210.png" "b/SettingViewIcon/setting_icon.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210.png" new file mode 100644 index 0000000..d5ac635 Binary files /dev/null and "b/SettingViewIcon/setting_icon.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210.png" differ diff --git "a/SettingViewIcon/setting_icon.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210@2x.png" "b/SettingViewIcon/setting_icon.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210@2x.png" new file mode 100644 index 0000000..3bdd1c5 Binary files /dev/null and "b/SettingViewIcon/setting_icon.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210@2x.png" differ diff --git "a/SettingViewIcon/setting_icon.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210@3x.png" "b/SettingViewIcon/setting_icon.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210@3x.png" new file mode 100644 index 0000000..e0d47ae Binary files /dev/null and "b/SettingViewIcon/setting_icon.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210@3x.png" differ diff --git a/SettingViewIcon/setting_icon_dark.imageset/1.png b/SettingViewIcon/setting_icon_dark.imageset/1.png new file mode 100644 index 0000000..75994d7 Binary files /dev/null and b/SettingViewIcon/setting_icon_dark.imageset/1.png differ diff --git a/SettingViewIcon/setting_icon_dark.imageset/Contents.json b/SettingViewIcon/setting_icon_dark.imageset/Contents.json new file mode 100644 index 0000000..38ee28b --- /dev/null +++ b/SettingViewIcon/setting_icon_dark.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SettingViewIcon/setting_nickname.imageset/Contents.json b/SettingViewIcon/setting_nickname.imageset/Contents.json new file mode 100644 index 0000000..1778501 --- /dev/null +++ b/SettingViewIcon/setting_nickname.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "设置/反馈备份.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/SettingViewIcon/setting_nickname.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275.png" "b/SettingViewIcon/setting_nickname.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275.png" new file mode 100644 index 0000000..1541567 Binary files /dev/null and "b/SettingViewIcon/setting_nickname.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275.png" differ diff --git "a/SettingViewIcon/setting_nickname.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275@2x.png" "b/SettingViewIcon/setting_nickname.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275@2x.png" new file mode 100644 index 0000000..7de3273 Binary files /dev/null and "b/SettingViewIcon/setting_nickname.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275@2x.png" differ diff --git "a/SettingViewIcon/setting_nickname.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275@3x.png" "b/SettingViewIcon/setting_nickname.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275@3x.png" new file mode 100644 index 0000000..24e1d3f Binary files /dev/null and "b/SettingViewIcon/setting_nickname.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275@3x.png" differ diff --git a/SettingViewIcon/setting_nickname_dark.imageset/7.png b/SettingViewIcon/setting_nickname_dark.imageset/7.png new file mode 100644 index 0000000..f2f0a0d Binary files /dev/null and b/SettingViewIcon/setting_nickname_dark.imageset/7.png differ diff --git a/SettingViewIcon/setting_nickname_dark.imageset/Contents.json b/SettingViewIcon/setting_nickname_dark.imageset/Contents.json new file mode 100644 index 0000000..fcced6a --- /dev/null +++ b/SettingViewIcon/setting_nickname_dark.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "7.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SettingViewIcon/setting_sign.imageset/Contents.json b/SettingViewIcon/setting_sign.imageset/Contents.json new file mode 100644 index 0000000..a4671ee --- /dev/null +++ b/SettingViewIcon/setting_sign.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "设置/反馈备份 2.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份 2@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份 2@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/SettingViewIcon/setting_sign.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 2.png" "b/SettingViewIcon/setting_sign.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 2.png" new file mode 100644 index 0000000..6e5b3cb Binary files /dev/null and "b/SettingViewIcon/setting_sign.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 2.png" differ diff --git "a/SettingViewIcon/setting_sign.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 2@2x.png" "b/SettingViewIcon/setting_sign.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 2@2x.png" new file mode 100644 index 0000000..9f4ee51 Binary files /dev/null and "b/SettingViewIcon/setting_sign.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 2@2x.png" differ diff --git "a/SettingViewIcon/setting_sign.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 2@3x.png" "b/SettingViewIcon/setting_sign.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 2@3x.png" new file mode 100644 index 0000000..079a3ec Binary files /dev/null and "b/SettingViewIcon/setting_sign.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 2@3x.png" differ diff --git a/SettingViewIcon/setting_sign_dark.imageset/2.png b/SettingViewIcon/setting_sign_dark.imageset/2.png new file mode 100644 index 0000000..0e83ce3 Binary files /dev/null and b/SettingViewIcon/setting_sign_dark.imageset/2.png differ diff --git a/SettingViewIcon/setting_sign_dark.imageset/Contents.json b/SettingViewIcon/setting_sign_dark.imageset/Contents.json new file mode 100644 index 0000000..c6348dd --- /dev/null +++ b/SettingViewIcon/setting_sign_dark.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SettingViewIcon/setting_suggestion.imageset/Contents.json b/SettingViewIcon/setting_suggestion.imageset/Contents.json new file mode 100644 index 0000000..9f18312 --- /dev/null +++ b/SettingViewIcon/setting_suggestion.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "设置/反馈备份 7.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份 7@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "设置/反馈备份 7@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git "a/SettingViewIcon/setting_suggestion.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 7.png" "b/SettingViewIcon/setting_suggestion.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 7.png" new file mode 100644 index 0000000..254235f Binary files /dev/null and "b/SettingViewIcon/setting_suggestion.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 7.png" differ diff --git "a/SettingViewIcon/setting_suggestion.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 7@2x.png" "b/SettingViewIcon/setting_suggestion.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 7@2x.png" new file mode 100644 index 0000000..137c926 Binary files /dev/null and "b/SettingViewIcon/setting_suggestion.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 7@2x.png" differ diff --git "a/SettingViewIcon/setting_suggestion.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 7@3x.png" "b/SettingViewIcon/setting_suggestion.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 7@3x.png" new file mode 100644 index 0000000..8b9ce25 Binary files /dev/null and "b/SettingViewIcon/setting_suggestion.imageset/\350\256\276\347\275\256\357\274\217\345\217\215\351\246\210\345\244\207\344\273\275 7@3x.png" differ diff --git a/SettingViewIcon/setting_suggestion_dark.imageset/5.png b/SettingViewIcon/setting_suggestion_dark.imageset/5.png new file mode 100644 index 0000000..aaac791 Binary files /dev/null and b/SettingViewIcon/setting_suggestion_dark.imageset/5.png differ diff --git a/SettingViewIcon/setting_suggestion_dark.imageset/Contents.json b/SettingViewIcon/setting_suggestion_dark.imageset/Contents.json new file mode 100644 index 0000000..90ec8dd --- /dev/null +++ b/SettingViewIcon/setting_suggestion_dark.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "5.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SportSettingViewController.m b/SportSettingViewController.m new file mode 100644 index 0000000..ba4470e --- /dev/null +++ b/SportSettingViewController.m @@ -0,0 +1,109 @@ +// +// SportSettingViewController.m +// MRMobileRun +// +// Created by 杨远舟 on 2020/8/6. +// + +#import "SportSettingViewController.h" +#import "Masonry.h" +@interface SportSettingViewController () + +@end + +@implementation SportSettingViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + [self.navigationItem setTitle:@"系统权限设置"]; + + UIButton *saveBtn = [[UIButton alloc]initWithFrame:CGRectMake(15, 300, 345, 50)]; + saveBtn.backgroundColor = [UIColor darkGrayColor]; + [saveBtn setTitle:@"快速设置" forState:UIControlStateNormal]; + [saveBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [saveBtn addTarget:self action:@selector(actionSet) forControlEvents:UIControlEventTouchUpInside]; + [saveBtn.layer setMasksToBounds:YES]; + [saveBtn.layer setCornerRadius:10.0]; + [self.view addSubview:saveBtn]; + [saveBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(self.view); + make.top.equalTo(self.view).offset(300*kRateY); + make.width.equalTo(@(345*kRateX)); + make.height.equalTo(@(50*kRateY)); + }]; + + UILabel *lable1 = [[UILabel alloc]initWithFrame:CGRectMake(25, 80, 330, 100)]; + lable1.text = @"由于系统的省电规则与后台限制,会误将约跑正在记录运动的进程杀掉。为了避免运动数据统计不准确请打开以下权限。"; + lable1.numberOfLines = 5; + [self.view addSubview:lable1]; + [lable1 mas_makeConstraints:^(MASConstraintMaker *make) { + //make.centerX.equalTo(self.view); + make.left.equalTo(self.view).offset(25*kRateY); + make.right.equalTo(self.view).offset(-25*kRateY); + make.top.equalTo(self.view).offset(80*kRateY); + //make.width.equalTo(@(330*kRateY)); + make.height.equalTo(@(100*kRateY)); + }]; + + UILabel *lable2 = [[UILabel alloc]initWithFrame:CGRectMake(25, 150, 330, 100)]; + lable2.text = @"白名单/自启动设置方法。"; + [lable2 setFont:[UIFont fontWithName:@"Helvetica-Bold"size:18]]; + [self.view addSubview:lable2]; + [lable2 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(25*kRateY); + make.right.equalTo(self.view).offset(-25*kRateY); + make.top.equalTo(self.view).offset(150*kRateY); + make.height.equalTo(@(100*kRateY)); + }]; + + UILabel *lable3 = [[UILabel alloc]initWithFrame:CGRectMake(25, 190, 330, 100)]; + lable3.text = @"设置->重邮约跑->允许约跑后台刷新"; + lable3.numberOfLines = 1; + [self.view addSubview:lable3]; + [lable3 mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.view).offset(25*kRateY); + make.right.equalTo(self.view).offset(-25*kRateY); + make.top.equalTo(self.view).offset(190*kRateY); + make.height.equalTo(@(100*kRateY)); + }]; + + if (@available(iOS 13.0, *)) { + UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return [UIColor whiteColor]; + } else { //深色模式 + saveBtn.backgroundColor = [UIColor colorWithRed:222/255.0 green:223/255.0 blue:229/255.0 alpha:1]; + [saveBtn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; + UIColor *color = [UIColor whiteColor]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:color forKey:UITextAttributeTextColor]; + self.navigationController.navigationBar.titleTextAttributes = dict; + + return [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } + }]; + self.view.backgroundColor = rightColor; //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } +} + +- (void)actionSet{ + if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) { + NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; + [[UIApplication sharedApplication]openURL:url options:@{} completionHandler:^(BOOL success) { + }]; + }else{ + //[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]] 应用标识 + NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:@"prefs:root=%@",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]]]; + [[UIApplication sharedApplication]openURL:url]; + } +} +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/YYZCommentViewController.m b/YYZCommentViewController.m new file mode 100644 index 0000000..b8ae29b --- /dev/null +++ b/YYZCommentViewController.m @@ -0,0 +1,101 @@ +// +// YYZCommentViewController.m +// MRMobileRun +// +// Created by 杨远舟 on 2020/8/6. +// +#import "Masonry.h" +#import "YYZCommentViewController.h" +#import "ZYLPersonalViewController.h" +@interface YYZCommentViewController () + +@end + +@implementation YYZCommentViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + + [self.navigationItem setTitle:@"意见反馈"]; + UIButton *saveBtn = [[UIButton alloc]initWithFrame:CGRectMake(13, 630, 350, 50)]; + saveBtn.backgroundColor = [UIColor darkGrayColor]; + [saveBtn setTitle:@"提交反馈" forState:UIControlStateNormal]; + [saveBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [saveBtn addTarget:self action:@selector(actionBack) forControlEvents:UIControlEventTouchUpInside]; + [saveBtn.layer setMasksToBounds:YES]; + [saveBtn.layer setCornerRadius:10.0]; + [self.view addSubview:saveBtn]; + [saveBtn mas_makeConstraints:^(MASConstraintMaker *make) { + //make.centerX.equalTo(self.view); + make.left.equalTo(self.view).offset(18*kRateY); + make.right.equalTo(self.view).offset(-18*kRateY); + make.bottom.equalTo(self.view).offset(-160*kRateY); + make.height.greaterThanOrEqualTo(@(50*kRateY)); + }]; + + UITextField *tf = [[UITextField alloc]initWithFrame:CGRectMake(18, 110, 342, 100)]; + tf.borderStyle = UITextBorderStyleNone; + tf.placeholder = @"请在此处写下你反馈的意见"; + //[tf setValue:[UIFont boldSystemFontOfSize:10] forKeyPath:@"_placeholderLabel.font"]; + tf.layer.cornerRadius = 13; + tf.layer.masksToBounds = YES; + tf.contentVerticalAlignment = UIControlContentVerticalAlignmentTop; + tf.backgroundColor = [UIColor colorWithRed:248/255.0 green:248/255.0 blue:248/255.0 alpha:1]; + UIView *paddingLeftView = [[UIView alloc] init]; + CGRect frame = tf.frame; + frame.size.width = 12; + paddingLeftView.frame = frame; + tf.leftViewMode = UITextFieldViewModeAlways; + tf.leftView = paddingLeftView; + [self.view addSubview:tf]; + [tf mas_makeConstraints:^(MASConstraintMaker *make) { + //make.centerX.equalTo(self.view); + make.left.equalTo(self.view).offset(18*kRateY); + make.right.equalTo(self.view).offset(-18*kRateY); + make.top.equalTo(self.view).offset(100*kRateY); + make.height.greaterThanOrEqualTo(@(100*kRateY)); + }]; + + if (@available(iOS 13.0, *)) { + UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return [UIColor whiteColor]; + } else { //深色模式 + tf.textColor = [UIColor whiteColor]; + tf.backgroundColor = [UIColor colorWithRed:75/255.0 green:76/255.0 blue:82/255.0 alpha:1]; + saveBtn.backgroundColor = [UIColor colorWithRed:222/255.0 green:223/255.0 blue:229/255.0 alpha:1]; + [saveBtn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; + UIColor *color = [UIColor whiteColor]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:color forKey:UITextAttributeTextColor]; + self.navigationController.navigationBar.titleTextAttributes = dict; + + return [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } + }]; + self.view.backgroundColor = rightColor; //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } +} +- (void)actionBack{ + + ZYLPersonalViewController *vc1 = [[ZYLPersonalViewController alloc]init]; + + [self.navigationController popViewControllerAnimated:YES]; + + + + // Do any additional setup after loading the view. + +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/YYZTextViewController.m b/YYZTextViewController.m new file mode 100644 index 0000000..b04a2a1 --- /dev/null +++ b/YYZTextViewController.m @@ -0,0 +1,111 @@ +#import "YYZTextViewController.h" +#import "ZYLPersonalViewController.h" +#import "Masonry.h" + +@interface YYZTextViewController () + +@end + +@implementation YYZTextViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + [self.navigationItem setTitle:@"个性签名"]; + UIButton *saveBtn = [[UIButton alloc]initWithFrame:CGRectMake(13, 630, 350, 50)]; + //UIButton *saveBtn = [[UIButton alloc]init]; + saveBtn.backgroundColor = [UIColor darkGrayColor]; + [saveBtn setTitle:@"保存签名" forState:UIControlStateNormal]; + [saveBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [saveBtn addTarget:self action:@selector(actionBack) forControlEvents:UIControlEventTouchUpInside]; + [saveBtn.layer setMasksToBounds:YES]; + [saveBtn.layer setCornerRadius:10.0]; + [self.view addSubview:saveBtn]; + [saveBtn mas_makeConstraints:^(MASConstraintMaker *make) { + //make.centerX.equalTo(self.view); + make.left.equalTo(self.view).offset(18*kRateY); + make.right.equalTo(self.view).offset(-18*kRateY); + make.bottom.equalTo(self.view).offset(-160*kRateY); + make.height.greaterThanOrEqualTo(@(50*kRateY)); + }]; + + UITextField *tf = [[UITextField alloc]initWithFrame:CGRectMake(18, 110, 342, 100)]; + tf.borderStyle = UITextBorderStyleNone; + tf.placeholder = @"请在此处写下你的个性签名"; + // [tf setValue:[UIFont boldSystemFontOfSize:7] forKeyPath:@"_placeholderLabel.font"]; + tf.layer.cornerRadius = 13; + tf.layer.masksToBounds = YES; + tf.contentVerticalAlignment = UIControlContentVerticalAlignmentTop; + tf.backgroundColor = [UIColor colorWithRed:248/255.0 green:248/255.0 blue:248/255.0 alpha:1]; + UIView *paddingLeftView = [[UIView alloc] init]; + CGRect frame = tf.frame; + frame.size.width = 12; + paddingLeftView.frame = frame; + tf.leftViewMode = UITextFieldViewModeAlways; + tf.leftView = paddingLeftView; + [self.view addSubview:tf]; + [tf mas_makeConstraints:^(MASConstraintMaker *make) { + //make.centerX.equalTo(self.view); + make.left.equalTo(self.view).offset(18*kRateY); + make.right.equalTo(self.view).offset(-18*kRateY); + make.top.equalTo(self.view).offset(100*kRateY); + make.height.greaterThanOrEqualTo(@(100*kRateY)); + }]; + + + if (@available(iOS 13.0, *)) { + UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return [UIColor whiteColor]; + } else { //深色模式 + tf.textColor = [UIColor whiteColor]; + tf.backgroundColor = [UIColor colorWithRed:75/255.0 green:76/255.0 blue:82/255.0 alpha:1]; + saveBtn.backgroundColor = [UIColor colorWithRed:222/255.0 green:223/255.0 blue:229/255.0 alpha:1]; + [saveBtn setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal]; + UIColor *color = [UIColor whiteColor]; + NSDictionary *dict = [NSDictionary dictionaryWithObject:color forKey:UITextAttributeTextColor]; + self.navigationController.navigationBar.titleTextAttributes = dict; + + return [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } + }]; + self.view.backgroundColor = rightColor; //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } + +} + +- (void)actionBack{ + + ZYLPersonalViewController *vc1 = [[ZYLPersonalViewController alloc]init]; + + [self.navigationController popViewControllerAnimated:YES]; + + + + // Do any additional setup after loading the view. + +} + + + +/* + +\#pragma mark - Navigation + + + +// In a storyboard-based application, you will often want to do a little preparation before navigation + +\- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + + // Get the new view controller using [segue destinationViewController]. + + // Pass the selected object to the new view controller. + +} + +*/ + + + +@end diff --git a/ZYLPersonalViewController.h b/ZYLPersonalViewController.h new file mode 100644 index 0000000..2cd4f3c --- /dev/null +++ b/ZYLPersonalViewController.h @@ -0,0 +1,16 @@ +// +// ZYLPersonalViewController.h +// MRMobileRun +// +// Created by 丁磊 on 2019/4/11. +// + +#import "MRBaseViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface ZYLPersonalViewController : MRBaseViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/ZYLPersonalViewController.m b/ZYLPersonalViewController.m new file mode 100644 index 0000000..9072a5e --- /dev/null +++ b/ZYLPersonalViewController.m @@ -0,0 +1,240 @@ +// +// ZYLPersonalViewController.m +// MRMobileRun +// +// Created by 丁磊 on 2019/4/11. +// + +#import "ZYLPersonalViewController.h" +#import "ZYLLoginViewController.h" +#import "ZYLSettingBackgound.h" +#import "ZYLUploadAvatar.h" +#import "ZYLChangeNickname.h" +#import "ZYLPhotoSelectedVIew.h" +#import "ZYLAvatarRequest.h" +#import "MRTabBarController.h" +#import +#import +#import "YYZCommentViewController.h" +#import "YYZTextViewController.h" +#import "AboutViewController.h" +#import "SportSettingViewController.h" +@interface ZYLPersonalViewController () + +//@property (strong, nonatomic) ZYLPersonalInformationView *personalInformationView; +@property (nonatomic, strong) ZYLSettingBackgound *bkgView; +@property (nonatomic,strong) MBProgressHUD *hud; +@property (nonatomic,strong) NSMutableDictionary *nicknameDic; +@property (strong, nonatomic) UIImageView *imageView; +@property (nonatomic, strong) NSUserDefaults *userDefaults; +@end + +@implementation ZYLPersonalViewController + +- (void)viewWillAppear:(BOOL)animated{ + [super viewDidAppear:animated]; + self.view.backgroundColor = [UIColor clearColor]; + [self.navigationController setNavigationBarHidden: NO]; +// 设置透明导航栏 + [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; + self.navigationController.navigationBar.shadowImage = [UIImage new]; + self.navigationController.navigationBar.translucent = YES; + self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor blackColor]}; // title颜色 + self.title = @"设置"; + if (@available(iOS 13.0, *)) { + UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return [UIColor whiteColor]; + } else { //深色模式 + self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor whiteColor]}; + return [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } + }]; + self.view.backgroundColor = rightColor; //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } + [self->_bkgView YYZdarkChange]; + +} +-(void)viewWillDisappear:(BOOL)animated{ + [self->_bkgView YYZdarkChange]; + +} +-(void)viewDidDisappear:(BOOL)animated{ + [self->_bkgView YYZdarkChange]; +} +-(void)viewDidAppear:(BOOL)animated{ + [self->_bkgView YYZdarkChange]; +} +- (void)viewDidLoad { + [super viewDidLoad]; + // [self setOverrideUserInterfaceStyle:UIUserInterfaceStyleDark]; + self.userDefaults = [NSUserDefaults standardUserDefaults]; +// [self.view addSubview: self.personalInformationView]; + [ZYLAvatarRequest ZYLGetAvatar]; + [self.view addSubview: self.bkgView]; + [_bkgView YYZdarkChange]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getAvatar:) name:@"getAvatar" object:nil]; +// NSData *imageData = [[NSData alloc] init]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myAvatar:) name:@"getAvatarSuccess" object: nil]; + + UIButton *textBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + textBtn.frame = CGRectMake(0, 210*kRateY, screenWidth, 70*kRateY); + textBtn.backgroundColor = [UIColor clearColor]; + [textBtn addTarget:self action:@selector(actionText) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:textBtn]; + + UIButton *aboutBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + aboutBtn.frame = CGRectMake(0, 280*kRateY, screenWidth, 70*kRateY); + aboutBtn.backgroundColor = [UIColor clearColor]; + [aboutBtn addTarget:self action:@selector(actionAbout) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:aboutBtn]; + + UIButton *settingBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + settingBtn.frame = CGRectMake(0, 350*kRateY, screenWidth, 70*kRateY); + settingBtn.backgroundColor = [UIColor clearColor]; + [settingBtn addTarget:self action:@selector(actionSetting) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:settingBtn]; + UIButton *commentBtn = [UIButton buttonWithType:UIButtonTypeCustom]; + commentBtn.frame = CGRectMake(0, 420*kRateY, screenWidth, 70*kRateY); + commentBtn.backgroundColor = [UIColor clearColor]; + [commentBtn addTarget:self action:@selector(actionComment) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:commentBtn]; + + if (@available(iOS 13.0, *)) { + UIColor * rightColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull trainCollection) { + if ([trainCollection userInterfaceStyle] == UIUserInterfaceStyleLight) { + return [UIColor whiteColor]; + } else { //深色模式 + self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor whiteColor]}; + + return [UIColor colorWithRed:60/255.0 green:63/255.0 blue:67/255.0 alpha:1]; + } + }]; + [self->_bkgView YYZdarkChange]; + self.view.backgroundColor = rightColor; //根据当前模式(光明\暗黑)-展示相应颜色 关键是这一句 + } + +} + +- (void)actionText{ + YYZTextViewController *vc1 =[[YYZTextViewController alloc]init]; + [self.navigationController pushViewController:vc1 animated:YES]; +} +- (void)actionAbout{ + AboutViewController *vc1 =[[AboutViewController alloc]init]; + [self.navigationController pushViewController:vc1 animated:YES]; +} +- (void)actionSetting{ + SportSettingViewController *vc1 =[[SportSettingViewController alloc]init]; + [self.navigationController pushViewController:vc1 animated:YES]; +} +- (void)actionComment{ + YYZCommentViewController *vc1 =[[YYZCommentViewController alloc]init]; + [self.navigationController pushViewController:vc1 animated:YES]; +} +- (void)clickLogoutBtu{ + [[NSNotificationCenter defaultCenter] postNotificationName:@"hideTabBar" object:nil]; +// NSDictionary *dic = [self.userDefaults dictionaryRepresentation]; +// for (id key in dic) +// { +// if ([key isEqual:@"studentID"] || [key isEqual:@"password"] || [key isEqual:@"nickname"] || [key isEqual:@"class_id"] || [key isEqual:@"token"]) +// { +// NSLog(@"非空%@ is %@",key,[self.userDefaults objectForKey:key]); +// [self.userDefaults removeObjectForKey:key]; +// } +// else +// { +// NSLog(@"空%@ is %@",key,[self.userDefaults objectForKey:key]); +// } +// } +// [self.userDefaults synchronize]; + [MGJRouter openURL:kLoginVCPageURL + withUserInfo:@{@"navigationVC" : self.navigationController, + } + completion:nil]; +} + +- (void)myAvatar:(NSNotification *)notification{ + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + UIImage *avatar = [UIImage imageWithData: [user objectForKey:@"myAvatar"] scale:1]; + self.imageView.image = avatar; + [self.bkgView.iconCell.iconButton setImage:avatar forState:UIControlStateNormal]; +} + +- (void)clickAvatarBtu{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + self.imageView = [[UIImageView alloc] init]; + self.imageView.image = [UIImage imageWithData: [defaults objectForKey:@"myAvatar"]]; + ZYLPhotoSelectedVIew *selectView = [ZYLPhotoSelectedVIew selectViewWithDestinationImageView: self.imageView delegate:self]; + selectView.iconImage = self.imageView.image; + [self.view addSubview:selectView]; +} + +- (void)getAvatar:(NSNotification*)notification{ + NSLog(@"\n\n\n\n获取成功\n\n\n\n"); + NSData *imageData = UIImageJPEGRepresentation(self.imageView.image, 1); +// // 将图片存储在本地 + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:imageData forKey: @"myAvatar"]; + [defaults synchronize]; + [self.bkgView.iconCell.iconButton setImage:[UIImage imageWithData:imageData] forState:UIControlStateNormal]; + + + [ZYLUploadAvatar UpdateAvatarWithImage:self.imageView.image]; +} + +- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ + + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"修改昵称" message:@"请在下方文本框内输入新的昵称" preferredStyle:UIAlertControllerStyleAlert]; + [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField){ + + }]; + + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; + [cancelAction setValue:[UIColor blackColor] forKey:@"titleTextColor"]; + + UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { + UITextField *nickName = alertController.textFields.firstObject; + if (![nickName.text isEqualToString:@""]) { + NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; + [user setObject:nickName.text forKey:@"nickname"]; + self.bkgView.nicknameCell.nicknameTextFiled.text = nickName.text; + self.nicknameDic = [[NSMutableDictionary alloc]init]; + [self.nicknameDic setObject:self.bkgView.nicknameCell.nicknameTextFiled.text forKey:@"nickname"]; + [ZYLChangeNickname uploadChangedNickname:nickName.text]; + } + }]; + + [okAction setValue:[UIColor blackColor] forKey:@"titleTextColor"]; + [alertController addAction:cancelAction]; + [alertController addAction:okAction]; + [self presentViewController:alertController animated:YES completion:nil]; + + return NO; +} + +#pragma mark - 懒加载 +- (ZYLSettingBackgound *)bkgView{ + if (!_bkgView) { + _bkgView = [[ZYLSettingBackgound alloc] init]; + _bkgView.frame = CGRectMake(0, kTabBarHeight, screenWidth, screenHeigth-kTabBarHeight); + [_bkgView.iconCell.iconButton addTarget: self action:@selector(clickAvatarBtu) forControlEvents:UIControlEventTouchUpInside]; + [_bkgView.logoutBtn addTarget:self action:@selector(clickLogoutBtu) forControlEvents:UIControlEventTouchUpInside]; + _bkgView.nicknameCell.nicknameTextFiled.text = [_userDefaults objectForKey:@"nickname"]; + _bkgView.nicknameCell.nicknameTextFiled.delegate = self; + _bkgView.nicknameCell.nicknameTextFiled.returnKeyType = UIReturnKeyDone; + } + return _bkgView; +} + + +- (MBProgressHUD *)hud{ + if (!_hud) { + _hud = [[MBProgressHUD alloc] init]; + } + return _hud; +} + + + +@end diff --git a/ZYLSettingBackgound.h b/ZYLSettingBackgound.h new file mode 100644 index 0000000..fabea35 --- /dev/null +++ b/ZYLSettingBackgound.h @@ -0,0 +1,28 @@ +// +// ZYLSettingBackgound.h +// MRMobileRun +// +// Created by 丁磊 on 2019/11/11. +// + +#import +#import "ZYLSettingNomalCell.h" +#import "ZYLSettingIconCell.h" +#import "ZYLSettingNameCell.h" +#import "ZYLSettingDarkModeCell.h" +#import "ZYLNicknameTextField.h" +NS_ASSUME_NONNULL_BEGIN + +@interface ZYLSettingBackgound : UIView +@property (nonatomic, strong) ZYLSettingDarkModeCell *switchCell; +@property (nonatomic, strong) ZYLSettingIconCell *iconCell; +@property (nonatomic, strong) ZYLSettingNameCell *nicknameCell; +@property (nonatomic, strong) ZYLSettingNomalCell *signCell; +@property (nonatomic, strong) ZYLSettingNomalCell *aboutCell; +@property (nonatomic, strong) ZYLSettingNomalCell *permissionCell; +@property (nonatomic, strong) ZYLSettingNomalCell *suggestionCell; +@property (nonatomic, strong) UIButton *logoutBtn; +//@property (nonatomic, strong) ZYLNicknameTextField *nicknameTextFiled; +-(void) YYZdarkChange; +@end +NS_ASSUME_NONNULL_END diff --git a/ZYLSettingBackgound.m b/ZYLSettingBackgound.m new file mode 100644 index 0000000..3d4011f --- /dev/null +++ b/ZYLSettingBackgound.m @@ -0,0 +1,152 @@ +// +// ZYLSettingBackgound.m +// MRMobileRun +// +// Created by 丁磊 on 2019/11/11. +// + +#import "ZYLSettingBackgound.h" +#import +@interface ZYLSettingBackgound () +@end + +@implementation ZYLSettingBackgound + +- (instancetype)init{ + self = [super init]; + if (self) { + [self initCells]; + [self initLogoutButton]; +// [self initTextField]; + } + return self; +} +//- (void)initTextField{ +// //输入昵称的文本框 +// +// self.nicknameTextFiled = [[ZYLNicknameTextField alloc]init]; +// [self addSubview:self.nicknameTextFiled]; +// [self.nicknameTextFiled mas_makeConstraints:^(MASConstraintMaker *make) { +// make.edges.equalTo (self).with.insets(UIEdgeInsetsMake(305.0/1334.0*screenHeigth, 101.0/750*screenWidth, 886.0/1334.0*screenHeigth, 43.0/750.0*screenWidth)); +// }]; +//} + +- (void)initCells{ + self.iconCell = [[ZYLSettingIconCell alloc] init]; + self.iconCell.frame = CGRectMake(0, 0, screenWidth, 70*kRateY); + [self addSubview: self.iconCell]; + + self.nicknameCell = [[ZYLSettingNameCell alloc] init]; + self.nicknameCell.frame = CGRectMake(0, 70*kRateY, screenWidth, 70*kRateY); + self.nicknameCell.userInteractionEnabled = YES; + [self addSubview: self.nicknameCell]; + + self.signCell = [[ZYLSettingNomalCell alloc] init]; + self.signCell.frame = CGRectMake(0, 140*kRateY, screenWidth, 70*kRateY); + self.signCell.textLab.text = @"个性签名"; + self.signCell.iconImage.image = [UIImage imageNamed:@"setting_sign"]; + [self addSubview:self.signCell]; + + self.aboutCell = [[ZYLSettingNomalCell alloc] init]; + self.aboutCell.frame = CGRectMake(0, 210*kRateY, screenWidth, 70*kRateY); + self.aboutCell.textLab.text = @"关于约跑"; + self.aboutCell.iconImage.image = [UIImage imageNamed:@"setting_about"]; + [self addSubview: self.aboutCell]; + + self.permissionCell = [[ZYLSettingNomalCell alloc] init]; + self.permissionCell.frame = CGRectMake(0, 280*kRateY, screenWidth, 70*kRateY); + self.permissionCell.textLab.text = @"运动权限设置"; + self.permissionCell.iconImage.image = [UIImage imageNamed: @"setting_authority"]; + [self addSubview: self.permissionCell]; + + self.suggestionCell = [[ZYLSettingNomalCell alloc] init]; + self.suggestionCell.frame = CGRectMake(0, 350*kRateY, screenWidth, 70*kRateY); + self.suggestionCell.textLab.text = @"意见反馈"; + self.suggestionCell.iconImage.image = [UIImage imageNamed:@"setting_suggestion"]; + [self addSubview: self.suggestionCell]; + + self.switchCell = [[ZYLSettingDarkModeCell alloc] init]; + self.switchCell.frame = CGRectMake(0, 420*kRateY, screenWidth, 70*kRateY); + // [self addSubview: self.switchCell]; + + + if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) { + } + else { //深色模式 + self.iconCell.textLab.textColor = [UIColor whiteColor]; + self.nicknameCell.textLab.textColor = [UIColor whiteColor]; + self.signCell.textLab.textColor = [UIColor whiteColor]; + self.aboutCell.textLab.textColor = [UIColor whiteColor]; + self.suggestionCell.textLab.textColor = [UIColor whiteColor]; + self.permissionCell.textLab.textColor = [UIColor whiteColor]; + self.switchCell.textLab.textColor = [UIColor whiteColor]; + + self.signCell.iconImage.image = [UIImage imageNamed:@"setting_sign_dark"]; + self.aboutCell.iconImage.image = [UIImage imageNamed:@"setting_about_dark"]; + self.permissionCell.iconImage.image = [UIImage imageNamed: @"setting_authority_dark"]; + self.suggestionCell.iconImage.image = [UIImage imageNamed:@"setting_suggestion_dark"]; + self.iconCell.iconImage.image = [UIImage imageNamed:@"setting_icon_dark"]; + self.nicknameCell.iconImage.image = [UIImage imageNamed:@"setting_nickname_dark"]; + self.switchCell.iconImage.image = [UIImage imageNamed:@"setting_darkMode_dark"]; + + } +} + +- (void)initLogoutButton{ + self.logoutBtn = [[UIButton alloc] initWithFrame:CGRectMake(16*kRateX,540*kRateY,screenWidth-32*kRateX,52*kRateY)]; + self.logoutBtn.backgroundColor = COLOR_WITH_HEX(0xFF5C77); + self.logoutBtn.layer.cornerRadius = 15*kRateX; + [self.logoutBtn setTitle:@"退出登录" forState:UIControlStateNormal]; + self.logoutBtn.titleLabel.textColor = [UIColor whiteColor]; + self.logoutBtn.titleLabel.font = [UIFont boldSystemFontOfSize:16*kRateX]; + [self addSubview: self.logoutBtn]; +} + +-(void)YYZdarkChange{ + if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleLight) { + self.iconCell.textLab.textColor = [UIColor blackColor]; + self.nicknameCell.textLab.textColor = [UIColor blackColor]; + self.signCell.textLab.textColor = [UIColor blackColor]; + self.aboutCell.textLab.textColor = [UIColor blackColor]; + self.suggestionCell.textLab.textColor = [UIColor blackColor]; + self.permissionCell.textLab.textColor = [UIColor blackColor]; + //self.switchCell.textLab.textColor = [UIColor blackColor]; + + self.signCell.iconImage.image = [UIImage imageNamed:@"setting_sign"]; + self.aboutCell.iconImage.image = [UIImage imageNamed:@"setting_about"]; + self.permissionCell.iconImage.image = [UIImage imageNamed: @"setting_authority"]; + self.suggestionCell.iconImage.image = [UIImage imageNamed:@"setting_suggestion"]; + self.iconCell.iconImage.image = [UIImage imageNamed:@"setting_icon"]; + self.nicknameCell.iconImage.image = [UIImage imageNamed:@"setting_nickname"]; + //self.switchCell.iconImage.image = [UIImage imageNamed:@"setting_darkMode"]; + } + else { //深色模式 + self.iconCell.textLab.textColor = [UIColor whiteColor]; + self.nicknameCell.textLab.textColor = [UIColor whiteColor]; + self.signCell.textLab.textColor = [UIColor whiteColor]; + self.aboutCell.textLab.textColor = [UIColor whiteColor]; + self.suggestionCell.textLab.textColor = [UIColor whiteColor]; + self.permissionCell.textLab.textColor = [UIColor whiteColor]; + //self.switchCell.textLab.textColor = [UIColor whiteColor]; + + self.signCell.iconImage.image = [UIImage imageNamed:@"setting_sign_dark"]; + self.aboutCell.iconImage.image = [UIImage imageNamed:@"setting_about_dark"]; + self.permissionCell.iconImage.image = [UIImage imageNamed: @"setting_authority_dark"]; + self.suggestionCell.iconImage.image = [UIImage imageNamed:@"setting_suggestion_dark"]; + self.iconCell.iconImage.image = [UIImage imageNamed:@"setting_icon_dark"]; + self.nicknameCell.iconImage.image = [UIImage imageNamed:@"setting_nickname_dark"]; + // self.switchCell.iconImage.image = [UIImage imageNamed:@"setting_darkMode_dark"]; + + } +} + + +/* +// Only override drawRect: if you perform custom drawing. +// An empty implementation adversely affects performance during animation. +- (void)drawRect:(CGRect)rect { + // Drawing code +} +*/ + +@end diff --git a/MRMobileRun/MRRunning/ZYLUptateRunningData.h b/ZYLUptateRunningData.h similarity index 100% rename from MRMobileRun/MRRunning/ZYLUptateRunningData.h rename to ZYLUptateRunningData.h diff --git a/MRMobileRun/MRRunning/ZYLUptateRunningData.m b/ZYLUptateRunningData.m similarity index 100% rename from MRMobileRun/MRRunning/ZYLUptateRunningData.m rename to ZYLUptateRunningData.m