Kaynağa Gözat

仪表盘效果

Steven 2 yıl önce
ebeveyn
işleme
59fb84d8a7
24 değiştirilmiş dosya ile 1219 ekleme ve 106 silme
  1. 20 0
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/TuningImage/instrument_choose.imageset/Contents.json
  3. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/TuningImage/instrument_choose.imageset/instrument_choose@2x.png
  4. BIN
      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 */; };
 		BCD457AC286469600010B493 /* PublicNoticeView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCD457AA286469600010B493 /* PublicNoticeView.xib */; };
 		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 */; };
 		BCD9295228F90202006793E4 /* ToneTuningBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCD9295128F90202006793E4 /* ToneTuningBodyView.m */; };
 		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>"; };
 		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>"; };
+		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>"; };
 		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>"; };
@@ -4658,6 +4664,7 @@
 		BC4CF28B28D058FB00961C61 /* View */ = {
 			isa = PBXGroup;
 			children = (
+				BCD886DE2907E75300BC4EE6 /* KSGaugeView */,
 				BCD9295528F9447B006793E4 /* WMGaugeView */,
 				BCFEED7028F7F16C0078A2B7 /* toneTuning */,
 				BCFEED4E28F7E4910078A2B7 /* Metronome */,
@@ -6097,6 +6104,17 @@
 			path = images;
 			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 */ = {
 			isa = PBXGroup;
 			children = (
@@ -7041,6 +7059,7 @@
 				BC8A45AC283DC33400094BBB /* KSSliderView.m in Sources */,
 				2723B62927F157D500E0B90B /* KSChatComplainController.m in Sources */,
 				2779351527E324A60010E277 /* NSArray+KSSafe.m in Sources */,
+				BCD886E42908E69900BC4EE6 /* KSGaugeColorView.m in Sources */,
 				2723B61A27F157D500E0B90B /* KSSearchResultViewCell.m in Sources */,
 				BC48C3A92828FC7D00EE65C5 /* KSUploadManager.m in Sources */,
 				BC8A4599283DC33400094BBB /* TBXML.m in Sources */,
@@ -7313,6 +7332,7 @@
 				BC8A459D283DC33400094BBB /* KSParseMessageModel.m in Sources */,
 				275FA23327E7356B00CFEA2E /* VefiCodeLoginController.m in Sources */,
 				BCB6359C27F6D2AB00ACFDCF /* ClassVideoListCell.m in Sources */,
+				BCD886E12907E7AE00BC4EE6 /* KSGaugeView.m in Sources */,
 				2723B61B27F157D500E0B90B /* KSSearchRCLabel.m in Sources */,
 				BC7E770F2900F38F00EB37AF /* TuningForkSettingView.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
+  }
+}

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/TuningImage/instrument_choose.imageset/instrument_choose@2x.png


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

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

@@ -139,13 +139,13 @@ shouldPrevent = NO; \
 
 //#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
 
-#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
 

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

@@ -12,6 +12,9 @@
 #import "DialPlateView.h"
 #import "TuningForkSettingView.h"
 #import <AVFoundation/AVFoundation.h>
+#import "TunerSettingView.h"
+#import "KSChoosePicker.h"
+//#import "KSGaugeView.h"
 
 @interface ToneTuningViewController ()<TunerDelegate>
 
@@ -33,6 +36,19 @@
 
 @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
 
 @implementation ToneTuningViewController
@@ -41,11 +57,16 @@
     [super viewDidLoad];
     // Do any additional setup after loading the view.
     self.ks_prefersNavigationBarHidden = YES;
-    self.chooseFrequence = 440;
+    [self configDefault];
     [self configUI];
     [self setupAudioSession];
 }
 
+- (void)configDefault {
+    self.chooseFrequence = 440;
+    self.isTransfer = NO;
+}
+
 - (void)setupAudioSession {
     
     AVAudioSession *audioSession = [AVAudioSession sharedInstance];
@@ -63,7 +84,6 @@
 - (void)configUI {
     [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)];
-    layer.cornerRadius = 14.0f;
     layer.masksToBounds = YES;
     [self.view.layer addSublayer:layer];
     
@@ -80,6 +100,11 @@
         make.top.mas_equalTo(self.navView.mas_bottom);
         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.plateView mas_makeConstraints:^(MASConstraintMaker *make) {
         make.top.bottom.left.right.mas_equalTo(self.bodyView.plateView);
@@ -138,7 +163,7 @@
 }
 
 - (void)showSettingView {
-    
+    [self.settingView showView];
 }
 
 - (Tuner *)tuner {
@@ -154,17 +179,33 @@
         
     }
     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) {
             self.bodyView.nomalPitch.text = output.pitch;
             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 {
+            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 {
     switch (action) {
-        case TUNINGACTION_SETTING: // 乐器选择
-        {
-            
-        }
-            break;
         case TUNINGACTION_FORKSETTING:  // 音叉设置
         {
             [self.forkView showView];
@@ -195,7 +231,9 @@
             break;
         case TUNINGACTION_FREQUENCE: // 调整频率
         {
-            
+            self.chooseFrequence = frequence;
+            self.settingView.A4Frequence = frequence;
+            self.tuner.A4Frequence = frequence;
         }
             break;
         case TUNINGACTION_PLAY:      // 播放音叉
@@ -233,6 +271,7 @@
 - (TuningForkSettingView *)forkView {
     if (!_forkView) {
         _forkView = [TuningForkSettingView shareInstance];
+        _forkView.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight);
         MJWeakSelf;
         [_forkView forkSettingAction:^(NSInteger frequence) {
             NSLog(@"----- frequence %zd", frequence);
@@ -252,6 +291,79 @@
     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
 

+ 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 = ""
     
     /**
+     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
      frequency of the microphone audio.
      
@@ -84,6 +111,10 @@ private let frequencies: [Float] = [
 @objc public class Tuner: NSObject {
     
     fileprivate let smoothingBufferCount = 30
+    // 设置的A4标准频率
+    @objc public var A4Frequence: Int
+    // 移调
+    @objc public var toneChangeRate: Int
     
     fileprivate let threshold: Float
     fileprivate let smoothing: Float
@@ -109,6 +140,8 @@ private let frequencies: [Float] = [
     @objc public init(threshold: Float = 0.0, smoothing: Float = 0.25) {
         self.threshold = Float(min(abs(threshold), 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.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
     }
+    
+//    @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];
 
         // 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];
         
         // Draw needle
@@ -208,6 +208,7 @@
 
     if (_showRangeLabels)
         [self drawRangeLabels:context];
+    
 }
 
 /**
@@ -216,6 +217,48 @@
 - (void)drawRim:(CGContextRef)context
 {
     // 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 == WMGaugeViewSubdivisionsAlignmentBottom) offset = _scaleDivisionsLength - _scaleSubdivisionsLength;
         
-        CGFloat y1 = scaleRect.origin.y;
+        CGFloat y1 = scaleRect.origin.y + 0.1;
         CGFloat y2 = y1 + _scaleSubdivisionsLength;
-        CGFloat y3 = y1 + _scaleDivisionsLength;
+        CGFloat y3 = y1 - _scaleDivisionsLength;
         
         float value = [self valueForTick:i];
         float div = (_maxValue - _minValue) / _scaleDivisions;
@@ -285,12 +328,12 @@
             if(_showScaleValues) {
                 NSString *valueString = [NSString stringWithFormat:@"%0.0f",value];
                 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];
                 CGSize fontWidth;
                 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

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

@@ -39,9 +39,9 @@
     // Left Needle
     CAShapeLayer *leftNeedleLayer = [CAShapeLayer layer];
     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];
     
     leftNeedleLayer.path = leftNeedlePath.CGPath;
@@ -53,9 +53,9 @@
     // Right Needle
     CAShapeLayer *rightNeedleLayer = [CAShapeLayer layer];
     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];
     
     rightNeedleLayer.path = rightNeedlePath.CGPath;
@@ -72,8 +72,8 @@
     
     // Screw drawing
     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.fillColor = _screwFillColor.CGColor;
     screwLayer.strokeColor = _screwStrokeColor.CGColor;
@@ -99,7 +99,7 @@
     baseSpace = NULL;
     CGContextAddEllipseInRect(context, rect);
     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;
     free(positions); positions = NULL;
@@ -112,7 +112,7 @@
     CGColorSpaceRelease(baseSpace); baseSpace = NULL;
     CGContextAddEllipseInRect(context, rect);
     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;
     free(positions); positions = NULL;
     

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

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

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

@@ -19,21 +19,25 @@
 - (instancetype)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 = [[UIColor redColor] colorWithAlphaComponent:0.2];
+//        _needleColor = [[UIColor redColor] colorWithAlphaComponent:0.2];
+        _needleColor = [UIColor whiteColor];
 //        _needleScrewColor = RGB(68, 84, 105);//蓝紫灰色
-        _needleScrewColor = [UIColor systemTealColor];
+//        _needleScrewColor = [UIColor systemTealColor];
+        _needleScrewColor = HexRGB(0x1A1C21);
         
         _externalRingRadius = 0.24;
 //        _externalFaceColor = RGB(255, 104, 97);
-        _externalFaceColor = [[UIColor redColor] colorWithAlphaComponent:0.2];
-
+//        _externalFaceColor = [[[UIColor redColor] colorWithAlphaComponent:0.2]];
+        _externalFaceColor = [UIColor clearColor];
+        
         _internalRingRadius = 0.1;
 //        _internalFaceColor = RGB(242, 99, 92);//亮橘红色
         _internalFaceColor = [[UIColor yellowColor] colorWithAlphaComponent:0.2];
+        _internalFaceColor = [UIColor clearColor];
         
 //        _borderColor = RGBA(81, 84, 89, 160);//火山灰色
         _borderColor = [UIColor blackColor];
@@ -46,16 +50,17 @@
 {
     _needleLayer = [CAShapeLayer layer];
     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];
     
     _needleLayer.path = needlePath.CGPath;
     _needleLayer.backgroundColor = [[UIColor clearColor] CGColor];
     _needleLayer.fillColor = _needleColor.CGColor;
     _needleLayer.strokeColor = _needleColor.CGColor;
-    _needleLayer.lineWidth = 1.2;
+    _needleLayer.lineWidth = 2;
     
     // Needle shadow
     _needleLayer.shadowColor = [[UIColor blackColor] CGColor];
@@ -67,8 +72,8 @@
     
     // Screw drawing
     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.fillColor = _needleScrewColor.CGColor;
     
@@ -84,12 +89,12 @@
 - (void)drawFaceWithContext:(CGContextRef)context inRect:(CGRect)rect
 {
     // 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);
     CGContextFillEllipseInRect(context, externalRect);
 
     // 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);
     CGContextFillEllipseInRect(context, internalRect);
     

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

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

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

@@ -32,23 +32,9 @@
     
 }
 
-- (WMGaugeView *)gaugeView {
+- (KSGaugeView *)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;
 }

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

@@ -11,7 +11,6 @@
 #define MINFREQUENCE (415)
 
 typedef NS_ENUM(NSInteger, TUNINGACTION) {
-    TUNINGACTION_SETTING,     // 设置
     TUNINGACTION_FREQUENCE,   // 调节频率
     TUNINGACTION_FORKSETTING, // 音叉设置
     TUNINGACTION_PLAY,        // 播放音叉
@@ -42,10 +41,22 @@ NS_ASSUME_NONNULL_BEGIN
 
 @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) BOOL isPlaying;
 
+// 是否移调
+@property (nonatomic, assign) BOOL isTransfer;
+// 移调调号
+@property (nonatomic, strong) NSString *transferPitchDesc;
+
+// 偏移
+@property (nonatomic, assign) NSInteger distance;
+
 + (instancetype)shareInstance;
 
 - (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 *playButton;
+@property (weak, nonatomic) IBOutlet UILabel *distanceLabel;
 
 @property (nonatomic, copy) TuningActionCallback callback;
 
@@ -116,6 +117,22 @@
     [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.
 // 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"/>
                     </constraints>
                 </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"/>
                     <constraints>
                         <constraint firstAttribute="width" secondItem="SXB-cz-Qdh" secondAttribute="height" multiplier="187:127" id="ixC-MD-R46"/>
                     </constraints>
                 </imageView>
                 <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"/>
                     <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>
                 </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">
                     <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"/>
@@ -267,18 +289,22 @@
                         <constraint firstAttribute="height" constant="29" id="tsc-a8-bbh"/>
                     </constraints>
                 </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"/>
                 </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"/>
                 </label>
                 <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>
                 </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">
-                    <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"/>
                     <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <nil key="highlightedColor"/>
@@ -305,32 +334,36 @@
             <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
             <constraints>
                 <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="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="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="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="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="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="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="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="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="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="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 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="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="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 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="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"/>
@@ -338,8 +371,11 @@
                 <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="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="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="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"/>
@@ -356,13 +392,16 @@
                 <outlet property="A4FrequenceLabel" destination="Ux8-2g-RqK" id="Jra-7M-iTB"/>
                 <outlet property="addButton" destination="VJU-LE-Pdq" id="Ap2-3f-er6"/>
                 <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="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="pitchBgView" destination="7Em-FC-3EL" id="0rG-SE-app"/>
                 <outlet property="pitchFrequenceLabel" destination="PnS-Ku-vsa" id="LlJ-w5-az7"/>
                 <outlet property="plateView" destination="Zrx-Pe-2NT" id="ppk-X8-oX5"/>
                 <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="transferNomalPitch" destination="MNR-s0-re6" id="sVk-tj-gtm"/>
                 <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>
 
+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
 
 @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
 
 NS_ASSUME_NONNULL_END

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

@@ -6,9 +6,81 @@
 //
 
 #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
 
++ (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.
 // 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>
-        <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"/>
     </dependencies>
     <objects>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <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"/>
-            <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>
     </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>