浏览代码

仪表盘效果

Steven 2 年之前
父节点
当前提交
59fb84d8a7
共有 24 个文件被更改,包括 1219 次插入106 次删除
  1. 20 0
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/TuningImage/instrument_choose.imageset/Contents.json
  3. 二进制
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/TuningImage/instrument_choose.imageset/instrument_choose@2x.png
  4. 二进制
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/TuningImage/instrument_choose.imageset/instrument_choose@3x.png
  5. 10 5
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSUploadManager.m
  6. 14 14
      KulexiuForStudent/KulexiuForStudent/Common/Define/PrefixHeader.pch
  7. 124 12
      KulexiuForStudent/KulexiuForStudent/Module/Widget/Controller/ToneTuningViewController.m
  8. 51 0
      KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/TuningFunction/Tuner.swift
  9. 16 0
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/KSGaugeView/KSGaugeColorView.h
  10. 72 0
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/KSGaugeView/KSGaugeColorView.m
  11. 51 0
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/KSGaugeView/KSGaugeView.h
  12. 337 0
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/KSGaugeView/KSGaugeView.m
  13. 48 5
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WMGaugeView/WMGaugeView.m
  14. 10 10
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WMGaugeView/WMGaugeViewStyle3D.m
  15. 3 1
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WMGaugeView/WMGaugeViewStyleFlatThin.h
  16. 20 15
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WMGaugeView/WMGaugeViewStyleFlatThin.m
  17. 2 2
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/DialPlateView.h
  18. 2 16
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/DialPlateView.m
  19. 12 1
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/ToneTuningBodyView.h
  20. 17 0
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/ToneTuningBodyView.m
  21. 56 17
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/ToneTuningBodyView.xib
  22. 21 0
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/TunerSettingView.h
  23. 72 0
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/TunerSettingView.m
  24. 239 8
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/TunerSettingView.xib

+ 20 - 0
KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj

@@ -886,6 +886,8 @@
 		BCD457AB286469600010B493 /* PublicNoticeView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD457A92864695F0010B493 /* PublicNoticeView.m */; };
 		BCD457AB286469600010B493 /* PublicNoticeView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD457A92864695F0010B493 /* PublicNoticeView.m */; };
 		BCD457AC286469600010B493 /* PublicNoticeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCD457AA286469600010B493 /* PublicNoticeView.xib */; };
 		BCD457AC286469600010B493 /* PublicNoticeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCD457AA286469600010B493 /* PublicNoticeView.xib */; };
 		BCD457AF28646B580010B493 /* NoticeSourceModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD457AE28646B580010B493 /* NoticeSourceModel.m */; };
 		BCD457AF28646B580010B493 /* NoticeSourceModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD457AE28646B580010B493 /* NoticeSourceModel.m */; };
+		BCD886E12907E7AE00BC4EE6 /* KSGaugeView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD886E02907E7AE00BC4EE6 /* KSGaugeView.m */; };
+		BCD886E42908E69900BC4EE6 /* KSGaugeColorView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD886E32908E69900BC4EE6 /* KSGaugeColorView.m */; };
 		BCD9294F28F8FCA4006793E4 /* AudioKit in Frameworks */ = {isa = PBXBuildFile; productRef = BCD9294E28F8FCA4006793E4 /* AudioKit */; };
 		BCD9294F28F8FCA4006793E4 /* AudioKit in Frameworks */ = {isa = PBXBuildFile; productRef = BCD9294E28F8FCA4006793E4 /* AudioKit */; };
 		BCD9295228F90202006793E4 /* ToneTuningBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD9295128F90202006793E4 /* ToneTuningBodyView.m */; };
 		BCD9295228F90202006793E4 /* ToneTuningBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD9295128F90202006793E4 /* ToneTuningBodyView.m */; };
 		BCD9295428F90209006793E4 /* ToneTuningBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCD9295328F90209006793E4 /* ToneTuningBodyView.xib */; };
 		BCD9295428F90209006793E4 /* ToneTuningBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCD9295328F90209006793E4 /* ToneTuningBodyView.xib */; };
@@ -2492,6 +2494,10 @@
 		BCD457AA286469600010B493 /* PublicNoticeView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PublicNoticeView.xib; sourceTree = "<group>"; };
 		BCD457AA286469600010B493 /* PublicNoticeView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PublicNoticeView.xib; sourceTree = "<group>"; };
 		BCD457AD28646B580010B493 /* NoticeSourceModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NoticeSourceModel.h; sourceTree = "<group>"; };
 		BCD457AD28646B580010B493 /* NoticeSourceModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NoticeSourceModel.h; sourceTree = "<group>"; };
 		BCD457AE28646B580010B493 /* NoticeSourceModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NoticeSourceModel.m; sourceTree = "<group>"; };
 		BCD457AE28646B580010B493 /* NoticeSourceModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NoticeSourceModel.m; sourceTree = "<group>"; };
+		BCD886DF2907E7AE00BC4EE6 /* KSGaugeView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSGaugeView.h; sourceTree = "<group>"; };
+		BCD886E02907E7AE00BC4EE6 /* KSGaugeView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSGaugeView.m; sourceTree = "<group>"; };
+		BCD886E22908E69900BC4EE6 /* KSGaugeColorView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSGaugeColorView.h; sourceTree = "<group>"; };
+		BCD886E32908E69900BC4EE6 /* KSGaugeColorView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSGaugeColorView.m; sourceTree = "<group>"; };
 		BCD9295028F90202006793E4 /* ToneTuningBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ToneTuningBodyView.h; sourceTree = "<group>"; };
 		BCD9295028F90202006793E4 /* ToneTuningBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ToneTuningBodyView.h; sourceTree = "<group>"; };
 		BCD9295128F90202006793E4 /* ToneTuningBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ToneTuningBodyView.m; sourceTree = "<group>"; };
 		BCD9295128F90202006793E4 /* ToneTuningBodyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ToneTuningBodyView.m; sourceTree = "<group>"; };
 		BCD9295328F90209006793E4 /* ToneTuningBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ToneTuningBodyView.xib; sourceTree = "<group>"; };
 		BCD9295328F90209006793E4 /* ToneTuningBodyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ToneTuningBodyView.xib; sourceTree = "<group>"; };
@@ -4658,6 +4664,7 @@
 		BC4CF28B28D058FB00961C61 /* View */ = {
 		BC4CF28B28D058FB00961C61 /* View */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				BCD886DE2907E75300BC4EE6 /* KSGaugeView */,
 				BCD9295528F9447B006793E4 /* WMGaugeView */,
 				BCD9295528F9447B006793E4 /* WMGaugeView */,
 				BCFEED7028F7F16C0078A2B7 /* toneTuning */,
 				BCFEED7028F7F16C0078A2B7 /* toneTuning */,
 				BCFEED4E28F7E4910078A2B7 /* Metronome */,
 				BCFEED4E28F7E4910078A2B7 /* Metronome */,
@@ -6097,6 +6104,17 @@
 			path = images;
 			path = images;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		BCD886DE2907E75300BC4EE6 /* KSGaugeView */ = {
+			isa = PBXGroup;
+			children = (
+				BCD886DF2907E7AE00BC4EE6 /* KSGaugeView.h */,
+				BCD886E02907E7AE00BC4EE6 /* KSGaugeView.m */,
+				BCD886E22908E69900BC4EE6 /* KSGaugeColorView.h */,
+				BCD886E32908E69900BC4EE6 /* KSGaugeColorView.m */,
+			);
+			path = KSGaugeView;
+			sourceTree = "<group>";
+		};
 		BCD9295528F9447B006793E4 /* WMGaugeView */ = {
 		BCD9295528F9447B006793E4 /* WMGaugeView */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
@@ -7041,6 +7059,7 @@
 				BC8A45AC283DC33400094BBB /* KSSliderView.m in Sources */,
 				BC8A45AC283DC33400094BBB /* KSSliderView.m in Sources */,
 				2723B62927F157D500E0B90B /* KSChatComplainController.m in Sources */,
 				2723B62927F157D500E0B90B /* KSChatComplainController.m in Sources */,
 				2779351527E324A60010E277 /* NSArray+KSSafe.m in Sources */,
 				2779351527E324A60010E277 /* NSArray+KSSafe.m in Sources */,
+				BCD886E42908E69900BC4EE6 /* KSGaugeColorView.m in Sources */,
 				2723B61A27F157D500E0B90B /* KSSearchResultViewCell.m in Sources */,
 				2723B61A27F157D500E0B90B /* KSSearchResultViewCell.m in Sources */,
 				BC48C3A92828FC7D00EE65C5 /* KSUploadManager.m in Sources */,
 				BC48C3A92828FC7D00EE65C5 /* KSUploadManager.m in Sources */,
 				BC8A4599283DC33400094BBB /* TBXML.m in Sources */,
 				BC8A4599283DC33400094BBB /* TBXML.m in Sources */,
@@ -7313,6 +7332,7 @@
 				BC8A459D283DC33400094BBB /* KSParseMessageModel.m in Sources */,
 				BC8A459D283DC33400094BBB /* KSParseMessageModel.m in Sources */,
 				275FA23327E7356B00CFEA2E /* VefiCodeLoginController.m in Sources */,
 				275FA23327E7356B00CFEA2E /* VefiCodeLoginController.m in Sources */,
 				BCB6359C27F6D2AB00ACFDCF /* ClassVideoListCell.m in Sources */,
 				BCB6359C27F6D2AB00ACFDCF /* ClassVideoListCell.m in Sources */,
+				BCD886E12907E7AE00BC4EE6 /* KSGaugeView.m in Sources */,
 				2723B61B27F157D500E0B90B /* KSSearchRCLabel.m in Sources */,
 				2723B61B27F157D500E0B90B /* KSSearchRCLabel.m in Sources */,
 				BC7E770F2900F38F00EB37AF /* TuningForkSettingView.m in Sources */,
 				BC7E770F2900F38F00EB37AF /* TuningForkSettingView.m in Sources */,
 				275FA23B27E7356B00CFEA2E /* PasswordBodyView.m in Sources */,
 				275FA23B27E7356B00CFEA2E /* PasswordBodyView.m in Sources */,

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/TuningImage/instrument_choose.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "instrument_choose@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "instrument_choose@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

二进制
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/TuningImage/instrument_choose.imageset/instrument_choose@2x.png


二进制
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/TuningImage/instrument_choose.imageset/instrument_choose@3x.png


+ 10 - 5
KulexiuForStudent/KulexiuForStudent/Common/Base/KSUploadManager.m

@@ -24,6 +24,9 @@
 // 上传位置全路径
 // 上传位置全路径
 @property (nonatomic, strong) NSString *uploadBucket;
 @property (nonatomic, strong) NSString *uploadBucket;
 
 
+// 访问位置全路径
+@property (nonatomic, strong) NSString *receiveBucket;
+
 // bucket
 // bucket
 @property (nonatomic, strong) NSString *bucketName;
 @property (nonatomic, strong) NSString *bucketName;
 
 
@@ -46,12 +49,14 @@
     }
     }
     self.bucketName = bucketName;
     self.bucketName = bucketName;
     self.uploadBucket = [NSString stringWithFormat:@"ks3-cn-beijing.ksyuncs.com/%@",bucketName];
     self.uploadBucket = [NSString stringWithFormat:@"ks3-cn-beijing.ksyuncs.com/%@",bucketName];
+    self.receiveBucket = [NSString stringWithFormat:@"%@.ks3-cn-beijing.ksyuncs.com",bucketName];
     [[KS3Client initialize] setBucketDomain:self.uploadBucket];
     [[KS3Client initialize] setBucketDomain:self.uploadBucket];
 }
 }
 
 
 - (void)configCilentBucket {
 - (void)configCilentBucket {
     self.bucketName = @"daya";
     self.bucketName = @"daya";
     self.uploadBucket = @"ks3-cn-beijing.ksyuncs.com/daya";
     self.uploadBucket = @"ks3-cn-beijing.ksyuncs.com/daya";
+    self.receiveBucket = [NSString stringWithFormat:@"daya.ks3-cn-beijing.ksyuncs.com"];
     [[KS3Client initialize] setBucketDomain:self.uploadBucket];
     [[KS3Client initialize] setBucketDomain:self.uploadBucket];
 }
 }
 
 
@@ -81,7 +86,7 @@
                 if (response.error == nil) {
                 if (response.error == nil) {
                     if (self.successCallback) {
                     if (self.successCallback) {
                         NSMutableArray *fileUrlArray = [NSMutableArray array];
                         NSMutableArray *fileUrlArray = [NSMutableArray array];
-                        [fileUrlArray addObject:[NSString stringWithFormat:@"https://%@/%@",self.uploadBucket,uploadFileName]];
+                        [fileUrlArray addObject:[NSString stringWithFormat:@"https://%@/%@",self.receiveBucket,uploadFileName]];
                         self.successCallback(fileUrlArray);
                         self.successCallback(fileUrlArray);
                     }
                     }
                 }
                 }
@@ -153,7 +158,7 @@
                 KS3PutObjectResponse *response = [[KS3Client initialize] putObject:putObjRequest];
                 KS3PutObjectResponse *response = [[KS3Client initialize] putObject:putObjRequest];
                 if (response.httpStatusCode == 200) {
                 if (response.httpStatusCode == 200) {
                     if (response.error == nil) {
                     if (response.error == nil) {
-                        [responses addObject:[NSString stringWithFormat:@"https://%@/%@",self.uploadBucket,uploadFileName]];
+                        [responses addObject:[NSString stringWithFormat:@"https://%@/%@",self.receiveBucket,uploadFileName]];
                     }
                     }
                     else {
                     else {
                         NSString *desc = [NSString stringWithFormat:@"第%d次上传文件失败",i];
                         NSString *desc = [NSString stringWithFormat:@"第%d次上传文件失败",i];
@@ -207,7 +212,7 @@
     }
     }
     NSString *uploadFileName = [NSString stringWithFormat:@"%@-%@%@%@",UserDefault(UIDKey),[NSDate getCurrentTimestamp], fileName,fileSuffix];
     NSString *uploadFileName = [NSString stringWithFormat:@"%@-%@%@%@",UserDefault(UIDKey),[NSDate getCurrentTimestamp], fileName,fileSuffix];
     NSString *keyValue = uploadFileName;
     NSString *keyValue = uploadFileName;
-    self.videoLinkUrl = [NSString stringWithFormat:@"https://%@/%@",self.uploadBucket,uploadFileName];
+    self.videoLinkUrl = [NSString stringWithFormat:@"https://%@/%@",self.receiveBucket,uploadFileName];
     [KSNetworkingManager getUploadSignRequest:KS_POST fileName:uploadFileName keyName:keyValue bucketName:self.bucketName success:^(NSDictionary * _Nonnull dic) {
     [KSNetworkingManager getUploadSignRequest:KS_POST fileName:uploadFileName keyName:keyValue bucketName:self.bucketName success:^(NSDictionary * _Nonnull dic) {
         if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
         if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
             KS3AccessControlList *acl = [[KS3AccessControlList alloc] init];
             KS3AccessControlList *acl = [[KS3AccessControlList alloc] init];
@@ -221,7 +226,7 @@
             self->_fileSize = putObjRequest.data.length;
             self->_fileSize = putObjRequest.data.length;
             putObjRequest.delegate = self;
             putObjRequest.delegate = self;
             [putObjRequest setCompleteRequest];
             [putObjRequest setCompleteRequest];
-            self.videoLinkUrl = [NSString stringWithFormat:@"https://%@/%@",self.uploadBucket,uploadFileName];
+            self.videoLinkUrl = [NSString stringWithFormat:@"https://%@/%@",self.receiveBucket,uploadFileName];
             KS3PutObjectResponse *response = [[KS3Client initialize] putObject:putObjRequest];
             KS3PutObjectResponse *response = [[KS3Client initialize] putObject:putObjRequest];
             if (putObjRequest.delegate == nil) {
             if (putObjRequest.delegate == nil) {
                 NSLog(@"%@",[[NSString alloc] initWithData:response.body encoding:NSUTF8StringEncoding]);
                 NSLog(@"%@",[[NSString alloc] initWithData:response.body encoding:NSUTF8StringEncoding]);
@@ -271,7 +276,7 @@
                 if (response.error == nil) {
                 if (response.error == nil) {
                     if (self.successCallback) {
                     if (self.successCallback) {
                         NSMutableArray *fileUrlArray = [NSMutableArray array];
                         NSMutableArray *fileUrlArray = [NSMutableArray array];
-                        [fileUrlArray addObject:[NSString stringWithFormat:@"https://%@/%@",self.uploadBucket,uploadFileName]];
+                        [fileUrlArray addObject:[NSString stringWithFormat:@"https://%@/%@",self.receiveBucket,uploadFileName]];
                         self.successCallback(fileUrlArray);
                         self.successCallback(fileUrlArray);
                     }
                     }
                 }
                 }

+ 14 - 14
KulexiuForStudent/KulexiuForStudent/Common/Define/PrefixHeader.pch

@@ -139,13 +139,13 @@ shouldPrevent = NO; \
 
 
 //#ifdef DEBUG
 //#ifdef DEBUG
 
 
-//#define hostURL (@"https://dev.colexiu.com")
-//#define SEALCLASSHOST (@"https://dev.colexiu.com/api-classroom")
-//#define WEBHOST (@"https://dev.colexiu.com/student")
-//#define SOCKET_URL (@"wss://dev.colexiu.com/audioAnalysis")
-//#define JSPUSH_ENVIRONMENT (NO)
-//#define RCIM_KEY (@"0vnjpoad0jbdz")
-//#define SUBMIT_UUID (YES)
+#define hostURL (@"https://dev.colexiu.com")
+#define SEALCLASSHOST (@"https://dev.colexiu.com/api-classroom")
+#define WEBHOST (@"https://dev.colexiu.com/student")
+#define SOCKET_URL (@"wss://dev.colexiu.com/audioAnalysis")
+#define JSPUSH_ENVIRONMENT (NO)
+#define RCIM_KEY (@"0vnjpoad0jbdz")
+#define SUBMIT_UUID (YES)
 
 
 // 预生产环境
 // 预生产环境
 
 
@@ -159,13 +159,13 @@ shouldPrevent = NO; \
 
 
 //#else
 //#else
 
 
-#define hostURL (@"https://online.colexiu.com")
-#define SEALCLASSHOST (@"https://online.colexiu.com/api-classroom")
-#define WEBHOST (@"https://online.colexiu.com/student")
-#define SOCKET_URL (@"wss://online.colexiu.com/audioAnalysis")
-#define JSPUSH_ENVIRONMENT (YES)
-#define RCIM_KEY (@"e5t4ouvpe42pa")
-#define SUBMIT_UUID (YES)
+//#define hostURL (@"https://online.colexiu.com")
+//#define SEALCLASSHOST (@"https://online.colexiu.com/api-classroom")
+//#define WEBHOST (@"https://online.colexiu.com/student")
+//#define SOCKET_URL (@"wss://online.colexiu.com/audioAnalysis")
+//#define JSPUSH_ENVIRONMENT (YES)
+//#define RCIM_KEY (@"e5t4ouvpe42pa")
+//#define SUBMIT_UUID (YES)
 
 
 //#endif
 //#endif
 
 

+ 124 - 12
KulexiuForStudent/KulexiuForStudent/Module/Widget/Controller/ToneTuningViewController.m

@@ -12,6 +12,9 @@
 #import "DialPlateView.h"
 #import "DialPlateView.h"
 #import "TuningForkSettingView.h"
 #import "TuningForkSettingView.h"
 #import <AVFoundation/AVFoundation.h>
 #import <AVFoundation/AVFoundation.h>
+#import "TunerSettingView.h"
+#import "KSChoosePicker.h"
+//#import "KSGaugeView.h"
 
 
 @interface ToneTuningViewController ()<TunerDelegate>
 @interface ToneTuningViewController ()<TunerDelegate>
 
 
@@ -33,6 +36,19 @@
 
 
 @property (nonatomic, strong) TunerForkManager *forkManager;
 @property (nonatomic, strong) TunerForkManager *forkManager;
 
 
+@property (nonatomic, strong) TunerSettingView *settingView;
+
+@property (nonatomic, strong) KSChoosePicker *instrumentPicker;
+
+@property (nonatomic, strong) NSArray *instrumentArray;
+
+@property (nonatomic, strong) NSArray *picthRateArray;
+
+// 判断是否选择移调乐器
+@property (nonatomic, assign) NSInteger toneChangeRate;
+
+@property (nonatomic, strong) NSArray *picthDescArray;
+
 @end
 @end
 
 
 @implementation ToneTuningViewController
 @implementation ToneTuningViewController
@@ -41,11 +57,16 @@
     [super viewDidLoad];
     [super viewDidLoad];
     // Do any additional setup after loading the view.
     // Do any additional setup after loading the view.
     self.ks_prefersNavigationBarHidden = YES;
     self.ks_prefersNavigationBarHidden = YES;
-    self.chooseFrequence = 440;
+    [self configDefault];
     [self configUI];
     [self configUI];
     [self setupAudioSession];
     [self setupAudioSession];
 }
 }
 
 
+- (void)configDefault {
+    self.chooseFrequence = 440;
+    self.isTransfer = NO;
+}
+
 - (void)setupAudioSession {
 - (void)setupAudioSession {
     
     
     AVAudioSession *audioSession = [AVAudioSession sharedInstance];
     AVAudioSession *audioSession = [AVAudioSession sharedInstance];
@@ -63,7 +84,6 @@
 - (void)configUI {
 - (void)configUI {
     [self.scrollView removeFromSuperview];
     [self.scrollView removeFromSuperview];
     CAGradientLayer *layer = [self createGradientLayerFromColor:HexRGB(0x1D2027) startPoint:CGPointMake(0.5, 0) endColor:HexRGB(0x17181C) endPoint:CGPointMake(0.5, 1) bounds:CGRectMake(0, 0, KPortraitWidth, KPortraitHeight)];
     CAGradientLayer *layer = [self createGradientLayerFromColor:HexRGB(0x1D2027) startPoint:CGPointMake(0.5, 0) endColor:HexRGB(0x17181C) endPoint:CGPointMake(0.5, 1) bounds:CGRectMake(0, 0, KPortraitWidth, KPortraitHeight)];
-    layer.cornerRadius = 14.0f;
     layer.masksToBounds = YES;
     layer.masksToBounds = YES;
     [self.view.layer addSublayer:layer];
     [self.view.layer addSublayer:layer];
     
     
@@ -80,6 +100,11 @@
         make.top.mas_equalTo(self.navView.mas_bottom);
         make.top.mas_equalTo(self.navView.mas_bottom);
         make.bottom.mas_equalTo(self.view.mas_bottom).offset(-iPhoneXSafeBottomMargin);
         make.bottom.mas_equalTo(self.view.mas_bottom).offset(-iPhoneXSafeBottomMargin);
     }];
     }];
+//    KSGaugeView *gaugeView = [[KSGaugeView alloc] init];
+//    [self.bodyView.plateView addSubview:gaugeView];
+//    [gaugeView mas_makeConstraints:^(MASConstraintMaker *make) {
+//        make.top.bottom.left.right.mas_equalTo(self.bodyView.plateView);
+//    }];
     [self.bodyView.plateView addSubview:self.plateView];
     [self.bodyView.plateView addSubview:self.plateView];
     [self.plateView mas_makeConstraints:^(MASConstraintMaker *make) {
     [self.plateView mas_makeConstraints:^(MASConstraintMaker *make) {
         make.top.bottom.left.right.mas_equalTo(self.bodyView.plateView);
         make.top.bottom.left.right.mas_equalTo(self.bodyView.plateView);
@@ -138,7 +163,7 @@
 }
 }
 
 
 - (void)showSettingView {
 - (void)showSettingView {
-    
+    [self.settingView showView];
 }
 }
 
 
 - (Tuner *)tuner {
 - (Tuner *)tuner {
@@ -154,17 +179,33 @@
         
         
     }
     }
     else {
     else {
-//        self.plateView.gaugeView.value = output.distance;
-        [self.plateView.gaugeView setValue:output.distance animated:YES];
+//        if (fabs(output.distance) > 1) {
+            self.plateView.gaugeView.value = (NSInteger)output.distance;
+        self.bodyView.distance = (NSInteger)output.distance;
+//        }
+        
+//        [self.plateView.gaugeView setValue:output.distance animated:YES];
+        
+        
+        // 调整频率后
+        
         if (self.isTransfer == NO) {
         if (self.isTransfer == NO) {
             self.bodyView.nomalPitch.text = output.pitch;
             self.bodyView.nomalPitch.text = output.pitch;
             self.bodyView.pitchFrequenceLabel.text = [NSString stringWithFormat:@"%@%zd:%.0fHz", output.pitch, output.octave, output.frequency];
             self.bodyView.pitchFrequenceLabel.text = [NSString stringWithFormat:@"%@%zd:%.0fHz", output.pitch, output.octave, output.frequency];
+            self.bodyView.preFrequence.text = [NSString stringWithFormat:@"%@%zd",output.prePitch, output.preOctave];
+            self.bodyView.nextFrequence.text = [NSString stringWithFormat:@"%@%zd",output.nextPitch, output.nextOctave];
         }
         }
         else {
         else {
+            self.bodyView.transferNomalPitch.text = output.pitch;
+            self.bodyView.transferDesc.text = self.settingView.transferPicthDesc;
+//            self.bodyView.transferPitch.text = 
+            self.bodyView.pitchFrequenceLabel.text = [NSString stringWithFormat:@"%@%zd:%.0fHz", output.pitch, output.octave, output.frequency];
+            self.bodyView.preFrequence.text = [NSString stringWithFormat:@"%@%zd",output.prePitch, output.preOctave];
+            self.bodyView.nextFrequence.text = [NSString stringWithFormat:@"%@%zd",output.nextPitch, output.nextOctave];
             
             
         }
         }
     }
     }
-//    NSLog(@"-------- %@%zd --- distance :%f frequence : %f" , output.pitch, output.octave, output.distance, output.frequency);
+    NSLog(@"-------- %@%zd --- distance :%f frequence : %f" , output.pitch, output.octave, output.distance, output.frequency);
     
     
 }
 }
 
 
@@ -183,11 +224,6 @@
 
 
 - (void)tuningAction:(TUNINGACTION)action frequence:(NSInteger)frequence {
 - (void)tuningAction:(TUNINGACTION)action frequence:(NSInteger)frequence {
     switch (action) {
     switch (action) {
-        case TUNINGACTION_SETTING: // 乐器选择
-        {
-            
-        }
-            break;
         case TUNINGACTION_FORKSETTING:  // 音叉设置
         case TUNINGACTION_FORKSETTING:  // 音叉设置
         {
         {
             [self.forkView showView];
             [self.forkView showView];
@@ -195,7 +231,9 @@
             break;
             break;
         case TUNINGACTION_FREQUENCE: // 调整频率
         case TUNINGACTION_FREQUENCE: // 调整频率
         {
         {
-            
+            self.chooseFrequence = frequence;
+            self.settingView.A4Frequence = frequence;
+            self.tuner.A4Frequence = frequence;
         }
         }
             break;
             break;
         case TUNINGACTION_PLAY:      // 播放音叉
         case TUNINGACTION_PLAY:      // 播放音叉
@@ -233,6 +271,7 @@
 - (TuningForkSettingView *)forkView {
 - (TuningForkSettingView *)forkView {
     if (!_forkView) {
     if (!_forkView) {
         _forkView = [TuningForkSettingView shareInstance];
         _forkView = [TuningForkSettingView shareInstance];
+        _forkView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight);
         MJWeakSelf;
         MJWeakSelf;
         [_forkView forkSettingAction:^(NSInteger frequence) {
         [_forkView forkSettingAction:^(NSInteger frequence) {
             NSLog(@"----- frequence %zd", frequence);
             NSLog(@"----- frequence %zd", frequence);
@@ -252,6 +291,79 @@
     return _forkManager;
     return _forkManager;
 }
 }
 
 
+- (TunerSettingView *)settingView {
+    if (!_settingView) {
+        _settingView = [TunerSettingView shareInstance];
+        _settingView.A4Frequence = self.chooseFrequence;
+        _settingView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight);
+        MJWeakSelf;
+        [_settingView tunerSettingAction:^(TUNETSETTING_ACTION action, NSInteger toneChangeRate, NSInteger frequence) {
+            [weakSelf tunerSettingAction:action picthRate:toneChangeRate frequence:frequence];
+        }];
+    }
+    return _settingView;
+}
+
+
+- (void)tunerSettingAction:(TUNETSETTING_ACTION)action picthRate:(NSInteger)toneChangeRate frequence:(NSInteger)frequence {
+    if (action == TUNETSETTING_ACTION_INSTRUMENT) {
+        // 选择乐器
+        MJWeakSelf;
+        self.instrumentPicker = [[KSChoosePicker alloc] initWithTitle:@"" sourceData:self.instrumentArray chooseReturnWithBlock:^(NSString * _Nonnull returnValue, NSInteger chooseIndex) {
+            weakSelf.settingView.instrumentLabel.text = returnValue;
+            NSInteger pitchRate = [self.picthRateArray[chooseIndex] integerValue];
+            weakSelf.settingView.toneChangeRate = pitchRate;
+            weakSelf.settingView.transferPicthDesc = self.picthDescArray[chooseIndex];
+        } cancel:^{
+            
+        }];
+        [self.instrumentPicker showPicker];
+    }
+    else if (action == TUNETSETTING_ACTION_SURE) {
+        // 设置成功
+        self.chooseFrequence = frequence;
+        self.bodyView.A4Frequence = frequence;
+        self.toneChangeRate = toneChangeRate;
+        self.tuner.A4Frequence = frequence;
+    }
+}
+
+- (NSArray *)instrumentArray {
+    if (!_instrumentArray) {
+        _instrumentArray = @[@"长笛:C大调",@"高音萨克斯:降B大调",@"中音萨克斯:降E大调",@"单簧管:降B大调",@"双簧管:C大调",@"竖笛:C调大调",@"小号:降B大调",@"长号:C大调",@"圆号:F大调",@"大号:降B大调",@"上低音号:C大调",@"上低音号:降B大调"];
+    }
+    return _instrumentArray;
+}
+
+- (NSArray *)picthRateArray {
+    if (!_picthRateArray) {
+        _picthRateArray = @[@0,@1,@8,@1,@0,@-12,@1,@0,@-5,@1,@0,@1];
+    }
+    return _picthRateArray;
+}
+
+- (NSArray *)picthDescArray {
+    if (!_picthDescArray) {
+        _picthDescArray = @[@"C ins.",@"B ins.",@"E ins.",@"B ins.",@"C ins.",@"C调大调 ins.",@"B ins.",@"C ins.",@"F ins.",@"C ins.",@"B ins."];
+    }
+    return _picthDescArray;
+}
+
+- (void)setToneChangeRate:(NSInteger)toneChangeRate {
+    _toneChangeRate = toneChangeRate;
+    self.tuner.toneChangeRate = toneChangeRate;
+    if (_toneChangeRate == 0) { // 
+        self.isTransfer = NO;
+    }
+    else {
+        self.isTransfer = YES;
+    }
+}
+
+- (void)setIsTransfer:(BOOL)isTransfer {
+    _isTransfer = isTransfer;
+    self.bodyView.isTransfer = isTransfer;
+}
 /*
 /*
 #pragma mark - Navigation
 #pragma mark - Navigation
 
 

+ 51 - 0
KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/TuningFunction/Tuner.swift

@@ -56,6 +56,33 @@ private let frequencies: [Float] = [
     @objc public fileprivate(set) var pitch: String = ""
     @objc public fileprivate(set) var pitch: String = ""
     
     
     /**
     /**
+     The octave of the interpreted  pre pitch.
+     */
+    @objc public fileprivate(set) var preOctave: Int = 0
+    /**
+     The interpreted pre pitch of the microphone audio.
+     */
+    @objc public fileprivate(set) var prePitch: String = ""
+    
+    /**
+     The octave of the interpreted  mid pitch.
+     */
+    @objc public fileprivate(set) var midOctave: Int = 0
+    /**
+     The interpreted mid pitch of the microphone audio.
+     */
+    @objc public fileprivate(set) var midPitch: String = ""
+    
+    /**
+     The octave of the interpreted  next pitch.
+     */
+    @objc public fileprivate(set) var nextOctave: Int = 0
+    
+    /**
+     The interpreted next pitch of the microphone audio.
+     */
+    @objc public fileprivate(set) var nextPitch: String = ""
+    /**
      The difference between the frequency of the interpreted pitch and the actual
      The difference between the frequency of the interpreted pitch and the actual
      frequency of the microphone audio.
      frequency of the microphone audio.
      
      
@@ -84,6 +111,10 @@ private let frequencies: [Float] = [
 @objc public class Tuner: NSObject {
 @objc public class Tuner: NSObject {
     
     
     fileprivate let smoothingBufferCount = 30
     fileprivate let smoothingBufferCount = 30
+    // 设置的A4标准频率
+    @objc public var A4Frequence: Int
+    // 移调
+    @objc public var toneChangeRate: Int
     
     
     fileprivate let threshold: Float
     fileprivate let threshold: Float
     fileprivate let smoothing: Float
     fileprivate let smoothing: Float
@@ -109,6 +140,8 @@ private let frequencies: [Float] = [
     @objc public init(threshold: Float = 0.0, smoothing: Float = 0.25) {
     @objc public init(threshold: Float = 0.0, smoothing: Float = 0.25) {
         self.threshold = Float(min(abs(threshold), 1.0))
         self.threshold = Float(min(abs(threshold), 1.0))
         self.smoothing = Float(min(abs(smoothing), 1.0))
         self.smoothing = Float(min(abs(smoothing), 1.0))
+        self.A4Frequence = 440
+        self.toneChangeRate = 0;
     }
     }
     
     
     /**
     /**
@@ -208,6 +241,24 @@ private let frequencies: [Float] = [
         output.distance = frequency - frequencies[i]
         output.distance = frequency - frequencies[i]
         output.pitch = String(format: "%@", sharps[i % sharps.count], flats[i % flats.count])
         output.pitch = String(format: "%@", sharps[i % sharps.count], flats[i % flats.count])
         
         
+        var index = i-1
+        if i == 0 {
+            index = 0
+        } else if i+1 == frequencies.count-1 {
+            index = frequencies.count-2
+        }
+        
+        output.preOctave = (index) / 12
+        output.prePitch = String(format: "%@", sharps[(index) % sharps.count], flats[(index) % flats.count])
+        output.midOctave = (index+1) / 12
+        output.midPitch = String(format: "%@", sharps[(index+1) % sharps.count], flats[(index+1) % flats.count])
+        output.nextOctave = (index+2) / 12
+        output.nextPitch = String(format: "%@", sharps[(index+2) % sharps.count], flats[(index+2) % flats.count])
         return output
         return output
     }
     }
+    
+//    @objc public func getTransferPitch(frequency: Float, toneChangeRate: Int)-> {
+//       
+//    }
+    
 }
 }

+ 16 - 0
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/KSGaugeView/KSGaugeColorView.h

@@ -0,0 +1,16 @@
+//
+//  KSGaugeColorView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/26.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSGaugeColorView : UIView
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 72 - 0
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/KSGaugeView/KSGaugeColorView.m

@@ -0,0 +1,72 @@
+//
+//  KSGaugeColorView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/26.
+//
+
+#import "KSGaugeColorView.h"
+
+@implementation KSGaugeColorView
+
+- (void)drawRect:(CGRect)rect {
+    CGContextRef context = UIGraphicsGetCurrentContext();
+    [self drawRoundRect:rect context:context];
+}
+
+- (void)drawRoundRect:(CGRect)rect context:(CGContextRef)context {
+    // 1. 还是添加一个圆弧路径
+    //获取图形上下文
+//    CGContextRef context = UIGraphicsGetCurrentContext();
+    //设置线的宽度
+    CGContextSetLineWidth(context, 18.0f);
+    //设置圆环线条的两个端点做圆滑处理
+    CGContextSetLineCap(context, kCGLineCapRound);
+    //设置画笔颜色
+    CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
+    //设置圆心
+    CGFloat originX = rect.size.width / 2.0f;
+    CGFloat originY = (rect.size.height - 25);
+    //计算半径
+    CGFloat radius = originY - 18 / 2.0f - 38;
+    //逆时针画一个圆弧
+    CGContextAddArc(context, originX, originY, radius, 0, -M_PI, YES);
+    
+    // 2. 创建一个渐变色
+    CGFloat locations[2];
+    NSArray *locationArray = @[@0,@0.85];
+    NSArray *colorArray = @[(id)HexRGB(0xFF41D3).CGColor,(id)HexRGB(0x4EFFC2).CGColor];
+    for (NSInteger index = 0; index < 2; index++) {
+        locations[index] = [locationArray[index] floatValue];
+    }
+    
+    //创建RGB色彩空间,创建这个以后,context里面用的颜色都是用RGB表示
+    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,(__bridge CFArrayRef _Nonnull)colorArray, locations);
+    
+    //释放色彩空间
+    CGColorSpaceRelease(colorSpace);
+    colorSpace = NULL;
+    
+    //3.画出圆环路径
+    CGContextReplacePathWithStrokedPath(context);
+//    //剪裁路径
+    CGContextClip(context);
+    CGPoint startPoint = CGPointMake(originX - radius, originY);
+    CGPoint endPoint = CGPointMake(originX + radius+18/2, originY);
+    //4.用渐变色填充,修改填充色的方向,_startPoint和_endPoint两个点的连线,就是颜色的分布方向
+    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 1);
+
+    //释放渐变色
+    CGGradientRelease(gradient);
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 51 - 0
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/KSGaugeView/KSGaugeView.h

@@ -0,0 +1,51 @@
+//
+//  KSGaugeView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/25.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSGaugeView : UIView
+// 显示指针的值
+@property (nonatomic, readwrite, assign) float value;
+// 最小值
+@property (nonatomic, readwrite, assign) float minValue;
+// 最大值
+@property (nonatomic, readwrite, assign) float maxValue;
+// 大刻度长度
+@property (nonatomic, readwrite, assign) CGFloat scaleDivisionsLength;
+// 大刻度宽度
+@property (nonatomic, readwrite, assign) CGFloat scaleDivisionsWidth;
+// 小刻度长度
+@property (nonatomic, readwrite, assign) CGFloat scaleSubdivisionsLength;
+// 小刻度宽度
+@property (nonatomic, readwrite, assign) CGFloat scaleSubdivisionsWidth;
+// 大刻度颜色
+@property (nonatomic, readwrite, strong) UIColor *scaleDivisionColor;
+// 小刻度颜色
+@property (nonatomic, readwrite, strong) UIColor *scaleSubDivisionColor;
+// 颜色
+@property (nonatomic, strong) UIColor *scaleLableColor;
+
+@property (nonatomic, readwrite, assign) CGFloat scalePosition;
+@property (nonatomic, readwrite, assign) CGFloat scaleStartAngle;
+@property (nonatomic, readwrite, assign) CGFloat scaleEndAngle;
+
+@property (nonatomic, readwrite, assign) CGFloat scaleDivisions;
+@property (nonatomic, readwrite, assign) CGFloat scaleSubdivisions;
+
+/**
+ * public functions
+ */
+- (void)setValue:(float)value animated:(BOOL)animated;
+- (void)setValue:(float)value animated:(BOOL)animated completion:(void (^)(BOOL finished))completion;
+- (void)setValue:(float)value animated:(BOOL)animated duration:(NSTimeInterval)duration;
+- (void)setValue:(float)value animated:(BOOL)animated duration:(NSTimeInterval)duration completion:(void (^)(BOOL finished))completion;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 337 - 0
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/KSGaugeView/KSGaugeView.m

@@ -0,0 +1,337 @@
+//
+//  KSGaugeView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/10/25.
+//
+
+#import "KSGaugeView.h"
+#import "KSGaugeColorView.h"
+
+/* Degrees to radians conversion macro */
+#define DEGREES_TO_RADIANS(degrees) (degrees) / 180.0 * M_PI
+
+@interface KSGaugeView ()
+{
+    /* View center */
+    CGPoint center;
+    /* Needle layer */
+    CALayer *rootNeedleLayer;
+    /* Annimation completion */
+    void (^animationCompletion)(BOOL);
+    
+    /* Scale variables */
+    CGFloat scaleRotation;
+    CGFloat divisionValue;
+    CGFloat subdivisionValue;
+    CGFloat subdivisionAngle;
+}
+
+@end
+
+@implementation KSGaugeView
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    self = [super initWithFrame:frame];
+    if (self)
+    {
+        self.backgroundColor = [UIColor clearColor];
+        [self initialize];
+    }
+    return self;
+}
+
+- (void)initialize {
+    _scaleStartAngle = 90;
+    _scaleEndAngle = 270;
+    _maxValue = 50.0;
+    _minValue = -50.0;
+    _scaleDivisions = 10;
+    _scaleSubdivisions = 5;
+    _scaleDivisionsWidth = 2;
+    _scaleDivisionsLength = 15;
+    _scaleSubdivisionsWidth = 1;
+    _scaleSubdivisionsLength = 5;
+    [self initScale];
+    [self addColorView];
+}
+
+- (void)addColorView {
+    KSGaugeColorView *colorView = [[KSGaugeColorView alloc] init];
+    colorView.backgroundColor = [UIColor clearColor];
+    [self addSubview:colorView];
+    [colorView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.bottom.left.right.mas_equalTo(self);
+    }];
+}
+
+- (void)initScale {
+    scaleRotation = (int)(_scaleStartAngle + 180) % 360;
+    divisionValue = (_maxValue - _minValue) / _scaleDivisions;
+    subdivisionValue = divisionValue / _scaleSubdivisions;
+    subdivisionAngle = (_scaleEndAngle - _scaleStartAngle) / (_scaleDivisions * _scaleSubdivisions);
+}
+
+
+- (void)drawRect:(CGRect)rect {
+    CGFloat originX = rect.size.width / 2.0f;
+    CGFloat originY = rect.size.height - 25;
+    center = CGPointMake(originX, originY);
+    CGContextRef context = UIGraphicsGetCurrentContext();
+    // 绘制lable
+    [self drawTextLabel:rect contenx:context];
+    // 绘制表盘
+    [self drawDevision:rect context:context];
+
+    // 绘制指针
+    rootNeedleLayer = [CALayer new];
+    // For performance puporse, the needle layer is not scaled to [0-1] range
+    rootNeedleLayer.frame = CGRectMake(0, 40, rect.size.width, (originY - 40) * 2);
+    [self.layer addSublayer:rootNeedleLayer];
+    [self drawNeedle:rect context:context];
+}
+
+- (void)drawNeedle:(CGRect)rect context:(CGContextRef)context {
+    
+    CGFloat originX = rect.size.width / 2.0f;
+    CGFloat originY = rect.size.height - 25;
+    center = CGPointMake(originX, originY);
+    
+    // Left Needle
+    CAShapeLayer *needleLayer = [CAShapeLayer layer];
+    UIBezierPath *needlePath = [UIBezierPath bezierPath];
+    [needlePath moveToPoint:CGPointMake(originX, originY - 40)];
+    [needlePath addLineToPoint:CGPointMake(originX-1, originY-40)];
+    [needlePath addLineToPoint:CGPointMake(originX-1, 0)];
+    [needlePath addLineToPoint:CGPointMake(originX+1, 0)];
+    [needlePath addLineToPoint:CGPointMake(originX+1, originY-40)];
+    [needlePath addLineToPoint:CGPointMake(originX, originY-40)];
+    [needlePath closePath];
+    
+    needleLayer.path = needlePath.CGPath;
+    needleLayer.backgroundColor = [[UIColor clearColor] CGColor];
+    needleLayer.fillColor = [UIColor whiteColor].CGColor;
+    [rootNeedleLayer addSublayer:needleLayer];
+}
+
+
+
+- (void)drawTextLabel:(CGRect)rect contenx:(CGContextRef)context {
+    int totalTicks = _scaleDivisions * _scaleSubdivisions + 1;
+    for (int i = 0; i < totalTicks; i++) {
+        float value = [self valueForTick:i];
+        float div = (_maxValue - _minValue) / _scaleDivisions;
+        float mod = (int)value % (int)div;
+        //
+        if ((fabsf(mod - 0) < 0.000001) || (fabsf(mod - div) < 0.000001)) {
+            
+            NSString *valueString = [NSString stringWithFormat:@"%0.0f",value];
+            UIFont* font = [UIFont fontWithName:@"DIN Alternate Bold" size:14.0f];
+            NSDictionary* stringAttrs = @{ NSFontAttributeName : font, NSForegroundColorAttributeName : HexRGB(0x999999) };
+            NSAttributedString* attrStr = [[NSAttributedString alloc] initWithString:valueString attributes:stringAttrs];
+            CGSize fontSize;
+            fontSize = [valueString sizeWithAttributes:stringAttrs];
+            CGFloat radius = rect.size.height - 30;
+            CGFloat angle = 180 - subdivisionAngle*i;
+            CGPoint drawPoint = [self calcCicleCoordinateWithCenter:center angle:angle radius:radius];
+            CGPoint lablePoint = CGPointZero;
+            if (angle > -90) {
+                lablePoint = CGPointMake(drawPoint.x - fontSize.width/2, drawPoint.y - fontSize.height/2);
+            }
+            
+            else {
+                lablePoint = CGPointMake(drawPoint.x + fontSize.width/2, drawPoint.y + fontSize.height/2);
+            }
+            [attrStr drawAtPoint:lablePoint];
+        }
+    }
+}
+
+- (CGPoint)calcCicleCoordinateWithCenter:(CGPoint)centerPoint angle:(CGFloat)angle radius:(CGFloat)radius {
+    CGFloat positionX = radius * cosf(angle*M_PI/180);
+    CGFloat positionY = radius * sinf(angle*M_PI/180);
+    return CGPointMake(centerPoint.x + positionX, centerPoint.y-positionY);
+}
+
+- (void)drawDevision:(CGRect)rect context:(CGContextRef)context {
+    
+    [self rotateContext:context fromCenter:center withAngle:DEGREES_TO_RADIANS(180 + _scaleStartAngle)];
+    int totalTicks = _scaleDivisions * _scaleSubdivisions + 1;
+    for (int i = 0; i < totalTicks; i++) {
+        CGFloat y1 = 18;
+        CGFloat y2 = y1 + _scaleSubdivisionsLength;
+        CGFloat y3 = y1 + _scaleDivisionsLength;
+        
+        float value = [self valueForTick:i];
+        float div = (_maxValue - _minValue) / _scaleDivisions;
+        float mod = (int)value % (int)div;
+        
+        // Division
+        if ((fabsf(mod - 0) < 0.000001) || (fabsf(mod - div) < 0.000001))
+        {
+            // Initialize Core Graphics settings
+            UIColor *color = HexRGB(0x2dc7aa);
+            CGContextSetStrokeColorWithColor(context, color.CGColor);
+            CGContextSetLineWidth(context, _scaleDivisionsWidth);
+            
+            // Draw tick
+            CGContextMoveToPoint(context, center.x, y1);
+            CGContextAddLineToPoint(context, center.x, y3);
+            CGContextStrokePath(context);
+            
+            // 绘制文字
+//            NSString *valueString = [NSString stringWithFormat:@"%0.0f",value];
+//            UIFont* font = [UIFont fontWithName:@"DIN Alternate Bold" size:14.0f];
+//            NSDictionary* stringAttrs = @{ NSFontAttributeName : font, NSForegroundColorAttributeName : HexRGB(0x999999) };
+//            NSAttributedString* attrStr = [[NSAttributedString alloc] initWithString:valueString attributes:stringAttrs];
+//            CGSize fontWidth;
+//            fontWidth = [valueString sizeWithAttributes:stringAttrs];
+//            [attrStr drawAtPoint:CGPointMake(center.x - fontWidth.width / 2.0, y1 - _scaleDivisionsLength - 5)];
+            
+        }
+        else {
+            // Initialize Core Graphics settings
+            UIColor *color = HexRGBAlpha(0x2dc7aa, 0.2);
+            CGContextSetStrokeColorWithColor(context, color.CGColor);
+            CGContextSetLineWidth(context, _scaleSubdivisionsWidth);
+            CGContextMoveToPoint(context, center.x, y1);
+            
+            // Draw tick
+            CGContextMoveToPoint(context, center.x, y1);
+            CGContextAddLineToPoint(context, center.x, y2);
+            CGContextStrokePath(context);
+        }
+        // Rotate to next tick
+        [self rotateContext:context fromCenter:center withAngle:DEGREES_TO_RADIANS(subdivisionAngle)];
+    }
+    
+}
+
+
+
+/**
+ * Scale tick value computation
+ */
+- (float)valueForTick:(int)tick
+{
+    return tick * (divisionValue / _scaleSubdivisions) + _minValue;
+}
+
+#pragma mark - Tools
+
+/**
+ * Core Graphics rotation in context
+ */
+- (void)rotateContext:(CGContextRef)context fromCenter:(CGPoint)center_ withAngle:(CGFloat)angle
+{
+    CGContextTranslateCTM(context, center_.x, center_.y);
+    CGContextRotateCTM(context, angle);
+    CGContextTranslateCTM(context, -center_.x, -center_.y);
+}
+
+/**
+ * Needle angle computation
+ */
+- (CGFloat)needleAngleForValue:(double)value
+{
+    return DEGREES_TO_RADIANS(_scaleStartAngle + (value - _minValue) / (_maxValue - _minValue) * (_scaleEndAngle - _scaleStartAngle)) + M_PI;
+}
+
+#pragma mark - Value update
+
+/**
+ * Update gauge value
+ */
+- (void)updateValue:(float)value
+{
+    // Clamp value if out of range
+    if (value > _maxValue)
+        value = _maxValue;
+    else if (value < _minValue)
+        value = _minValue;
+    else
+        value = value;
+    
+    // Set value
+    _value = value;
+}
+
+/**
+ * Update gauge value with animation
+ */
+- (void)setValue:(float)value animated:(BOOL)animated
+{
+    [self setValue:value animated:animated duration:0.8];
+}
+
+/**
+ * Update gauge value with animation and fire a completion block
+ */
+- (void)setValue:(float)value animated:(BOOL)animated completion:(void (^)(BOOL finished))completion
+{
+    [self setValue:value animated:animated duration:0.8 completion:completion];
+}
+
+/**
+ * Update gauge value with animation and duration
+ */
+- (void)setValue:(float)value animated:(BOOL)animated duration:(NSTimeInterval)duration
+{
+    [self setValue:value animated:animated duration:duration completion:nil];
+}
+
+/**
+ * Update gauge value with animation, duration and fire a completion block
+ */
+- (void)setValue:(float)value animated:(BOOL)animated duration:(NSTimeInterval)duration completion:(void (^)(BOOL finished))completion
+{
+    animationCompletion = completion;
+    
+    double lastValue = _value;
+    
+    [self updateValue:value];
+    double middleValue = lastValue + (((lastValue + (_value - lastValue) / 2.0) >= 0) ? (_value - lastValue) / 2.0 : (lastValue - _value) / 2.0);
+    
+    // Needle animation to target value
+    // An intermediate "middle" value is used to make sure the needle will follow the right rotation direction
+    
+    CAKeyframeAnimation * animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
+    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
+    animation.removedOnCompletion = YES;
+    animation.duration = animated ? duration : 0.0;
+    animation.delegate = (id<CAAnimationDelegate>)self;
+    animation.values = @[[NSValue valueWithCATransform3D:CATransform3DMakeRotation([self needleAngleForValue:lastValue]  , 0, 0, 1.0)],
+                         [NSValue valueWithCATransform3D:CATransform3DMakeRotation([self needleAngleForValue:middleValue], 0, 0, 1.0)],
+                         [NSValue valueWithCATransform3D:CATransform3DMakeRotation([self needleAngleForValue:_value]     , 0, 0, 1.0)]];
+    rootNeedleLayer.transform = [[animation.values lastObject] CATransform3DValue];
+    [rootNeedleLayer addAnimation:animation forKey:kCATransition];
+    
+}
+
+#pragma mark - CAAnimation delegate
+
+- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
+{
+    if (animationCompletion)
+        animationCompletion(flag);
+    
+    animationCompletion = nil;
+}
+
+
+#pragma mark - Properties
+
+- (void)setValue:(float)value
+{
+    [self setValue:value animated:YES];
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 48 - 5
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WMGaugeView/WMGaugeView.m

@@ -179,7 +179,7 @@
         rootNeedleLayer = [CALayer new];
         rootNeedleLayer = [CALayer new];
 
 
         // For performance puporse, the needle layer is not scaled to [0-1] range
         // For performance puporse, the needle layer is not scaled to [0-1] range
-        rootNeedleLayer.frame = self.bounds;
+        rootNeedleLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height*2);
         [self.layer addSublayer:rootNeedleLayer];
         [self.layer addSublayer:rootNeedleLayer];
         
         
         // Draw needle
         // Draw needle
@@ -208,6 +208,7 @@
 
 
     if (_showRangeLabels)
     if (_showRangeLabels)
         [self drawRangeLabels:context];
         [self drawRangeLabels:context];
+    
 }
 }
 
 
 /**
 /**
@@ -216,6 +217,48 @@
 - (void)drawRim:(CGContextRef)context
 - (void)drawRim:(CGContextRef)context
 {
 {
     // TODO
     // TODO
+//    // 绘制内圈渐变色圆弧
+//    CGContextSaveGState(context);
+////    CGContextRef ctx = UIGraphicsGetCurrentContext();
+//    CGContextSetLineWidth(context, 18.0f);
+//    //设置圆环线条的两个端点做圆滑处理
+//    CGContextSetLineCap(context, kCGLineCapRound);
+//    //设置画笔颜色
+//    CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
+//    //设置圆心
+//    CGFloat originX = self.bounds.size.width / 2;
+//    CGFloat originY = self.bounds.size.height / 2;
+//    //计算半径
+//    CGFloat radius = MIN(originX, originY) - 18/2.0 - 10;
+//
+//    CGContextAddArc(context, originX, originY, radius, -M_PI_2 - 5, M_PI_2 + 5, NO);
+//
+//    //2. 创建一个渐变色
+//    CGFloat locations[2];
+//    NSArray *locationArray = @[@0,@0.5];
+//    NSArray *colorArray = @[(id)HexRGB(0xFF41D3).CGColor,(id)HexRGB(0x4EFFC2).CGColor];
+//    for (NSInteger index = 0; index < 2; index++) {
+//        locations[index] = [locationArray[index] floatValue];
+//    }
+//
+//    //创建RGB色彩空间,创建这个以后,context里面用的颜色都是用RGB表示
+//    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+//    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,(__bridge CFArrayRef _Nonnull)colorArray, locations);
+//
+//    //释放色彩空间
+//    CGColorSpaceRelease(colorSpace);
+//    colorSpace = NULL;
+//
+//    //3.画出圆环路径
+//    CGContextReplacePathWithStrokedPath(context);
+//    //剪裁路径
+//    CGContextClip(context);
+//
+//    //4.用渐变色填充,修改填充色的方向,_startPoint和_endPoint两个点的连线,就是颜色的分布方向
+//    CGContextDrawLinearGradient(context, gradient, CGPointMake(10, self.bounds.size.height / 2), CGPointMake(self.bounds.size.width - 28, self.bounds.size.height / 2), 1);
+//
+//    //释放渐变色
+//    CGGradientRelease(gradient);
 }
 }
 
 
 /**
 /**
@@ -259,9 +302,9 @@
         if (_scalesubdivisionsAligment == WMGaugeViewSubdivisionsAlignmentCenter) offset = (_scaleDivisionsLength - _scaleSubdivisionsLength) / 2.0;
         if (_scalesubdivisionsAligment == WMGaugeViewSubdivisionsAlignmentCenter) offset = (_scaleDivisionsLength - _scaleSubdivisionsLength) / 2.0;
         if (_scalesubdivisionsAligment == WMGaugeViewSubdivisionsAlignmentBottom) offset = _scaleDivisionsLength - _scaleSubdivisionsLength;
         if (_scalesubdivisionsAligment == WMGaugeViewSubdivisionsAlignmentBottom) offset = _scaleDivisionsLength - _scaleSubdivisionsLength;
         
         
-        CGFloat y1 = scaleRect.origin.y;
+        CGFloat y1 = scaleRect.origin.y + 0.1;
         CGFloat y2 = y1 + _scaleSubdivisionsLength;
         CGFloat y2 = y1 + _scaleSubdivisionsLength;
-        CGFloat y3 = y1 + _scaleDivisionsLength;
+        CGFloat y3 = y1 - _scaleDivisionsLength;
         
         
         float value = [self valueForTick:i];
         float value = [self valueForTick:i];
         float div = (_maxValue - _minValue) / _scaleDivisions;
         float div = (_maxValue - _minValue) / _scaleDivisions;
@@ -285,12 +328,12 @@
             if(_showScaleValues) {
             if(_showScaleValues) {
                 NSString *valueString = [NSString stringWithFormat:@"%0.0f",value];
                 NSString *valueString = [NSString stringWithFormat:@"%0.0f",value];
                 UIFont* font = _scaleFont ? _scaleFont : [UIFont fontWithName:@"Helvetica-Bold" size:0.05];
                 UIFont* font = _scaleFont ? _scaleFont : [UIFont fontWithName:@"Helvetica-Bold" size:0.05];
-                NSDictionary* stringAttrs = @{ NSFontAttributeName : font, NSForegroundColorAttributeName : color };
+                NSDictionary* stringAttrs = @{ NSFontAttributeName : font, NSForegroundColorAttributeName : HexRGB(0x999999) };
                 NSAttributedString* attrStr = [[NSAttributedString alloc] initWithString:valueString attributes:stringAttrs];
                 NSAttributedString* attrStr = [[NSAttributedString alloc] initWithString:valueString attributes:stringAttrs];
                 CGSize fontWidth;
                 CGSize fontWidth;
                 fontWidth = [valueString sizeWithAttributes:stringAttrs];
                 fontWidth = [valueString sizeWithAttributes:stringAttrs];
                 
                 
-                [attrStr drawAtPoint:CGPointMake(0.5 - fontWidth.width / 2.0, y3 + 0.005)];
+                [attrStr drawAtPoint:CGPointMake(0.5 - fontWidth.width / 2.0, y3 - 0.065)];
             }
             }
         }
         }
         // Subdivision
         // Subdivision

+ 10 - 10
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WMGaugeView/WMGaugeViewStyle3D.m

@@ -39,9 +39,9 @@
     // Left Needle
     // Left Needle
     CAShapeLayer *leftNeedleLayer = [CAShapeLayer layer];
     CAShapeLayer *leftNeedleLayer = [CAShapeLayer layer];
     UIBezierPath *leftNeedlePath = [UIBezierPath bezierPath];
     UIBezierPath *leftNeedlePath = [UIBezierPath bezierPath];
-    [leftNeedlePath moveToPoint:CGPointMake(FULLSCALE(kCenterX, kCenterY))];
-    [leftNeedlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX - _needleWidth, kCenterY))];
-    [leftNeedlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX, kCenterY - _needleHeight))];
+    [leftNeedlePath moveToPoint:CGPointMake(FULLSCALE(kCenterX, 1))];
+    [leftNeedlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX - _needleWidth, 1))];
+    [leftNeedlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX, 1 - _needleHeight))];
     [leftNeedlePath closePath];
     [leftNeedlePath closePath];
     
     
     leftNeedleLayer.path = leftNeedlePath.CGPath;
     leftNeedleLayer.path = leftNeedlePath.CGPath;
@@ -53,9 +53,9 @@
     // Right Needle
     // Right Needle
     CAShapeLayer *rightNeedleLayer = [CAShapeLayer layer];
     CAShapeLayer *rightNeedleLayer = [CAShapeLayer layer];
     UIBezierPath *rightNeedlePath = [UIBezierPath bezierPath];
     UIBezierPath *rightNeedlePath = [UIBezierPath bezierPath];
-    [rightNeedlePath moveToPoint:CGPointMake(FULLSCALE(kCenterX, kCenterY))];
-    [rightNeedlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX + _needleWidth, kCenterY))];
-    [rightNeedlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX, kCenterY - _needleHeight))];
+    [rightNeedlePath moveToPoint:CGPointMake(FULLSCALE(kCenterX, 1))];
+    [rightNeedlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX + _needleWidth, 1))];
+    [rightNeedlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX, 1 - _needleHeight))];
     [rightNeedlePath closePath];
     [rightNeedlePath closePath];
     
     
     rightNeedleLayer.path = rightNeedlePath.CGPath;
     rightNeedleLayer.path = rightNeedlePath.CGPath;
@@ -72,8 +72,8 @@
     
     
     // Screw drawing
     // Screw drawing
     CAShapeLayer *screwLayer = [CAShapeLayer layer];
     CAShapeLayer *screwLayer = [CAShapeLayer layer];
-    screwLayer.bounds = CGRectMake(FULLSCALE(kCenterX - _needleScrewRadius, kCenterY - _needleScrewRadius), FULLSCALE(_needleScrewRadius * 2.0, _needleScrewRadius * 2.0));
-    screwLayer.position = CGPointMake(FULLSCALE(kCenterX, kCenterY));
+    screwLayer.bounds = CGRectMake(FULLSCALE(kCenterX - _needleScrewRadius, 1 - _needleScrewRadius), FULLSCALE(_needleScrewRadius * 2.0, _needleScrewRadius * 2.0));
+    screwLayer.position = CGPointMake(FULLSCALE(kCenterX, 1));
     screwLayer.path = [UIBezierPath bezierPathWithOvalInRect:screwLayer.bounds].CGPath;
     screwLayer.path = [UIBezierPath bezierPathWithOvalInRect:screwLayer.bounds].CGPath;
     screwLayer.fillColor = _screwFillColor.CGColor;
     screwLayer.fillColor = _screwFillColor.CGColor;
     screwLayer.strokeColor = _screwStrokeColor.CGColor;
     screwLayer.strokeColor = _screwStrokeColor.CGColor;
@@ -99,7 +99,7 @@
     baseSpace = NULL;
     baseSpace = NULL;
     CGContextAddEllipseInRect(context, rect);
     CGContextAddEllipseInRect(context, rect);
     CGContextClip(context);
     CGContextClip(context);
-    CGContextDrawRadialGradient(context, gradient, kCenterPoint, 0, kCenterPoint, rect.size.width / 2.0, kCGGradientDrawsAfterEndLocation);
+    CGContextDrawRadialGradient(context, gradient, CGPointMake(kCenterX, 1), 0, CGPointMake(kCenterX, 1), rect.size.width / 2.0, kCGGradientDrawsAfterEndLocation);
     CGGradientRelease(gradient);
     CGGradientRelease(gradient);
     gradient = NULL;
     gradient = NULL;
     free(positions); positions = NULL;
     free(positions); positions = NULL;
@@ -112,7 +112,7 @@
     CGColorSpaceRelease(baseSpace); baseSpace = NULL;
     CGColorSpaceRelease(baseSpace); baseSpace = NULL;
     CGContextAddEllipseInRect(context, rect);
     CGContextAddEllipseInRect(context, rect);
     CGContextClip(context);
     CGContextClip(context);
-    CGContextDrawRadialGradient(context, gradient, kCenterPoint, 0, kCenterPoint, rect.size.width / 2.0, kCGGradientDrawsAfterEndLocation);
+    CGContextDrawRadialGradient(context, gradient, CGPointMake(kCenterX, 1), 0, CGPointMake(kCenterX, 1), rect.size.width / 2.0, kCGGradientDrawsAfterEndLocation);
     CGGradientRelease(gradient); gradient = NULL;
     CGGradientRelease(gradient); gradient = NULL;
     free(positions); positions = NULL;
     free(positions); positions = NULL;
     
     

+ 3 - 1
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WMGaugeView/WMGaugeViewStyleFlatThin.h

@@ -9,9 +9,11 @@
 #import "WMGaugeViewStyle.h"
 #import "WMGaugeViewStyle.h"
 
 
 @interface WMGaugeViewStyleFlatThin : NSObject<WMGaugeViewStyle>
 @interface WMGaugeViewStyleFlatThin : NSObject<WMGaugeViewStyle>
-
+// 指针 线宽
 @property (nonatomic) CGFloat needleWidth;
 @property (nonatomic) CGFloat needleWidth;
+// 指针 线高
 @property (nonatomic) CGFloat needleHeight;
 @property (nonatomic) CGFloat needleHeight;
+// 顶部表盘大小
 @property (nonatomic) CGFloat needleScrewRadius;
 @property (nonatomic) CGFloat needleScrewRadius;
 
 
 @property (nonatomic) UIColor* needleColor;
 @property (nonatomic) UIColor* needleColor;

+ 20 - 15
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WMGaugeView/WMGaugeViewStyleFlatThin.m

@@ -19,21 +19,25 @@
 - (instancetype)init
 - (instancetype)init
 {
 {
     if (self = [super init]) {
     if (self = [super init]) {
-        _needleWidth = 0.012;
-        _needleHeight = 0.4;
-        _needleScrewRadius = 0.05;
+        _needleWidth = 0.002;
+        _needleHeight = 0.8;
+        _needleScrewRadius = 0.12;
 //        _needleColor = RGB(255, 104, 97);//橘红色
 //        _needleColor = RGB(255, 104, 97);//橘红色
-        _needleColor = [[UIColor redColor] colorWithAlphaComponent:0.2];
+//        _needleColor = [[UIColor redColor] colorWithAlphaComponent:0.2];
+        _needleColor = [UIColor whiteColor];
 //        _needleScrewColor = RGB(68, 84, 105);//蓝紫灰色
 //        _needleScrewColor = RGB(68, 84, 105);//蓝紫灰色
-        _needleScrewColor = [UIColor systemTealColor];
+//        _needleScrewColor = [UIColor systemTealColor];
+        _needleScrewColor = HexRGB(0x1A1C21);
         
         
         _externalRingRadius = 0.24;
         _externalRingRadius = 0.24;
 //        _externalFaceColor = RGB(255, 104, 97);
 //        _externalFaceColor = RGB(255, 104, 97);
-        _externalFaceColor = [[UIColor redColor] colorWithAlphaComponent:0.2];
-
+//        _externalFaceColor = [[[UIColor redColor] colorWithAlphaComponent:0.2]];
+        _externalFaceColor = [UIColor clearColor];
+        
         _internalRingRadius = 0.1;
         _internalRingRadius = 0.1;
 //        _internalFaceColor = RGB(242, 99, 92);//亮橘红色
 //        _internalFaceColor = RGB(242, 99, 92);//亮橘红色
         _internalFaceColor = [[UIColor yellowColor] colorWithAlphaComponent:0.2];
         _internalFaceColor = [[UIColor yellowColor] colorWithAlphaComponent:0.2];
+        _internalFaceColor = [UIColor clearColor];
         
         
 //        _borderColor = RGBA(81, 84, 89, 160);//火山灰色
 //        _borderColor = RGBA(81, 84, 89, 160);//火山灰色
         _borderColor = [UIColor blackColor];
         _borderColor = [UIColor blackColor];
@@ -46,16 +50,17 @@
 {
 {
     _needleLayer = [CAShapeLayer layer];
     _needleLayer = [CAShapeLayer layer];
     UIBezierPath *needlePath = [UIBezierPath bezierPath];
     UIBezierPath *needlePath = [UIBezierPath bezierPath];
-    [needlePath moveToPoint:CGPointMake(FULLSCALE(kCenterX - _needleWidth, kCenterY))];
-    [needlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX + _needleWidth, kCenterY))];
-    [needlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX, kCenterY - _needleHeight))];
+    [needlePath moveToPoint:CGPointMake(FULLSCALE(kCenterX - _needleWidth, 1))];
+    [needlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX + _needleWidth, 1))];
+    [needlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX + _needleWidth, 1 - _needleHeight))];
+    [needlePath addLineToPoint:CGPointMake(FULLSCALE(kCenterX - _needleWidth, 1 - _needleHeight))];
     [needlePath closePath];
     [needlePath closePath];
     
     
     _needleLayer.path = needlePath.CGPath;
     _needleLayer.path = needlePath.CGPath;
     _needleLayer.backgroundColor = [[UIColor clearColor] CGColor];
     _needleLayer.backgroundColor = [[UIColor clearColor] CGColor];
     _needleLayer.fillColor = _needleColor.CGColor;
     _needleLayer.fillColor = _needleColor.CGColor;
     _needleLayer.strokeColor = _needleColor.CGColor;
     _needleLayer.strokeColor = _needleColor.CGColor;
-    _needleLayer.lineWidth = 1.2;
+    _needleLayer.lineWidth = 2;
     
     
     // Needle shadow
     // Needle shadow
     _needleLayer.shadowColor = [[UIColor blackColor] CGColor];
     _needleLayer.shadowColor = [[UIColor blackColor] CGColor];
@@ -67,8 +72,8 @@
     
     
     // Screw drawing
     // Screw drawing
     CAShapeLayer *screwLayer = [CAShapeLayer layer];
     CAShapeLayer *screwLayer = [CAShapeLayer layer];
-    screwLayer.bounds = CGRectMake(FULLSCALE(kCenterX - _needleScrewRadius, kCenterY - _needleScrewRadius), FULLSCALE(_needleScrewRadius * 2.0, _needleScrewRadius * 2.0));
-    screwLayer.position = CGPointMake(FULLSCALE(kCenterX, kCenterY));
+    screwLayer.bounds = CGRectMake(FULLSCALE(kCenterX - _needleScrewRadius, 1 - _needleScrewRadius), FULLSCALE(_needleScrewRadius * 2.0, _needleScrewRadius * 2.0));
+    screwLayer.position = CGPointMake(FULLSCALE(kCenterX, 1));
     screwLayer.path = [UIBezierPath bezierPathWithOvalInRect:screwLayer.bounds].CGPath;
     screwLayer.path = [UIBezierPath bezierPathWithOvalInRect:screwLayer.bounds].CGPath;
     screwLayer.fillColor = _needleScrewColor.CGColor;
     screwLayer.fillColor = _needleScrewColor.CGColor;
     
     
@@ -84,12 +89,12 @@
 - (void)drawFaceWithContext:(CGContextRef)context inRect:(CGRect)rect
 - (void)drawFaceWithContext:(CGContextRef)context inRect:(CGRect)rect
 {
 {
     // External circle
     // External circle
-    CGRect externalRect = CGRectMake(kCenterX - _externalRingRadius, kCenterY - _externalRingRadius, _externalRingRadius * 2.0, _externalRingRadius * 2.0);
+    CGRect externalRect = CGRectMake(kCenterX - _externalRingRadius, 1 - _externalRingRadius, _externalRingRadius * 2.0, _externalRingRadius * 2.0);
     CGContextSetFillColorWithColor(context, _externalFaceColor.CGColor);
     CGContextSetFillColorWithColor(context, _externalFaceColor.CGColor);
     CGContextFillEllipseInRect(context, externalRect);
     CGContextFillEllipseInRect(context, externalRect);
 
 
     // Inner circle
     // Inner circle
-    CGRect internalRect = CGRectMake(kCenterX - _internalRingRadius, kCenterY - _internalRingRadius, _internalRingRadius * 2.0, _internalRingRadius * 2.0);
+    CGRect internalRect = CGRectMake(kCenterX - _internalRingRadius, 1 - _internalRingRadius, _internalRingRadius * 2.0, _internalRingRadius * 2.0);
     CGContextSetFillColorWithColor(context, _internalFaceColor.CGColor);
     CGContextSetFillColorWithColor(context, _internalFaceColor.CGColor);
     CGContextFillEllipseInRect(context, internalRect);
     CGContextFillEllipseInRect(context, internalRect);
     
     

+ 2 - 2
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/DialPlateView.h

@@ -6,13 +6,13 @@
 //
 //
 
 
 #import <UIKit/UIKit.h>
 #import <UIKit/UIKit.h>
-#import "WMGaugeView.h"
+#import "KSGaugeView.h"
 NS_ASSUME_NONNULL_BEGIN
 NS_ASSUME_NONNULL_BEGIN
 
 
 /// 表盘View
 /// 表盘View
 @interface DialPlateView : UIView
 @interface DialPlateView : UIView
 
 
-@property (nonatomic, strong) WMGaugeView *gaugeView;
+@property (nonatomic, strong) KSGaugeView *gaugeView;
 
 
 @end
 @end
 
 

+ 2 - 16
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/DialPlateView.m

@@ -32,23 +32,9 @@
     
     
 }
 }
 
 
-- (WMGaugeView *)gaugeView {
+- (KSGaugeView *)gaugeView {
     if (!_gaugeView) {
     if (!_gaugeView) {
-        _gaugeView = [[WMGaugeView alloc] init];
-        _gaugeView.style = [[WMGaugeViewStyleFlatThin alloc] init];
-        _gaugeView.maxValue = 50.0f;
-        _gaugeView.minValue = -50.0f;
-        _gaugeView.scaleDivisions = 10;
-        _gaugeView.scaleEndAngle = 270;
-        _gaugeView.scaleStartAngle = 90;
-        _gaugeView.scaleSubdivisions = 5;
-        _gaugeView.showScaleShadow = NO;
-        _gaugeView.scaleDivisionsLength = 0.05;
-        _gaugeView.scaleDivisionsWidth = 0.007;
-        _gaugeView.scaleSubdivisionsLength = 0.02;
-        _gaugeView.scaleSubdivisionsWidth = 0.002;
-        _gaugeView.backgroundColor = [UIColor clearColor];
-        _gaugeView.scaleFont = [UIFont systemFontOfSize:0.05 weight:UIFontWeightUltraLight];
+        _gaugeView = [[KSGaugeView alloc] init];
     }
     }
     return _gaugeView;
     return _gaugeView;
 }
 }

+ 12 - 1
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/ToneTuningBodyView.h

@@ -11,7 +11,6 @@
 #define MINFREQUENCE (415)
 #define MINFREQUENCE (415)
 
 
 typedef NS_ENUM(NSInteger, TUNINGACTION) {
 typedef NS_ENUM(NSInteger, TUNINGACTION) {
-    TUNINGACTION_SETTING,     // 设置
     TUNINGACTION_FREQUENCE,   // 调节频率
     TUNINGACTION_FREQUENCE,   // 调节频率
     TUNINGACTION_FORKSETTING, // 音叉设置
     TUNINGACTION_FORKSETTING, // 音叉设置
     TUNINGACTION_PLAY,        // 播放音叉
     TUNINGACTION_PLAY,        // 播放音叉
@@ -42,10 +41,22 @@ NS_ASSUME_NONNULL_BEGIN
 
 
 @property (weak, nonatomic) IBOutlet UILabel *pitchFrequenceLabel;
 @property (weak, nonatomic) IBOutlet UILabel *pitchFrequenceLabel;
 
 
+@property (weak, nonatomic) IBOutlet UILabel *preFrequence;
+
+@property (weak, nonatomic) IBOutlet UILabel *nextFrequence;
+
 @property (nonatomic, assign) NSInteger A4Frequence;
 @property (nonatomic, assign) NSInteger A4Frequence;
 
 
 @property (nonatomic, assign) BOOL isPlaying;
 @property (nonatomic, assign) BOOL isPlaying;
 
 
+// 是否移调
+@property (nonatomic, assign) BOOL isTransfer;
+// 移调调号
+@property (nonatomic, strong) NSString *transferPitchDesc;
+
+// 偏移
+@property (nonatomic, assign) NSInteger distance;
+
 + (instancetype)shareInstance;
 + (instancetype)shareInstance;
 
 
 - (void)tuningViewAction:(TuningActionCallback)callback;
 - (void)tuningViewAction:(TuningActionCallback)callback;

+ 17 - 0
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/ToneTuningBodyView.m

@@ -18,6 +18,7 @@
 @property (weak, nonatomic) IBOutlet UIButton *addButton;
 @property (weak, nonatomic) IBOutlet UIButton *addButton;
 
 
 @property (weak, nonatomic) IBOutlet UIButton *playButton;
 @property (weak, nonatomic) IBOutlet UIButton *playButton;
+@property (weak, nonatomic) IBOutlet UILabel *distanceLabel;
 
 
 @property (nonatomic, copy) TuningActionCallback callback;
 @property (nonatomic, copy) TuningActionCallback callback;
 
 
@@ -116,6 +117,22 @@
     [self.playButton setImage:[UIImage imageNamed:playImage] forState:UIControlStateNormal];
     [self.playButton setImage:[UIImage imageNamed:playImage] forState:UIControlStateNormal];
 }
 }
 
 
+- (void)setIsTransfer:(BOOL)isTransfer {
+    _isTransfer = isTransfer;
+    if (isTransfer) {
+        self.nomalPitch.hidden = YES;
+        self.transferView.hidden = NO;
+    }
+    else {
+        self.nomalPitch.hidden = NO;
+        self.transferView.hidden = YES;
+    }
+}
+
+- (void)setDistance:(NSInteger)distance {
+    _distance = distance;
+    self.distanceLabel.text = [NSString stringWithFormat:@"%zd¢", distance];
+}
 /*
 /*
 // Only override drawRect: if you perform custom drawing.
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 // An empty implementation adversely affects performance during animation.

+ 56 - 17
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/ToneTuningBodyView.xib

@@ -30,20 +30,42 @@
                         <constraint firstAttribute="height" constant="12" id="gve-gP-2q7"/>
                         <constraint firstAttribute="height" constant="12" id="gve-gP-2q7"/>
                     </constraints>
                     </constraints>
                 </imageView>
                 </imageView>
-                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="plate_bg" translatesAutoresizingMaskIntoConstraints="NO" id="SXB-cz-Qdh">
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="plate_bg" translatesAutoresizingMaskIntoConstraints="NO" id="SXB-cz-Qdh">
                     <rect key="frame" x="8" y="42" width="374" height="254"/>
                     <rect key="frame" x="8" y="42" width="374" height="254"/>
                     <constraints>
                     <constraints>
                         <constraint firstAttribute="width" secondItem="SXB-cz-Qdh" secondAttribute="height" multiplier="187:127" id="ixC-MD-R46"/>
                         <constraint firstAttribute="width" secondItem="SXB-cz-Qdh" secondAttribute="height" multiplier="187:127" id="ixC-MD-R46"/>
                     </constraints>
                     </constraints>
                 </imageView>
                 </imageView>
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zrx-Pe-2NT">
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Zrx-Pe-2NT">
-                    <rect key="frame" x="43.666666666666657" y="88" width="303" height="303"/>
+                    <rect key="frame" x="25" y="84" width="340" height="170"/>
                     <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <constraints>
                     <constraints>
-                        <constraint firstAttribute="width" constant="303" id="93S-gk-24h"/>
-                        <constraint firstAttribute="height" constant="303" id="rD4-eg-11F"/>
+                        <constraint firstAttribute="width" secondItem="Zrx-Pe-2NT" secondAttribute="height" multiplier="2:1" id="J6J-6P-lDY"/>
                     </constraints>
                     </constraints>
                 </view>
                 </view>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9aU-LL-Lsq">
+                    <rect key="frame" x="160" y="204" width="70" height="70"/>
+                    <subviews>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0¢" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="D7p-nE-fr1">
+                            <rect key="frame" x="15.666666666666657" y="19.666666666666657" width="39" height="31"/>
+                            <fontDescription key="fontDescription" name="DINAlternate-Bold" family="DIN Alternate" pointSize="26"/>
+                            <color key="textColor" red="0.0" green="1" blue="0.81176470588235294" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                    </subviews>
+                    <color key="backgroundColor" red="0.062745098039215685" green="0.074509803921568626" blue="0.094117647058823528" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="70" id="EVn-sM-7ft"/>
+                        <constraint firstItem="D7p-nE-fr1" firstAttribute="centerY" secondItem="9aU-LL-Lsq" secondAttribute="centerY" id="YyQ-A4-OY3"/>
+                        <constraint firstAttribute="width" constant="70" id="gV3-KZ-iAV"/>
+                        <constraint firstItem="D7p-nE-fr1" firstAttribute="centerX" secondItem="9aU-LL-Lsq" secondAttribute="centerX" id="rVT-76-xxU"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="35"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="g4h-vE-BMO">
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="g4h-vE-BMO">
                     <rect key="frame" x="107" y="322.66666666666669" width="50" height="31"/>
                     <rect key="frame" x="107" y="322.66666666666669" width="50" height="31"/>
                     <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -267,18 +289,22 @@
                         <constraint firstAttribute="height" constant="29" id="tsc-a8-bbh"/>
                         <constraint firstAttribute="height" constant="29" id="tsc-a8-bbh"/>
                     </constraints>
                     </constraints>
                 </imageView>
                 </imageView>
-                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5sT-Eb-2rJ">
-                    <rect key="frame" x="56" y="264" width="42" height="21"/>
-                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
-                    <nil key="textColor"/>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5sT-Eb-2rJ">
+                    <rect key="frame" x="75" y="254" width="0.0" height="14"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="14" id="g2f-fr-DrN"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" name="DINAlternate-Bold" family="DIN Alternate" pointSize="12"/>
+                    <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
                     <nil key="highlightedColor"/>
                     <nil key="highlightedColor"/>
                 </label>
                 </label>
-                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ke2-CX-K7G">
-                    <rect key="frame" x="293" y="264" width="42" height="21"/>
-                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
-                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
-                    <nil key="textColor"/>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ke2-CX-K7G">
+                    <rect key="frame" x="315" y="254" width="0.0" height="14"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="14" id="Csw-Dx-b3r"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" name="DINAlternate-Bold" family="DIN Alternate" pointSize="12"/>
+                    <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
                     <nil key="highlightedColor"/>
                     <nil key="highlightedColor"/>
                 </label>
                 </label>
                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="tuning_decorate" translatesAutoresizingMaskIntoConstraints="NO" id="v4Z-dA-iqI">
                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="tuning_decorate" translatesAutoresizingMaskIntoConstraints="NO" id="v4Z-dA-iqI">
@@ -296,7 +322,10 @@
                     </constraints>
                     </constraints>
                 </imageView>
                 </imageView>
                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PnS-Ku-vsa">
                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PnS-Ku-vsa">
-                    <rect key="frame" x="195" y="76" width="0.0" height="0.0"/>
+                    <rect key="frame" x="195" y="46" width="0.0" height="20"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="20" id="2X9-wE-8CN"/>
+                    </constraints>
                     <fontDescription key="fontDescription" type="system" pointSize="14"/>
                     <fontDescription key="fontDescription" type="system" pointSize="14"/>
                     <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <nil key="highlightedColor"/>
                     <nil key="highlightedColor"/>
@@ -305,32 +334,36 @@
             <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
             <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
             <constraints>
             <constraints>
                 <constraint firstItem="sZj-ZO-VHR" firstAttribute="leading" secondItem="Cai-ev-v5E" secondAttribute="trailing" constant="17" id="0D9-VV-0Lx"/>
                 <constraint firstItem="sZj-ZO-VHR" firstAttribute="leading" secondItem="Cai-ev-v5E" secondAttribute="trailing" constant="17" id="0D9-VV-0Lx"/>
+                <constraint firstItem="9aU-LL-Lsq" firstAttribute="bottom" secondItem="Zrx-Pe-2NT" secondAttribute="bottom" constant="20" id="0pz-qw-7TT"/>
                 <constraint firstItem="7Em-FC-3EL" firstAttribute="leading" secondItem="ZeX-qM-LJD" secondAttribute="leading" id="1nv-ne-dbI"/>
                 <constraint firstItem="7Em-FC-3EL" firstAttribute="leading" secondItem="ZeX-qM-LJD" secondAttribute="leading" id="1nv-ne-dbI"/>
                 <constraint firstItem="g4h-vE-BMO" firstAttribute="bottom" secondItem="Cai-ev-v5E" secondAttribute="bottom" id="3KO-qD-HZ2"/>
                 <constraint firstItem="g4h-vE-BMO" firstAttribute="bottom" secondItem="Cai-ev-v5E" secondAttribute="bottom" id="3KO-qD-HZ2"/>
                 <constraint firstItem="p0z-qL-bMm" firstAttribute="top" secondItem="7Em-FC-3EL" secondAttribute="bottom" constant="12" id="4SR-6A-ipm"/>
                 <constraint firstItem="p0z-qL-bMm" firstAttribute="top" secondItem="7Em-FC-3EL" secondAttribute="bottom" constant="12" id="4SR-6A-ipm"/>
                 <constraint firstItem="p0z-qL-bMm" firstAttribute="leading" secondItem="Tkl-Cw-Mdz" secondAttribute="trailing" id="5EB-Vw-dj2"/>
                 <constraint firstItem="p0z-qL-bMm" firstAttribute="leading" secondItem="Tkl-Cw-Mdz" secondAttribute="trailing" id="5EB-Vw-dj2"/>
                 <constraint firstItem="Cai-ev-v5E" firstAttribute="leading" secondItem="v4Z-dA-iqI" secondAttribute="trailing" constant="22" id="6b8-ki-CY9"/>
                 <constraint firstItem="Cai-ev-v5E" firstAttribute="leading" secondItem="v4Z-dA-iqI" secondAttribute="trailing" constant="22" id="6b8-ki-CY9"/>
+                <constraint firstItem="Ke2-CX-K7G" firstAttribute="trailing" secondItem="Zrx-Pe-2NT" secondAttribute="trailing" constant="-50" id="6hN-re-nBS"/>
                 <constraint firstItem="7Em-FC-3EL" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="7ZV-OX-B1b"/>
                 <constraint firstItem="7Em-FC-3EL" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="7ZV-OX-B1b"/>
                 <constraint firstItem="Cai-ev-v5E" firstAttribute="centerY" secondItem="v4Z-dA-iqI" secondAttribute="centerY" id="8Eb-SN-txF"/>
                 <constraint firstItem="Cai-ev-v5E" firstAttribute="centerY" secondItem="v4Z-dA-iqI" secondAttribute="centerY" id="8Eb-SN-txF"/>
                 <constraint firstItem="IXi-hL-in1" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Au1-eF-R25"/>
                 <constraint firstItem="IXi-hL-in1" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Au1-eF-R25"/>
                 <constraint firstItem="VJU-LE-Pdq" firstAttribute="leading" secondItem="sZj-ZO-VHR" secondAttribute="trailing" constant="17" id="C3a-5i-dtf"/>
                 <constraint firstItem="VJU-LE-Pdq" firstAttribute="leading" secondItem="sZj-ZO-VHR" secondAttribute="trailing" constant="17" id="C3a-5i-dtf"/>
+                <constraint firstItem="Zrx-Pe-2NT" firstAttribute="top" secondItem="PnS-Ku-vsa" secondAttribute="bottom" constant="18" id="CQp-De-b4B"/>
                 <constraint firstItem="p0z-qL-bMm" firstAttribute="width" secondItem="Tkl-Cw-Mdz" secondAttribute="width" id="Dk9-Wv-4mD"/>
                 <constraint firstItem="p0z-qL-bMm" firstAttribute="width" secondItem="Tkl-Cw-Mdz" secondAttribute="width" id="Dk9-Wv-4mD"/>
                 <constraint firstItem="PnS-Ku-vsa" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="FLp-jq-kpX"/>
                 <constraint firstItem="PnS-Ku-vsa" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="FLp-jq-kpX"/>
                 <constraint firstItem="SXB-cz-Qdh" firstAttribute="top" secondItem="Ux8-2g-RqK" secondAttribute="bottom" constant="10" id="FYQ-Rq-QtT"/>
                 <constraint firstItem="SXB-cz-Qdh" firstAttribute="top" secondItem="Ux8-2g-RqK" secondAttribute="bottom" constant="10" id="FYQ-Rq-QtT"/>
+                <constraint firstItem="Zrx-Pe-2NT" firstAttribute="centerY" secondItem="SXB-cz-Qdh" secondAttribute="centerY" id="Fj7-fu-frt"/>
                 <constraint firstItem="7Em-FC-3EL" firstAttribute="top" secondItem="ZeX-qM-LJD" secondAttribute="top" id="FlV-cS-OgW"/>
                 <constraint firstItem="7Em-FC-3EL" firstAttribute="top" secondItem="ZeX-qM-LJD" secondAttribute="top" id="FlV-cS-OgW"/>
                 <constraint firstItem="g4h-vE-BMO" firstAttribute="trailing" secondItem="Cai-ev-v5E" secondAttribute="trailing" id="N2Y-VV-UPi"/>
                 <constraint firstItem="g4h-vE-BMO" firstAttribute="trailing" secondItem="Cai-ev-v5E" secondAttribute="trailing" id="N2Y-VV-UPi"/>
                 <constraint firstItem="SXB-cz-Qdh" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="8" id="O3Y-u0-MV3"/>
                 <constraint firstItem="SXB-cz-Qdh" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="8" id="O3Y-u0-MV3"/>
                 <constraint firstItem="sZj-ZO-VHR" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="PEf-sX-DzU"/>
                 <constraint firstItem="sZj-ZO-VHR" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="PEf-sX-DzU"/>
                 <constraint firstItem="Tkl-Cw-Mdz" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="6" id="Q9g-JT-4o6"/>
                 <constraint firstItem="Tkl-Cw-Mdz" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="6" id="Q9g-JT-4o6"/>
+                <constraint firstItem="9aU-LL-Lsq" firstAttribute="centerX" secondItem="Zrx-Pe-2NT" secondAttribute="centerX" id="RYl-V1-dyU"/>
                 <constraint firstItem="VJU-LE-Pdq" firstAttribute="top" secondItem="uwR-ra-cDH" secondAttribute="top" id="RZq-Hd-B0P"/>
                 <constraint firstItem="VJU-LE-Pdq" firstAttribute="top" secondItem="uwR-ra-cDH" secondAttribute="top" id="RZq-Hd-B0P"/>
                 <constraint firstAttribute="trailing" secondItem="p0z-qL-bMm" secondAttribute="trailing" constant="6" id="RoG-8u-1ap"/>
                 <constraint firstAttribute="trailing" secondItem="p0z-qL-bMm" secondAttribute="trailing" constant="6" id="RoG-8u-1ap"/>
                 <constraint firstItem="V2v-I8-jzm" firstAttribute="centerY" secondItem="VJU-LE-Pdq" secondAttribute="centerY" id="T1g-e0-zDn"/>
                 <constraint firstItem="V2v-I8-jzm" firstAttribute="centerY" secondItem="VJU-LE-Pdq" secondAttribute="centerY" id="T1g-e0-zDn"/>
                 <constraint firstItem="VJU-LE-Pdq" firstAttribute="trailing" secondItem="uwR-ra-cDH" secondAttribute="trailing" id="Tew-m4-zeK"/>
                 <constraint firstItem="VJU-LE-Pdq" firstAttribute="trailing" secondItem="uwR-ra-cDH" secondAttribute="trailing" id="Tew-m4-zeK"/>
-                <constraint firstItem="Zrx-Pe-2NT" firstAttribute="top" secondItem="SXB-cz-Qdh" secondAttribute="top" constant="46" id="Xd5-nj-nbj"/>
+                <constraint firstItem="Ke2-CX-K7G" firstAttribute="centerY" secondItem="5sT-Eb-2rJ" secondAttribute="centerY" id="Vh3-en-b6z"/>
                 <constraint firstItem="V2v-I8-jzm" firstAttribute="leading" secondItem="VJU-LE-Pdq" secondAttribute="trailing" constant="22" id="YYc-Q5-aGD"/>
                 <constraint firstItem="V2v-I8-jzm" firstAttribute="leading" secondItem="VJU-LE-Pdq" secondAttribute="trailing" constant="22" id="YYc-Q5-aGD"/>
                 <constraint firstItem="IXi-hL-in1" firstAttribute="top" secondItem="Tkl-Cw-Mdz" secondAttribute="bottom" constant="7" id="YgN-1n-xha"/>
                 <constraint firstItem="IXi-hL-in1" firstAttribute="top" secondItem="Tkl-Cw-Mdz" secondAttribute="bottom" constant="7" id="YgN-1n-xha"/>
                 <constraint firstAttribute="trailing" secondItem="7Em-FC-3EL" secondAttribute="trailing" constant="14" id="a3n-fN-euB"/>
                 <constraint firstAttribute="trailing" secondItem="7Em-FC-3EL" secondAttribute="trailing" constant="14" id="a3n-fN-euB"/>
-                <constraint firstItem="Zrx-Pe-2NT" firstAttribute="top" secondItem="PnS-Ku-vsa" secondAttribute="bottom" constant="12" id="aSM-PX-vLj"/>
                 <constraint firstItem="g4h-vE-BMO" firstAttribute="leading" secondItem="Cai-ev-v5E" secondAttribute="leading" id="btp-Oe-y1i"/>
                 <constraint firstItem="g4h-vE-BMO" firstAttribute="leading" secondItem="Cai-ev-v5E" secondAttribute="leading" id="btp-Oe-y1i"/>
                 <constraint firstItem="sZj-ZO-VHR" firstAttribute="centerY" secondItem="Cai-ev-v5E" secondAttribute="centerY" id="cIh-IQ-xRr"/>
                 <constraint firstItem="sZj-ZO-VHR" firstAttribute="centerY" secondItem="Cai-ev-v5E" secondAttribute="centerY" id="cIh-IQ-xRr"/>
                 <constraint firstItem="Tkl-Cw-Mdz" firstAttribute="top" secondItem="7Em-FC-3EL" secondAttribute="bottom" constant="12" id="cJp-sC-nM0"/>
                 <constraint firstItem="Tkl-Cw-Mdz" firstAttribute="top" secondItem="7Em-FC-3EL" secondAttribute="bottom" constant="12" id="cJp-sC-nM0"/>
@@ -338,8 +371,11 @@
                 <constraint firstItem="7Em-FC-3EL" firstAttribute="bottom" secondItem="ZeX-qM-LJD" secondAttribute="bottom" id="coV-Qi-RkQ"/>
                 <constraint firstItem="7Em-FC-3EL" firstAttribute="bottom" secondItem="ZeX-qM-LJD" secondAttribute="bottom" id="coV-Qi-RkQ"/>
                 <constraint firstItem="Ux8-2g-RqK" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="22" id="cwN-DO-wkV"/>
                 <constraint firstItem="Ux8-2g-RqK" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="22" id="cwN-DO-wkV"/>
                 <constraint firstItem="VJU-LE-Pdq" firstAttribute="bottom" secondItem="uwR-ra-cDH" secondAttribute="bottom" id="e0m-sL-feH"/>
                 <constraint firstItem="VJU-LE-Pdq" firstAttribute="bottom" secondItem="uwR-ra-cDH" secondAttribute="bottom" id="e0m-sL-feH"/>
+                <constraint firstItem="5sT-Eb-2rJ" firstAttribute="leading" secondItem="Zrx-Pe-2NT" secondAttribute="leading" constant="50" id="eBI-aU-v4Z"/>
                 <constraint firstItem="Ux8-2g-RqK" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="ev8-FX-ve4"/>
                 <constraint firstItem="Ux8-2g-RqK" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="ev8-FX-ve4"/>
                 <constraint firstItem="VJU-LE-Pdq" firstAttribute="leading" secondItem="uwR-ra-cDH" secondAttribute="leading" id="hAr-OA-5ce"/>
                 <constraint firstItem="VJU-LE-Pdq" firstAttribute="leading" secondItem="uwR-ra-cDH" secondAttribute="leading" id="hAr-OA-5ce"/>
+                <constraint firstItem="5sT-Eb-2rJ" firstAttribute="top" secondItem="Zrx-Pe-2NT" secondAttribute="bottom" id="ixH-ow-czJ"/>
+                <constraint firstItem="Zrx-Pe-2NT" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="25" id="lyO-cd-xcJ"/>
                 <constraint firstItem="Sbe-L2-liH" firstAttribute="leading" secondItem="Ux8-2g-RqK" secondAttribute="trailing" constant="5" id="meC-LK-DKS"/>
                 <constraint firstItem="Sbe-L2-liH" firstAttribute="leading" secondItem="Ux8-2g-RqK" secondAttribute="trailing" constant="5" id="meC-LK-DKS"/>
                 <constraint firstItem="g4h-vE-BMO" firstAttribute="top" secondItem="Cai-ev-v5E" secondAttribute="top" id="nxA-Si-aiG"/>
                 <constraint firstItem="g4h-vE-BMO" firstAttribute="top" secondItem="Cai-ev-v5E" secondAttribute="top" id="nxA-Si-aiG"/>
                 <constraint firstItem="7Em-FC-3EL" firstAttribute="trailing" secondItem="ZeX-qM-LJD" secondAttribute="trailing" id="oKn-54-J78"/>
                 <constraint firstItem="7Em-FC-3EL" firstAttribute="trailing" secondItem="ZeX-qM-LJD" secondAttribute="trailing" id="oKn-54-J78"/>
@@ -356,13 +392,16 @@
                 <outlet property="A4FrequenceLabel" destination="Ux8-2g-RqK" id="Jra-7M-iTB"/>
                 <outlet property="A4FrequenceLabel" destination="Ux8-2g-RqK" id="Jra-7M-iTB"/>
                 <outlet property="addButton" destination="VJU-LE-Pdq" id="Ap2-3f-er6"/>
                 <outlet property="addButton" destination="VJU-LE-Pdq" id="Ap2-3f-er6"/>
                 <outlet property="addView" destination="uwR-ra-cDH" id="aTz-zS-V4w"/>
                 <outlet property="addView" destination="uwR-ra-cDH" id="aTz-zS-V4w"/>
+                <outlet property="distanceLabel" destination="D7p-nE-fr1" id="36B-jL-Pga"/>
                 <outlet property="minusButton" destination="Cai-ev-v5E" id="7T1-RS-zM3"/>
                 <outlet property="minusButton" destination="Cai-ev-v5E" id="7T1-RS-zM3"/>
                 <outlet property="minusView" destination="g4h-vE-BMO" id="SOP-VD-G0z"/>
                 <outlet property="minusView" destination="g4h-vE-BMO" id="SOP-VD-G0z"/>
+                <outlet property="nextFrequence" destination="Ke2-CX-K7G" id="fQM-qB-mxv"/>
                 <outlet property="nomalPitch" destination="uIc-iL-EXg" id="i9k-OK-L2i"/>
                 <outlet property="nomalPitch" destination="uIc-iL-EXg" id="i9k-OK-L2i"/>
                 <outlet property="pitchBgView" destination="7Em-FC-3EL" id="0rG-SE-app"/>
                 <outlet property="pitchBgView" destination="7Em-FC-3EL" id="0rG-SE-app"/>
                 <outlet property="pitchFrequenceLabel" destination="PnS-Ku-vsa" id="LlJ-w5-az7"/>
                 <outlet property="pitchFrequenceLabel" destination="PnS-Ku-vsa" id="LlJ-w5-az7"/>
                 <outlet property="plateView" destination="Zrx-Pe-2NT" id="ppk-X8-oX5"/>
                 <outlet property="plateView" destination="Zrx-Pe-2NT" id="ppk-X8-oX5"/>
                 <outlet property="playButton" destination="p0z-qL-bMm" id="DsB-sp-PJ7"/>
                 <outlet property="playButton" destination="p0z-qL-bMm" id="DsB-sp-PJ7"/>
+                <outlet property="preFrequence" destination="5sT-Eb-2rJ" id="YqE-f3-IK2"/>
                 <outlet property="transferDesc" destination="tD3-d1-rfd" id="vBI-n9-F5P"/>
                 <outlet property="transferDesc" destination="tD3-d1-rfd" id="vBI-n9-F5P"/>
                 <outlet property="transferNomalPitch" destination="MNR-s0-re6" id="sVk-tj-gtm"/>
                 <outlet property="transferNomalPitch" destination="MNR-s0-re6" id="sVk-tj-gtm"/>
                 <outlet property="transferPitch" destination="vku-Yz-AEN" id="ca0-HH-hao"/>
                 <outlet property="transferPitch" destination="vku-Yz-AEN" id="ca0-HH-hao"/>

+ 21 - 0
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/TunerSettingView.h

@@ -7,10 +7,31 @@
 
 
 #import <UIKit/UIKit.h>
 #import <UIKit/UIKit.h>
 
 
+typedef NS_ENUM(NSInteger, TUNETSETTING_ACTION) {
+    TUNETSETTING_ACTION_INSTRUMENT,
+    TUNETSETTING_ACTION_SURE,
+};
+
+typedef void(^TunerSettingCallback)(TUNETSETTING_ACTION action, NSInteger toneChangeRate, NSInteger frequence);
+
 NS_ASSUME_NONNULL_BEGIN
 NS_ASSUME_NONNULL_BEGIN
 
 
 @interface TunerSettingView : UIView
 @interface TunerSettingView : UIView
 
 
+@property (weak, nonatomic) IBOutlet UILabel *instrumentLabel;
+/// 乐器选择->变调情况
+@property (nonatomic, assign) NSInteger toneChangeRate;
+// A4频率
+@property (nonatomic, assign) NSInteger A4Frequence;
+
+@property (nonatomic, strong) NSString *transferPicthDesc;
+
++ (instancetype)shareInstance;
+
+- (void)tunerSettingAction:(TunerSettingCallback)callback;
+
+- (void)showView;
+
 @end
 @end
 
 
 NS_ASSUME_NONNULL_END
 NS_ASSUME_NONNULL_END

+ 72 - 0
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/TunerSettingView.m

@@ -6,9 +6,81 @@
 //
 //
 
 
 #import "TunerSettingView.h"
 #import "TunerSettingView.h"
+#import "UIView+Animation.h"
+
+#define MAXFREQUENCE (445)
+#define MINFREQUENCE (415)
+
+@interface TunerSettingView ()
+
+@property (nonatomic, copy) TunerSettingCallback callback;
+
+@property (weak, nonatomic) IBOutlet UILabel *frequenceLabel;
+
+@end
+
 
 
 @implementation TunerSettingView
 @implementation TunerSettingView
 
 
++ (instancetype)shareInstance {
+    TunerSettingView *view = [[[NSBundle mainBundle] loadNibNamed:@"TunerSettingView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)tunerSettingAction:(TunerSettingCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (void)showView {
+    [[NSObject getKeyWindow] addSubview:self];
+    [self setPopAnimation];
+}
+
+- (void)removeView {
+    [self removeFromSuperview];
+}
+
+- (IBAction)frequenceMinus:(id)sender {
+    NSInteger frequence = self.A4Frequence;
+    if (self.A4Frequence <= MINFREQUENCE) {
+        return;
+    }
+    self.A4Frequence = frequence - 1;
+
+}
+
+- (IBAction)frequenceAdd:(id)sender {
+    NSInteger frequence = self.A4Frequence;
+    if (self.A4Frequence >= MAXFREQUENCE) {
+        return;
+    }
+    self.A4Frequence = frequence + 1;
+}
+- (IBAction)resetFrequence:(id)sender {
+    self.A4Frequence = 440;
+}
+
+- (IBAction)chooseInstrunemt:(id)sender {
+    if (self.callback) {
+        self.callback(TUNETSETTING_ACTION_INSTRUMENT, self.toneChangeRate, self.A4Frequence);
+    }
+}
+
+
+- (IBAction)sureAtion:(id)sender {
+    if (self.callback) {
+        self.callback(TUNETSETTING_ACTION_SURE, self.toneChangeRate, self.A4Frequence);
+    }
+    [self removeView];
+}
+
+
+- (void)setA4Frequence:(NSInteger)A4Frequence {
+    _A4Frequence = A4Frequence;
+    self.frequenceLabel.text = [NSString stringWithFormat:@"%zdHz",A4Frequence];
+}
 /*
 /*
 // Only override drawRect: if you perform custom drawing.
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 // An empty implementation adversely affects performance during animation.

+ 239 - 8
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/TunerSettingView.xib

@@ -1,18 +1,249 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="13142" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_0" orientation="portrait" appearance="light"/>
     <dependencies>
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12042"/>
-        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     </dependencies>
     <objects>
     <objects>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB">
-            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="TunerSettingView">
+            <rect key="frame" x="0.0" y="0.0" width="390" height="844"/>
             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
             <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-            <color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
-            <viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zvx-Af-NkA">
+                    <rect key="frame" x="59.666666666666657" y="255.66666666666663" width="271" height="333"/>
+                    <subviews>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qda-Ej-mIn">
+                            <rect key="frame" x="18" y="64.000000000000028" width="235" height="45"/>
+                            <subviews>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="长笛:C大调" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EOf-Po-cpZ">
+                                    <rect key="frame" x="17" y="12.666666666666627" width="93" height="19.333333333333329"/>
+                                    <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                                    <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="instrument_choose" translatesAutoresizingMaskIntoConstraints="NO" id="lfw-pC-y6W">
+                                    <rect key="frame" x="214" y="16" width="9" height="13"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="9" id="6lp-xW-auq"/>
+                                        <constraint firstAttribute="height" constant="13" id="xGg-HO-POW"/>
+                                    </constraints>
+                                </imageView>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4JG-vi-r5z">
+                                    <rect key="frame" x="0.0" y="0.0" width="235" height="45"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="chooseInstrunemt:" destination="iN0-l3-epB" eventType="touchUpInside" id="dRS-bh-Bqe"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" red="0.94509803921568625" green="0.94509803921568625" blue="0.94509803921568625" alpha="1" colorSpace="calibratedRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="trailing" secondItem="lfw-pC-y6W" secondAttribute="trailing" constant="12" id="7H8-cv-AcI"/>
+                                <constraint firstAttribute="bottom" secondItem="4JG-vi-r5z" secondAttribute="bottom" id="9h0-YG-Kdk"/>
+                                <constraint firstItem="lfw-pC-y6W" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="EOf-Po-cpZ" secondAttribute="trailing" constant="10" id="CfB-v4-cmc"/>
+                                <constraint firstItem="lfw-pC-y6W" firstAttribute="centerY" secondItem="qda-Ej-mIn" secondAttribute="centerY" id="Eor-zw-cTu"/>
+                                <constraint firstItem="EOf-Po-cpZ" firstAttribute="centerY" secondItem="qda-Ej-mIn" secondAttribute="centerY" id="HR4-gt-ISH"/>
+                                <constraint firstAttribute="height" constant="45" id="bUq-fG-WLZ"/>
+                                <constraint firstItem="4JG-vi-r5z" firstAttribute="leading" secondItem="qda-Ej-mIn" secondAttribute="leading" id="daT-QC-JzR"/>
+                                <constraint firstAttribute="trailing" secondItem="4JG-vi-r5z" secondAttribute="trailing" id="fI2-Us-8r0"/>
+                                <constraint firstItem="4JG-vi-r5z" firstAttribute="top" secondItem="qda-Ej-mIn" secondAttribute="top" id="xJa-hI-3fS"/>
+                                <constraint firstItem="EOf-Po-cpZ" firstAttribute="leading" secondItem="qda-Ej-mIn" secondAttribute="leading" constant="17" id="xcf-bw-F3f"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="6"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </view>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="设置" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EDe-Es-ZOO">
+                            <rect key="frame" x="118" y="14.000000000000028" width="35" height="24"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="24" id="PUZ-p7-3Nr"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                            <color key="textColor" red="0.1019607843" green="0.1019607843" blue="0.1019607843" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mDa-ie-eMH">
+                            <rect key="frame" x="18" y="275" width="235" height="40"/>
+                            <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="40" id="8vf-71-f2U"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" title="确认"/>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="6"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                            <connections>
+                                <action selector="sureAtion:" destination="iN0-l3-epB" eventType="touchUpInside" id="NW9-2O-UWA"/>
+                            </connections>
+                        </button>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageWhenHighlighted="NO" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2g5-vG-H7G">
+                            <rect key="frame" x="18.000000000000007" y="177.00000000000003" width="63.999999999999993" height="45"/>
+                            <color key="backgroundColor" red="0.94509803921568625" green="0.94509803921568625" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" image="speed_add">
+                                <color key="titleColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            </state>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="6"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                            <connections>
+                                <action selector="frequenceAdd:" destination="iN0-l3-epB" eventType="touchUpInside" id="Uoq-GS-qWv"/>
+                            </connections>
+                        </button>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Qhz-EL-kI1">
+                            <rect key="frame" x="189" y="177.00000000000003" width="64" height="45"/>
+                            <color key="backgroundColor" red="0.94509803921568625" green="0.94509803921568625" blue="0.94509803921568625" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" image="speed_minus">
+                                <color key="titleColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            </state>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="6"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                            <connections>
+                                <action selector="frequenceMinus:" destination="iN0-l3-epB" eventType="touchUpInside" id="a0a-bZ-ijm"/>
+                            </connections>
+                        </button>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="UV0-Et-juG">
+                            <rect key="frame" x="94" y="177.00000000000003" width="83" height="45"/>
+                            <subviews>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="440Hz" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="kAP-y9-pDd">
+                                    <rect key="frame" x="19.333333333333346" y="14" width="44.333333333333343" height="17"/>
+                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                    <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                            </subviews>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="45" id="6i7-n9-sOp"/>
+                                <constraint firstAttribute="width" constant="83" id="LT5-wv-I7C"/>
+                                <constraint firstItem="kAP-y9-pDd" firstAttribute="centerX" secondItem="UV0-Et-juG" secondAttribute="centerX" id="QaN-YV-ztS"/>
+                                <constraint firstItem="kAP-y9-pDd" firstAttribute="centerY" secondItem="UV0-Et-juG" secondAttribute="centerY" id="UsU-QK-hNv"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="6"/>
+                                </userDefinedRuntimeAttribute>
+                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                    <real key="value" value="1"/>
+                                </userDefinedRuntimeAttribute>
+                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                    <color key="value" red="0.59215686270000001" green="0.59215686270000001" blue="0.59215686270000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </view>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aNk-pq-Ual">
+                            <rect key="frame" x="18" y="230.00000000000003" width="235" height="30.999999999999972"/>
+                            <color key="backgroundColor" red="0.94509803921568625" green="0.94509803921568625" blue="0.94509803921568625" alpha="1" colorSpace="calibratedRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="31" id="MBY-je-3Ow"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" title="Reset:440Hz">
+                                <color key="titleColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                            </state>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="6"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                            <connections>
+                                <action selector="resetFrequence:" destination="iN0-l3-epB" eventType="touchUpInside" id="GGF-HC-PX6"/>
+                            </connections>
+                        </button>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="A4 Frquency" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uzJ-r7-heL">
+                            <rect key="frame" x="18.000000000000007" y="147.00000000000003" width="83" height="20"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="20" id="DE1-95-dRt"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0cJ-gC-99F">
+                            <rect key="frame" x="18" y="135.00000000000003" width="235" height="1"/>
+                            <color key="backgroundColor" red="0.91764705882352937" green="0.91764705882352937" blue="0.91764705882352937" alpha="1" colorSpace="calibratedRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="1" id="OCc-t4-qfg"/>
+                            </constraints>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstItem="UV0-Et-juG" firstAttribute="centerY" secondItem="2g5-vG-H7G" secondAttribute="centerY" id="3BV-NF-v7z"/>
+                        <constraint firstAttribute="bottom" secondItem="mDa-ie-eMH" secondAttribute="bottom" constant="18" id="5VQ-mF-Jhw"/>
+                        <constraint firstItem="mDa-ie-eMH" firstAttribute="leading" secondItem="aNk-pq-Ual" secondAttribute="leading" id="74N-rY-NDU"/>
+                        <constraint firstItem="EDe-Es-ZOO" firstAttribute="centerX" secondItem="zvx-Af-NkA" secondAttribute="centerX" id="80S-JL-SG1"/>
+                        <constraint firstItem="UV0-Et-juG" firstAttribute="centerX" secondItem="zvx-Af-NkA" secondAttribute="centerX" id="AjW-sj-YPf"/>
+                        <constraint firstItem="mDa-ie-eMH" firstAttribute="leading" secondItem="zvx-Af-NkA" secondAttribute="leading" constant="18" id="Icv-Bu-2GE"/>
+                        <constraint firstItem="Qhz-EL-kI1" firstAttribute="leading" secondItem="UV0-Et-juG" secondAttribute="trailing" constant="12" id="LeD-aR-KZv"/>
+                        <constraint firstItem="qda-Ej-mIn" firstAttribute="top" secondItem="EDe-Es-ZOO" secondAttribute="bottom" constant="26" id="Msr-0j-WvN"/>
+                        <constraint firstItem="uzJ-r7-heL" firstAttribute="top" secondItem="0cJ-gC-99F" secondAttribute="bottom" constant="11" id="NE8-vH-b8x"/>
+                        <constraint firstItem="2g5-vG-H7G" firstAttribute="top" secondItem="uzJ-r7-heL" secondAttribute="bottom" constant="10" id="OyQ-f6-hXP"/>
+                        <constraint firstItem="aNk-pq-Ual" firstAttribute="top" secondItem="UV0-Et-juG" secondAttribute="bottom" constant="8" id="Q0l-2U-Ozd"/>
+                        <constraint firstItem="EDe-Es-ZOO" firstAttribute="top" secondItem="zvx-Af-NkA" secondAttribute="top" constant="14" id="Vow-vC-Jjs"/>
+                        <constraint firstItem="Qhz-EL-kI1" firstAttribute="trailing" secondItem="aNk-pq-Ual" secondAttribute="trailing" id="aHS-0S-Kgy"/>
+                        <constraint firstAttribute="trailing" secondItem="mDa-ie-eMH" secondAttribute="trailing" constant="18" id="byH-F9-gVw"/>
+                        <constraint firstItem="UV0-Et-juG" firstAttribute="height" secondItem="2g5-vG-H7G" secondAttribute="height" id="cXu-TO-QAi"/>
+                        <constraint firstAttribute="trailing" secondItem="qda-Ej-mIn" secondAttribute="trailing" constant="18" id="d8m-hC-mIZ"/>
+                        <constraint firstItem="qda-Ej-mIn" firstAttribute="leading" secondItem="zvx-Af-NkA" secondAttribute="leading" constant="18" id="dv1-yD-usK"/>
+                        <constraint firstItem="uzJ-r7-heL" firstAttribute="leading" secondItem="zvx-Af-NkA" secondAttribute="leading" constant="18" id="gXv-ms-gJb"/>
+                        <constraint firstItem="mDa-ie-eMH" firstAttribute="top" secondItem="aNk-pq-Ual" secondAttribute="bottom" constant="14" id="gbF-yN-qmd"/>
+                        <constraint firstItem="UV0-Et-juG" firstAttribute="leading" secondItem="2g5-vG-H7G" secondAttribute="trailing" constant="12" id="iFc-A9-LG4"/>
+                        <constraint firstItem="Qhz-EL-kI1" firstAttribute="height" secondItem="2g5-vG-H7G" secondAttribute="height" id="nlg-Cb-apR"/>
+                        <constraint firstAttribute="trailing" secondItem="0cJ-gC-99F" secondAttribute="trailing" constant="18" id="p3h-da-69M"/>
+                        <constraint firstItem="Qhz-EL-kI1" firstAttribute="centerY" secondItem="2g5-vG-H7G" secondAttribute="centerY" id="prF-22-4aI"/>
+                        <constraint firstItem="mDa-ie-eMH" firstAttribute="trailing" secondItem="aNk-pq-Ual" secondAttribute="trailing" id="q28-gL-kU6"/>
+                        <constraint firstAttribute="width" constant="271" id="qqF-ug-lB6"/>
+                        <constraint firstItem="aNk-pq-Ual" firstAttribute="leading" secondItem="2g5-vG-H7G" secondAttribute="leading" id="tKz-5v-yaC"/>
+                        <constraint firstItem="0cJ-gC-99F" firstAttribute="top" secondItem="qda-Ej-mIn" secondAttribute="bottom" constant="26" id="tmX-4F-FaS"/>
+                        <constraint firstItem="0cJ-gC-99F" firstAttribute="leading" secondItem="zvx-Af-NkA" secondAttribute="leading" constant="18" id="wqy-8o-TR9"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="15"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="calibratedRGB"/>
+            <constraints>
+                <constraint firstItem="zvx-Af-NkA" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="WK7-3Z-e0F"/>
+                <constraint firstItem="zvx-Af-NkA" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="hnd-7l-R35"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="frequenceLabel" destination="kAP-y9-pDd" id="N3x-Ni-VBp"/>
+                <outlet property="instrumentLabel" destination="EOf-Po-cpZ" id="5ou-au-uyX"/>
+            </connections>
+            <point key="canvasLocation" x="61.538461538461533" y="-11.374407582938389"/>
         </view>
         </view>
     </objects>
     </objects>
+    <resources>
+        <image name="instrument_choose" width="9" height="13"/>
+        <image name="speed_add" width="14" height="14"/>
+        <image name="speed_minus" width="14" height="14"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
 </document>
 </document>