Browse Source

修改节拍器播放功能

Steven 2 years ago
parent
commit
c4fffa5575
38 changed files with 515 additions and 203 deletions
  1. 8 2
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. BIN
      KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/UserInterfaceState.xcuserstate
  3. 18 2
      KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  4. 6 0
      KulexiuForStudent/KulexiuForStudent/AppDelegate.m
  5. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigHightSpot.imageset/Contents.json
  6. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigHightSpot.imageset/metro_bigHightSpot@2x.png
  7. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigHightSpot.imageset/metro_bigHightSpot@3x.png
  8. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigWhiteSpot.imageset/Contents.json
  9. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigWhiteSpot.imageset/metro_bigWhiteSpot@2x.png
  10. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigWhiteSpot.imageset/metro_bigWhiteSpot@3x.png
  11. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_hightSpot.imageset/metro_hightSpot@2x.png
  12. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_hightSpot.imageset/metro_hightSpot@3x.png
  13. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_whiteSpot.imageset/metro_whiteSpot@2x.png
  14. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_whiteSpot.imageset/metro_whiteSpot@3x.png
  15. 5 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSBaseWKWebViewController.m
  16. 14 14
      KulexiuForStudent/KulexiuForStudent/Common/Define/PrefixHeader.pch
  17. BIN
      KulexiuForStudent/KulexiuForStudent/Module/Classroom/View/tick.wav
  18. BIN
      KulexiuForStudent/KulexiuForStudent/Module/Classroom/View/tock.wav
  19. 0 1
      KulexiuForStudent/KulexiuForStudent/Module/Home/Controller/HomeViewController.m
  20. 6 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Controller/NotiferMessageViewController.m
  21. 5 1
      KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m
  22. 1 0
      KulexiuForStudent/KulexiuForStudent/Module/Login/Controller/PasswordLoginController.m
  23. 6 0
      KulexiuForStudent/KulexiuForStudent/Module/Login/Model/UserInfoManager.h
  24. 16 0
      KulexiuForStudent/KulexiuForStudent/Module/Login/Model/UserInfoManager.m
  25. 7 1
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Homework/Controller/HomeworkListViewController.m
  26. 6 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/MineCourse/Controller/MyCourseViewController.m
  27. 7 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Setting/Controller/FeedbackViewController.m
  28. 35 4
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Setting/Controller/UserSettingViewController.m
  29. 4 2
      KulexiuForStudent/KulexiuForStudent/Module/SealClass/Services/RTC/RTCService.m
  30. 25 75
      KulexiuForStudent/KulexiuForStudent/Module/Widget/Controller/WidgetViewController.m
  31. 24 0
      KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/KSMetronomePlayer.h
  32. 170 0
      KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/KSMetronomePlayer.m
  33. 10 10
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetDotView.h
  34. 75 68
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetDotView.m
  35. 1 1
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetFunctionView.h
  36. 11 11
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetFunctionView.m
  37. 2 2
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetSpeedView.h
  38. 9 9
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetSpeedView.m

+ 8 - 2
KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj

@@ -450,6 +450,7 @@
 		BC494A7C286958EC00CCD343 /* MusicRoomCourseInfoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC494A7A286958EC00CCD343 /* MusicRoomCourseInfoCell.m */; };
 		BC494A7D286958EC00CCD343 /* MusicRoomCourseInfoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC494A7B286958EC00CCD343 /* MusicRoomCourseInfoCell.xib */; };
 		BC494A8028696BC300CCD343 /* MusicRoomListModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC494A7F28696BC300CCD343 /* MusicRoomListModel.m */; };
+		BC49BAEC28D98C500031FF06 /* KSMetronomePlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = BC49BAEB28D98C500031FF06 /* KSMetronomePlayer.m */; };
 		BC4CC417288FD689004AD8EC /* LaunchAnimationView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC4CC416288FD689004AD8EC /* LaunchAnimationView.m */; };
 		BC4CF26A28D025E200961C61 /* HomeQualityMusic.m in Sources */ = {isa = PBXBuildFile; fileRef = BC4CF26928D025E200961C61 /* HomeQualityMusic.m */; };
 		BC4CF26C28D025EA00961C61 /* HomeQualityMusic.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC4CF26B28D025EA00961C61 /* HomeQualityMusic.xib */; };
@@ -1768,6 +1769,8 @@
 		BC494A7B286958EC00CCD343 /* MusicRoomCourseInfoCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MusicRoomCourseInfoCell.xib; sourceTree = "<group>"; };
 		BC494A7E28696BC300CCD343 /* MusicRoomListModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicRoomListModel.h; sourceTree = "<group>"; };
 		BC494A7F28696BC300CCD343 /* MusicRoomListModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MusicRoomListModel.m; sourceTree = "<group>"; };
+		BC49BAEA28D98C500031FF06 /* KSMetronomePlayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSMetronomePlayer.h; sourceTree = "<group>"; };
+		BC49BAEB28D98C500031FF06 /* KSMetronomePlayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSMetronomePlayer.m; sourceTree = "<group>"; };
 		BC4CC415288FD689004AD8EC /* LaunchAnimationView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LaunchAnimationView.h; sourceTree = "<group>"; };
 		BC4CC416288FD689004AD8EC /* LaunchAnimationView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LaunchAnimationView.m; sourceTree = "<group>"; };
 		BC4CF26828D025E200961C61 /* HomeQualityMusic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeQualityMusic.h; sourceTree = "<group>"; };
@@ -4459,6 +4462,8 @@
 		BC4CF28A28D058FB00961C61 /* Model */ = {
 			isa = PBXGroup;
 			children = (
+				BC49BAEA28D98C500031FF06 /* KSMetronomePlayer.h */,
+				BC49BAEB28D98C500031FF06 /* KSMetronomePlayer.m */,
 			);
 			path = Model;
 			sourceTree = "<group>";
@@ -6953,6 +6958,7 @@
 				277935A427E324A80010E277 /* TZImageRequestOperation.m in Sources */,
 				BCB6356527F6D2A300ACFDCF /* AccompanyDownloadMessage.m in Sources */,
 				275FA23627E7356B00CFEA2E /* LoginBodyView.m in Sources */,
+				BC49BAEC28D98C500031FF06 /* KSMetronomePlayer.m in Sources */,
 				2779355A27E324A70010E277 /* QCCountdownButton.m in Sources */,
 				275FA1E127E7351900CFEA2E /* KSTabBarViewController.m in Sources */,
 				BC11926B280FAF5900A716F7 /* AccompanyAlertView.m in Sources */,
@@ -7336,7 +7342,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_ENTITLEMENTS = KulexiuForStudent/KulexiuForStudent.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 1.3.7;
+				CURRENT_PROJECT_VERSION = 1.3.8;
 				DEVELOPMENT_TEAM = B2AP53HHTU;
 				ENABLE_BITCODE = NO;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -7408,7 +7414,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_ENTITLEMENTS = KulexiuForStudent/KulexiuForStudent.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 1.3.7;
+				CURRENT_PROJECT_VERSION = 1.3.8;
 				DEVELOPMENT_TEAM = B2AP53HHTU;
 				ENABLE_BITCODE = NO;
 				FRAMEWORK_SEARCH_PATHS = (

BIN
KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/UserInterfaceState.xcuserstate


+ 18 - 2
KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -26,11 +26,27 @@
             filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "786"
-            endingLineNumber = "786"
+            startingLineNumber = "790"
+            endingLineNumber = "790"
             landmarkName = "-updateVideoViewContainer"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "0700CAEF-2659-4E05-BAA4-46175D2BBA9F"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "KulexiuForStudent/Module/Home/NoticeCenter/Controller/NotiferMessageViewController.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "41"
+            endingLineNumber = "41"
+            landmarkName = "-countUMEvent"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
    </Breakpoints>
 </Bucket>

+ 6 - 0
KulexiuForStudent/KulexiuForStudent/AppDelegate.m

@@ -15,6 +15,7 @@
 #import <RongIMKit/RongIMKit.h>
 
 #import <UMCommon/UMCommon.h>
+
 #import <UMShare/UMShare.h>
 #import <UShareUI/UShareUI.h>
 // 引入 JPush 功能所需头文件
@@ -197,7 +198,12 @@
 }
 
 - (void)configUM {
+
     [UMConfigure initWithAppkey:@"62a2a806eae04539a8e253ed" channel:@"App Store"];
+
+    [USER_MANAGER startCountUMEvent];
+    [USER_MANAGER sendUMEvent:@"klx_login"];
+//    [UMConfigure setLogEnabled:YES];
     // 配置友盟分享
     // 微信、QQ、微博完整版会校验合法的universalLink,不设置会在初始化平台失败
        //配置微信Universal Link需注意 universalLinkDic的key是rawInt类型,不是枚举类型 ,即为 UMSocialPlatformType.wechatSession.rawInt

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigHightSpot.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigHightSpot.imageset/metro_bigHightSpot@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigHightSpot.imageset/metro_bigHightSpot@3x.png


+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigWhiteSpot.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigWhiteSpot.imageset/metro_bigWhiteSpot@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_bigWhiteSpot.imageset/metro_bigWhiteSpot@3x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_hightSpot.imageset/metro_hightSpot@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_hightSpot.imageset/metro_hightSpot@3x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_whiteSpot.imageset/metro_whiteSpot@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/metronome/metro_whiteSpot.imageset/metro_whiteSpot@3x.png


+ 5 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/KSBaseWKWebViewController.m

@@ -156,6 +156,7 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     }
 }
 
+
 - (void)sendResumeMessage {
     
     NSMutableDictionary *parm = [NSMutableDictionary dictionary];
@@ -578,6 +579,10 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
             [self postMessage:sendParm];
         }
     }
+    else if ([[parm stringValueForKey:@"api"] isEqualToString:@"setEventTracking"]) {
+        NSString *type = [[parm dictionaryValueForKey:@"content"] stringValueForKey:@"type"];
+        [USER_MANAGER sendUMEvent:type];
+    }
 }
 
 - (void)chooseFileWithType:(NSString *)typeStr maxNumber:(NSInteger)maxCount bucket:(NSString *)bucket {

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

@@ -117,24 +117,24 @@ 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)
 
 
 //#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
 

BIN
KulexiuForStudent/KulexiuForStudent/Module/Classroom/View/tick.wav


BIN
KulexiuForStudent/KulexiuForStudent/Module/Classroom/View/tock.wav


+ 0 - 1
KulexiuForStudent/KulexiuForStudent/Module/Home/Controller/HomeViewController.m

@@ -561,7 +561,6 @@
 }
 
 
-
 - (void)requestHotMusic {
     dispatch_group_enter(self.requestGroup);
     [KSNetworkingManager homeMusicListRequest:KS_POST version:[USER_MANAGER getCurrentVersion] success:^(NSDictionary * _Nonnull dic) {

+ 6 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Controller/NotiferMessageViewController.m

@@ -14,6 +14,7 @@
 #import "HomeworkDetailViewController.h"
 #import "UIButton+EnlargeEdge.h"
 #import "NotiferNavView.h"
+#import "UserInfoManager.h"
 
 @interface NotiferMessageViewController ()<UITableViewDelegate, UITableViewDataSource>
 
@@ -36,12 +37,17 @@
     [self resetSourceAndRequest];
 }
 
+- (void)countUMEvent {
+    [USER_MANAGER sendUMEvent:@"klx_notification"];
+}
+
 - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view.
     self.ks_prefersNavigationBarHidden = YES;
     [self configUI];
     self.hasUnreadCount = NO;
+    [self countUMEvent];
 }
 
 - (void)viewWillAppear:(BOOL)animated {

+ 5 - 1
KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m

@@ -194,10 +194,14 @@ static int clickPraiseBtnTimes  = 0;
             });
         }];
     }
-    
+    [self countUMEvent];
     [self judgeAutoClose];
 }
 
+- (void)countUMEvent {
+    [USER_MANAGER sendUMEvent:@"klx_live"];
+}
+
 - (void)muteAllAudio {
     if (self.room) {
         [self.room muteAllRemoteAudio:YES];

+ 1 - 0
KulexiuForStudent/KulexiuForStudent/Module/Login/Controller/PasswordLoginController.m

@@ -94,6 +94,7 @@
     }
 }
 
+
 - (void)toHomeView {
     AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
     [appDelegate initTableBar];

+ 6 - 0
KulexiuForStudent/KulexiuForStudent/Module/Login/Model/UserInfoManager.h

@@ -42,6 +42,12 @@ NS_ASSUME_NONNULL_BEGIN
 
 - (NSString *)getCurrentVersion;
 
+- (void)startCountUMEvent;
+
+- (void)stopCountUMEvent;
+
+- (void)sendUMEvent:(NSString *)eventId;
+
 @end
 
 NS_ASSUME_NONNULL_END

+ 16 - 0
KulexiuForStudent/KulexiuForStudent/Module/Login/Model/UserInfoManager.m

@@ -13,6 +13,7 @@
 #import "RCConnectionManager.h"
 #import "AppDelegate.h"
 #import "KSTipsAlert.h"
+#import <UMCommon/MobClick.h>
 
 @interface UserInfoManager ()
 
@@ -144,6 +145,8 @@
             
             NSString *uid = self.userInfo.userId;
             UserDefaultSet(uid, UIDKey);
+            
+            
             NSString *rongToken = UserDefault(RongTokenKey);
             BOOL needConnect = NO;
             if ([NSString isEmptyString:rongToken]) {
@@ -160,6 +163,7 @@
             [RCIM sharedRCIM].currentUserInfo = currentUserInfo;
             
             if (connectRM) {
+
                 // 设置推送别名
                 [JPUSHService setAlias:UserDefault(UIDKey) completion:nil seq:0];
                 [Bugly setUserIdentifier:UserDefault(UIDKey)];
@@ -329,6 +333,18 @@
     }
 }
 
+- (void)startCountUMEvent {
+    [MobClick profileSignInWithPUID:UserDefault(UIDKey)];
+}
+
+- (void)stopCountUMEvent {
+    [MobClick profileSignOff];
+}
+
+- (void)sendUMEvent:(NSString *)eventId {
+    [MobClick event:eventId];
+}
+
 
 - (void)dealloc {
     [[NSNotificationCenter defaultCenter] removeObserver:self];

+ 7 - 1
KulexiuForStudent/KulexiuForStudent/Module/Mine/Homework/Controller/HomeworkListViewController.m

@@ -9,7 +9,7 @@
 #import "JXCategoryView.h"
 #import "JXPagerListRefreshView.h"
 #import "HomeworkBodyView.h"
-
+#import "UserInfoManager.h"
 
 @interface HomeworkListViewController ()<JXPagerViewDelegate, JXPagerMainTableViewGestureDelegate,JXCategoryViewDelegate>
 
@@ -30,8 +30,14 @@
     [self allocTitle:@"我的作业"];
     self.titles = @[@"未提交",@"已提交"];
     [self setupUI];
+    [self countUMEvent];
+}
+
+- (void)countUMEvent {
+    [USER_MANAGER sendUMEvent:@"klx_homework"];
 }
 
+
 - (void)setupUI {
     self.headHeight = 50.0f;
     [self.scrollView removeFromSuperview];

+ 6 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/MineCourse/Controller/MyCourseViewController.m

@@ -10,6 +10,7 @@
 #import "MyVideoCourseBodyView.h"
 #import "JXCategoryView.h"
 #import "JXPagerListRefreshView.h"
+#import "UserInfoManager.h"
 
 #define HEADER_HEIGHT (50)
 
@@ -33,6 +34,11 @@
     [self allocTitle:@"我的课程"];
     self.titles = @[@"陪练课",@"直播课",@"视频课",@"琴房课"];
     [self configUI];
+    [self countUMEvent];
+}
+
+- (void)countUMEvent {
+    [USER_MANAGER sendUMEvent:@"klx_myCourse"];
 }
 
 - (void)configUI {

+ 7 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Setting/Controller/FeedbackViewController.m

@@ -7,6 +7,7 @@
 
 #import "FeedbackViewController.h"
 #import "FeedbackBodyView.h"
+#import "UserInfoManager.h"
 
 @interface FeedbackViewController ()
 
@@ -19,6 +20,12 @@
     // Do any additional setup after loading the view.
     [self allocTitle:@"意见反馈"];
     [self configUI];
+    [self countUMEvent];
+}
+
+
+- (void)countUMEvent {
+    [USER_MANAGER sendUMEvent:@"klx_feedback"];
 }
 
 - (void)configUI {

+ 35 - 4
KulexiuForStudent/KulexiuForStudent/Module/Mine/Setting/Controller/UserSettingViewController.m

@@ -24,8 +24,9 @@
 #import "StudentInfoModel.h"
 #import "KSFullDatePicker.h"
 #import "UserInfoManager.h"
+#import <RSKImageCropper/RSKImageCropper.h>
 
-@interface UserSettingViewController ()
+@interface UserSettingViewController ()<RSKImageCropViewControllerDelegate>
 
 @property (nonatomic, strong) UseBodyView *bodyView;
 
@@ -237,11 +238,17 @@
     self.mediaManager.mediaType = MEDIATYPE_PHOTO;
     self.mediaManager.maxPhotoNumber = 1;
     self.mediaManager.baseCtrl = self;
-    self.mediaManager.needCropImage = YES;
+    self.mediaManager.needCropImage = NO;
     MJWeakSelf;
     [self.mediaManager noAlertCallback:^(NSString * _Nullable videoUrl, NSMutableArray * _Nullable imageArray, NSMutableArray * _Nullable imageAsset) {
         UIImage *sendImg = [imageArray lastObject];
-        [weakSelf updateWithUserLogo:sendImg];
+        // 跳转到裁剪功能
+        RSKImageCropViewController *imageCropVC = [[RSKImageCropViewController alloc] initWithImage:sendImg cropMode:RSKImageCropModeSquare];
+        imageCropVC.rotationEnabled = YES;
+        imageCropVC.delegate = weakSelf;
+        CustomNavViewController *navCtrl = [[CustomNavViewController alloc] initWithRootViewController:imageCropVC];
+        navCtrl.modalPresentationStyle = UIModalPresentationFullScreen;
+        [weakSelf.navigationController presentViewController:navCtrl animated:YES completion:nil];
     }];
     [self.mediaManager pushImagePickerController];
 }
@@ -318,6 +325,7 @@
 }
 
 - (void)logoutAction {
+    
     [KSNetworkingManager logoutRequest:KS_GET success:^(NSDictionary * _Nonnull dic) {
         [self clearSource];
     } faliure:^(NSError * _Nonnull error) {
@@ -325,8 +333,13 @@
     }];
 }
 
+- (void)clearUMCount {
+    [USER_MANAGER sendUMEvent:@"klx_logout"];
+    [USER_MANAGER stopCountUMEvent];
+}
+
 - (void)clearSource {
-    
+    [self clearUMCount];
     USER_MANAGER.hasShowFlash = NO;
     [RCConnectionManager shareManager].isNeedJoin = NO;
     [RCConnectionManager shareManager].isNeedShowMessage = NO;
@@ -345,6 +358,24 @@
     AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
     appDelegate.window.rootViewController = navCtrl;
 }
+
+#pragma mark --- RSKImageCropViewControllerDelegate
+/**
+ 通知 delegate 取消裁剪图像。
+ */
+- (void)imageCropViewControllerDidCancelCrop:(RSKImageCropViewController *)controller {
+
+    [controller.navigationController dismissViewControllerAnimated:YES completion:nil];
+}
+
+/**
+ 通知 delegate 原始图像已经被裁剪。此外,还提供了一个裁剪矩形和用于生成图像的旋转角度。
+ */
+- (void)imageCropViewController:(RSKImageCropViewController *)controller didCropImage:(UIImage *)croppedImage usingCropRect:(CGRect)cropRect rotationAngle:(CGFloat)rotationAngle {
+//    croppedImage
+    [self updateWithUserLogo:croppedImage];
+    [controller.navigationController dismissViewControllerAnimated:YES completion:nil];
+}
 /*
 #pragma mark - Navigation
 

+ 4 - 2
KulexiuForStudent/KulexiuForStudent/Module/SealClass/Services/RTC/RTCService.m

@@ -64,6 +64,7 @@
     [self.capturer stopCapture];
     self.localView = nil;
     _capturer = nil;
+    _captureParam = nil;
     _audioCapturer = nil;
     [[RCRTCEngine sharedInstance] leaveRoom:^(BOOL isSuccess, RCRTCCode code) {
         dispatch_async(dispatch_get_main_queue(), ^{
@@ -590,6 +591,7 @@
     if(!_capturer) {
         _capturer = [RCRTCEngine sharedInstance].defaultVideoStream;
         _capturer.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
+        [_capturer setVideoConfig:self.captureParam];
         _capturer.streamEventDelegate = self;
 //        _capturer.isPreviewMirror = YES;
     }
@@ -608,8 +610,8 @@
     if (!_captureParam) {
         _captureParam = [[RCRTCVideoStreamConfig alloc] init];
         _captureParam.videoSizePreset = RCRTCVideoSizePreset640x480;
-        _captureParam.maxBitrate = 1000;
-        _captureParam.minBitrate = 500;
+        _captureParam.maxBitrate = 900;
+        _captureParam.minBitrate = 200;
     }
     return _captureParam;
 }

+ 25 - 75
KulexiuForStudent/KulexiuForStudent/Module/Widget/Controller/WidgetViewController.m

@@ -13,6 +13,7 @@
 #import "KSChoosePicker.h"
 #import "WidgetBottomButtonView.h"
 #import <AVFoundation/AVFoundation.h>
+#import "KSMetronomePlayer.h"
 
 @interface WidgetViewController ()<MetronomeControlViewDelegate,MetronomeFunctionDelegate>
 
@@ -26,7 +27,7 @@
 
 @property (nonatomic, assign) int speed;
 
-@property (nonatomic, assign) KSMetronomeType metronomeType;
+@property (nonatomic, assign) KSWidgeMetronomeType metronomeType;
 
 @property (nonatomic, strong) KSChoosePicker *pickerView;
 
@@ -38,18 +39,14 @@
 /** 定时器多少秒循环一次 */
 @property (nonatomic, assign) float timerLength;
 
-/** 发出"嘀"声的播放器 */
-@property (nonatomic, strong) AVAudioPlayer *audioPlayDI;
-
-/** 发出"咚"声的播放器 */
-@property (nonatomic, strong) AVAudioPlayer *audioPlayDONG;
-
 @property (nonatomic, assign) int currentNo;
 
 @property (nonatomic, assign) NSInteger totalNoCount;
 
 @property (nonatomic, assign) float playVolume;
 
+@property (nonatomic, strong) KSMetronomePlayer *nodePlayer;
+
 @end
 
 @implementation WidgetViewController
@@ -62,11 +59,16 @@
     [self setDefaultConfig];
 }
 
+- (void)backAction {
+    [self removeAll];
+    [self.navigationController popViewControllerAnimated:YES];
+}
+
 - (void)setDefaultConfig {
     self.speed = 90;
     self.playVolume = 1.0f;
     [self updateSpeedUI];
-    self.metronomeType = KSMetronomeType4V4;
+    self.metronomeType = KSWidgeMetronomeType4V4;
     [self changeBeat];
     self.functionView.volumeRate = 1.0f;
 }
@@ -115,15 +117,14 @@
 #pragma mark --- delegate
 - (void)volumeChange:(float)volume {
     self.playVolume = volume;
-    [self.audioPlayDONG setVolume:volume];
-    [self.audioPlayDI setVolume:volume];
+    self.nodePlayer.volume = volume;
 }
 
 - (void)clickChangeBeat {
     // 显示节拍选择弹窗
     MJWeakSelf;
     self.pickerView = [[KSChoosePicker alloc] initWithTitle:@"节拍" sourceData:@[@"1/2",@"2/2",@"1/4",@"2/4",@"3/4",@"4/4",@"3/8",@"6/8"] chooseReturnWithBlock:^(NSString * _Nonnull returnValue, NSInteger chooseIndex) {
-        KSMetronomeType type = chooseIndex;
+        KSWidgeMetronomeType type = chooseIndex;
         weakSelf.metronomeType = type;
         [weakSelf changeBeat];
     } cancel:^{
@@ -140,7 +141,7 @@
 
 - (void)changeSpeedWithIsAdd:(BOOL)isAdd speed:(int)speed {
     if (isAdd) {
-        self.speed = MIN(self.speed +speed, 240);
+        self.speed = MIN(self.speed +speed, 200);
     }else{
         self.speed = MAX(self.speed -speed, 50);
     }
@@ -206,12 +207,18 @@
 }
 
 - (void)playBeat {
+    // 重置
+    self.currentNo = -1;
     // 开始播放
     [self.timer setFireDate:[NSDate distantPast]];
+    [self.nodePlayer playAction:self.speed metronomeTyle:self.metronomeType];
+    
 }
 
 - (void)stopBeat {
     [self.timer setFireDate:[NSDate distantFuture]];//暂停计时器
+    [self.nodePlayer stopPlay];
+    self.currentNo = -1;
 }
 
 
@@ -219,6 +226,7 @@
     [self.dotView updateSpotView:self.metronomeType];
     self.functionView.currentMetronomeType = self.metronomeType;
     self.speedView.currentType = self.metronomeType;
+    
 }
 
 
@@ -228,36 +236,13 @@
     self.timerLength = 1 / (rateFloat / 60);
 }
 
-- (AVAudioPlayer *)audioPlayDI{
-    
-    if (!_audioPlayDI) {
-        
-        NSString *soundPath = [[NSBundle mainBundle]pathForResource:@"tick" ofType:@"wav"];
-        NSURL *soundUrl = [NSURL fileURLWithPath:soundPath];
-        //        初始化播放器对象
-        self.audioPlayDI = [[AVAudioPlayer alloc]initWithContentsOfURL:soundUrl error:nil];
-        //        设置循环次数,如果为负数,就是无限循环
-        self.audioPlayDI.numberOfLoops = 0;
-        //        是否可以更改播放速率
-        //        self.audioPlay.enableRate = YES;
-        
+- (KSMetronomePlayer *)nodePlayer {
+    if (!_nodePlayer) {
+        _nodePlayer = [[KSMetronomePlayer alloc] init];
     }
-    
-    return _audioPlayDI;
+    return _nodePlayer;
 }
 
-- (AVAudioPlayer *)audioPlayDONG{
-    
-    if (!_audioPlayDONG) {
-        
-        NSString *soundPath = [[NSBundle mainBundle]pathForResource:@"tock" ofType:@"wav"];
-        NSURL *soundUrl = [NSURL fileURLWithPath:soundPath];
-        self.audioPlayDONG = [[AVAudioPlayer alloc]initWithContentsOfURL:soundUrl error:nil];
-        self.audioPlayDONG.numberOfLoops = 0;
-        
-    }
-    return _audioPlayDONG;
-}
 
 - (NSTimer *)timer{
     
@@ -270,34 +255,6 @@
 
 - (void)timerAction {
     
-    
-    if (_metronomeType == KSMetronomeType1V2 || _metronomeType == KSMetronomeType1V4) {
-        [self.audioPlayDI play];
-//        [self.audioPlayDONG stop];
-    }
-    else {
-        
-        if (_metronomeType == KSMetronomeType2V4 && self.currentNo %2 == 0) {
-            [self.audioPlayDI play];
-//            [self.audioPlayDONG stop];
-        }else if (_metronomeType == KSMetronomeType3V4 && self.currentNo %3 == 0){
-            [self.audioPlayDI play];
-//            [self.audioPlayDONG stop];
-        }else if (_metronomeType == KSMetronomeType4V4 && self.currentNo %4 == 0){
-            [self.audioPlayDI play];
-//            [self.audioPlayDONG stop];
-        }else if (_metronomeType == KSMetronomeType3V8 && self.currentNo %3 == 0){
-            [self.audioPlayDI play];
-//            [self.audioPlayDONG stop];
-        }else if (_metronomeType == KSMetronomeType6V8 && self.currentNo %6 == 0){
-            [self.audioPlayDI play];
-//            [self.audioPlayDONG stop];
-        }else{
-//            [self.audioPlayDI stop];
-            [self.audioPlayDONG play];
-        }
-    }
-    
     [self.dotView updateSpotViewHeightState:self.currentNo];
     self.currentNo++;
 }
@@ -317,16 +274,9 @@
         [_timer invalidate];
         _timer = nil;
     }
-    
-    if (_audioPlayDI) {
-        _audioPlayDI = nil;
-    }
-    
-    if (_audioPlayDONG) {
-        _audioPlayDONG = nil;
-    }
 }
 - (void)dealloc {
+    NSLog(@"----dealloc ");
     [self removeAll];
 }
 /*

+ 24 - 0
KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/KSMetronomePlayer.h

@@ -0,0 +1,24 @@
+//
+//  KSMetronomePlayer.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/9/20.
+//
+
+#import <Foundation/Foundation.h>
+#import "WidgetDotView.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSMetronomePlayer : NSObject
+
+@property (nonatomic, assign) float volume;
+
+- (void)playAction:(int)bpm metronomeTyle:(KSWidgeMetronomeType)type;
+
+- (void)stopPlay;
+
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 170 - 0
KulexiuForStudent/KulexiuForStudent/Module/Widget/Model/KSMetronomePlayer.m

@@ -0,0 +1,170 @@
+//
+//  KSMetronomePlayer.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/9/20.
+//
+
+#import "KSMetronomePlayer.h"
+#import <AVFoundation/AVFoundation.h>
+
+@interface KSMetronomePlayer ()
+
+@property (nonatomic, strong) AVAudioPlayerNode *playerNode;
+
+@property (nonatomic, strong) AVAudioEngine *audioEngine;
+
+@property (nonatomic, strong) AVAudioFile *audioDIFile;
+
+@property (nonatomic, strong) AVAudioFile *audioDongFile;
+
+@property(nonatomic, assign) BOOL isPlaying;
+
+@end
+
+@implementation KSMetronomePlayer
+
+- (instancetype)init {
+    self = [super init];
+    if (self) {
+        [self configEngine];
+    }
+    return self;
+}
+
+
+- (void)configEngine {
+    NSString *tickPath = [[NSBundle mainBundle]pathForResource:@"tick" ofType:@"wav"];
+    NSURL *tickUrl = [NSURL fileURLWithPath:tickPath];
+    self.audioDIFile = [[AVAudioFile alloc] initForReading:tickUrl error:nil];
+    
+    NSString *tockPath = [[NSBundle mainBundle]pathForResource:@"tock" ofType:@"wav"];
+    NSURL *tockUrl = [NSURL fileURLWithPath:tockPath];
+    self.audioDongFile = [[AVAudioFile alloc] initForReading:tockUrl error:nil];
+    self.playerNode = [[AVAudioPlayerNode alloc] init];
+    self.audioEngine = [[AVAudioEngine alloc] init];
+    [self.audioEngine attachNode:self.playerNode];
+    
+    [self.audioEngine connect:self.playerNode to:self.audioEngine.mainMixerNode format:self.audioDIFile.processingFormat];
+    [self.audioEngine startAndReturnError:nil];
+}
+
+- (AVAudioPCMBuffer *)generateBuffer:(int)bmp metronomeType:(KSWidgeMetronomeType)type {
+    self.audioDIFile.framePosition = 0;
+    self.audioDongFile.framePosition = 0;
+    
+    AVAudioFrameCount beatLength = self.audioDIFile.processingFormat.sampleRate * 60 / bmp;
+    
+    AVAudioPCMBuffer *dingBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:self.audioDIFile.processingFormat frameCapacity:beatLength];
+    [self.audioDIFile readIntoBuffer:dingBuffer error:nil];
+    dingBuffer.frameLength = beatLength;
+    
+    AVAudioPCMBuffer *dongBuffer = [[AVAudioPCMBuffer alloc] initWithPCMFormat:self.audioDIFile.processingFormat frameCapacity:beatLength];
+    [self.audioDongFile readIntoBuffer:dongBuffer error:nil];
+    dongBuffer.frameLength = beatLength;
+    
+    int totalCount = [self getTotalCountFrame:type];
+    AVAudioPCMBuffer *bufferBar = [[AVAudioPCMBuffer alloc] initWithPCMFormat:self.audioDIFile.processingFormat frameCapacity:totalCount * beatLength];
+    bufferBar.frameLength = totalCount * beatLength;
+    
+    int channerCount = (int)self.audioDIFile.processingFormat.channelCount;
+    
+    NSMutableArray *dingClickArray = [NSMutableArray array];
+    NSMutableArray *dongClickArray = [NSMutableArray array];
+    
+    for (int i = 0 ; i < channerCount *(int)beatLength; i++) {
+        double temp = *(dongBuffer.floatChannelData[0]+i);
+        double tempMain = *(dingBuffer.floatChannelData[0]+i);
+        [dingClickArray addObject:@(tempMain)];
+        [dongClickArray addObject:@(temp)];
+    }
+    
+    NSMutableArray *barArray = [NSMutableArray array];
+    
+    [barArray addObjectsFromArray:dingClickArray];
+    NSInteger dongCount = [self getDongCount:type];
+    for (int i = 0; i < dongCount; i++) {
+        [barArray addObjectsFromArray:dongClickArray];
+    }
+    for (NSInteger i = 0; i < channerCount * bufferBar.frameLength; i++) {
+        double temp = 0;
+        if (i < barArray.count) {
+            temp = [barArray[i] doubleValue];
+        }
+        *(bufferBar.floatChannelData[0]+i) = temp;
+    }
+
+    return bufferBar;
+}
+
+- (int)getTotalCountFrame:(KSWidgeMetronomeType)type {
+    switch (type) {
+        case KSWidgeMetronomeType1V2:
+            return 1;
+        case KSWidgeMetronomeType2V2:
+            return 2;
+        case KSWidgeMetronomeType1V4:
+            return 1;
+        case KSWidgeMetronomeType2V4:
+            return 2;
+        case KSWidgeMetronomeType3V4:
+            return 3;
+        case KSWidgeMetronomeType4V4:
+            return 4;
+        case KSWidgeMetronomeType3V8:
+            return 3;
+        case KSWidgeMetronomeType6V8:
+            return 6;
+        default:
+            return 4;
+            break;
+    }
+}
+
+- (int)getDongCount:(KSWidgeMetronomeType)type {
+    if (type == KSWidgeMetronomeType1V2) {
+        return 0;
+    }
+    else if (type == KSWidgeMetronomeType2V2) {
+        return 1;
+    }
+    else if (type == KSWidgeMetronomeType1V4) {
+        return 0;
+    }
+    else if (type == KSWidgeMetronomeType2V4) {
+        return 1;
+    }
+    else if (type == KSWidgeMetronomeType3V4) {
+        return 2;
+    }
+    else if (type == KSWidgeMetronomeType4V4) {
+        return 3;
+    }
+    else if (type == KSWidgeMetronomeType3V8) {
+        return 2;
+    }
+    else {
+        return 5;
+    }
+}
+
+- (void)playAction:(int)bpm metronomeTyle:(KSWidgeMetronomeType)type {
+    AVAudioPCMBuffer *buffer = [self generateBuffer:bpm metronomeType:type];
+    if (self.playerNode.isPlaying) {
+        [self.playerNode scheduleBuffer:buffer atTime:nil options:AVAudioPlayerNodeBufferLoops completionHandler:nil];
+    }else{
+        [self.playerNode play];
+    }
+    
+    [self.playerNode scheduleBuffer:buffer atTime:nil options:AVAudioPlayerNodeBufferLoops completionHandler:nil];
+}
+
+- (void)stopPlay {
+    [self.playerNode stop];
+}
+
+- (void)setVolume:(float)volume {
+    self.playerNode.volume = volume;
+}
+
+@end

+ 10 - 10
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetDotView.h

@@ -8,15 +8,15 @@
 #import <UIKit/UIKit.h>
 
 // 节拍器节拍选择
-typedef NS_ENUM(NSInteger, KSMetronomeType) {
-    KSMetronomeType1V2 = 0,    // 1/2
-    KSMetronomeType2V2,        // 2/2
-    KSMetronomeType1V4,        // 1/4
-    KSMetronomeType2V4,        // 2/4
-    KSMetronomeType3V4,        // 3/4
-    KSMetronomeType4V4,        // 4/4
-    KSMetronomeType3V8,        // 3/8
-    KSMetronomeType6V8         // 6/8
+typedef NS_ENUM(NSInteger, KSWidgeMetronomeType) {
+    KSWidgeMetronomeType1V2 = 0,    // 1/2
+    KSWidgeMetronomeType2V2,        // 2/2
+    KSWidgeMetronomeType1V4,        // 1/4
+    KSWidgeMetronomeType2V4,        // 2/4
+    KSWidgeMetronomeType3V4,        // 3/4
+    KSWidgeMetronomeType4V4,        // 4/4
+    KSWidgeMetronomeType3V8,        // 3/8
+    KSWidgeMetronomeType6V8         // 6/8
 };
 
 
@@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN
 + (instancetype)shareInstance;
 
 /** 更新当前点View(显示几个点) */
-- (void)updateSpotView:(KSMetronomeType)metronomeStat;
+- (void)updateSpotView:(KSWidgeMetronomeType)metronomeType;
 
 /**
  更新某个点闪烁

+ 75 - 68
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetDotView.m

@@ -7,11 +7,11 @@
 
 #import "WidgetDotView.h"
 
-#define SPOT_WHDTH (24)
+#define SPOT_WHDTH (21)
 
 @interface WidgetDotView ()
 
-@property (nonatomic, assign) KSMetronomeType currentMetronomeType;
+@property (nonatomic, assign) KSWidgeMetronomeType currentMetronomeType;
 
 @end
 
@@ -23,35 +23,33 @@
     return view;
 }
 
-- (void)createUI {
-    
-}
-
 
 - (void)updateSpotViewHeightState:(int)currentTotalNo {
     //    当前圆个数
     int spotNo;
     
-    if (self.currentMetronomeType == KSMetronomeType1V4) {
+    if (self.currentMetronomeType == KSWidgeMetronomeType1V4) {
         spotNo = 1;
-    }else if (self.currentMetronomeType == KSMetronomeType2V4){
+    }else if (self.currentMetronomeType == KSWidgeMetronomeType2V4){
         spotNo = 2;
-    }else if (self.currentMetronomeType == KSMetronomeType3V4){
+    }else if (self.currentMetronomeType == KSWidgeMetronomeType3V4){
         spotNo = 3;
-    }else if (self.currentMetronomeType == KSMetronomeType4V4){
+    }else if (self.currentMetronomeType == KSWidgeMetronomeType4V4){
         spotNo = 4;
     }else{
         spotNo = 6;
     }
     
     UIImageView *currentImageView = [self viewWithTag:currentTotalNo % spotNo +100];
-    currentImageView.highlighted = YES;
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-        currentImageView.highlighted = NO;
-    });
+    if (currentImageView) {
+        currentImageView.highlighted = YES;
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+            currentImageView.highlighted = NO;
+        });
+    }
 }
 
-- (void)updateSpotView:(KSMetronomeType)metronomeStat {
+- (void)updateSpotView:(KSWidgeMetronomeType)metronomeStat {
     
     self.currentMetronomeType = metronomeStat;
     [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
@@ -59,26 +57,29 @@
     [self creatSpotImageView:metronomeStat];
 }
 
-- (void)creatSpotImageView:(KSMetronomeType)metronomeStat {
-    if (metronomeStat == KSMetronomeType1V2) {
+- (void)creatSpotImageView:(KSWidgeMetronomeType)metronomeType {
+    CGFloat dotSpace = 8.0f;
+    if (metronomeType == KSWidgeMetronomeType1V2) {
         UIImageView *spotView = [self creatSpotImageView];
         spotView.tag = 100;
+        spotView.highlighted = YES;
         [self addSubview:spotView];
         [spotView mas_makeConstraints:^(MASConstraintMaker *make) {
             make.centerX.mas_equalTo(self.mas_centerX);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
     }
-    else if (metronomeStat == KSMetronomeType2V2) {
-        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 2) / 3;
+    else if (metronomeType == KSWidgeMetronomeType2V2) {
+        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 2 - dotSpace) / 2;
         
         UIImageView *spotView = [self creatSpotImageView];
         spotView.tag = 100;
+        spotView.highlighted = YES;
         [self addSubview:spotView];
         [spotView mas_makeConstraints:^(MASConstraintMaker *make) {
             make.left.mas_equalTo(self.mas_left).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -86,30 +87,32 @@
         spotView1.tag = 101;
         [self addSubview:spotView1];
         [spotView1 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView.mas_right).offset(xSpace);
-            make.centerY.mas_equalTo(0);
+            make.left.mas_equalTo(spotView.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
     }
-    else if (metronomeStat == KSMetronomeType1V4) {
+    else if (metronomeType == KSWidgeMetronomeType1V4) {
         UIImageView *spotView = [self creatSpotImageView];
         spotView.tag = 100;
+        spotView.highlighted = YES;
         [self addSubview:spotView];
         [spotView mas_makeConstraints:^(MASConstraintMaker *make) {
             make.centerX.mas_equalTo(self.mas_centerX);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
     }
-    else if (metronomeStat == KSMetronomeType2V4) {
-        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 2) / 3;
+    else if (metronomeType == KSWidgeMetronomeType2V4) {
+        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 2 - dotSpace) / 2;
         
         UIImageView *spotView = [self creatSpotImageView];
         spotView.tag = 100;
+        spotView.highlighted = YES;
         [self addSubview:spotView];
         [spotView mas_makeConstraints:^(MASConstraintMaker *make) {
             make.left.mas_equalTo(self.mas_left).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -117,19 +120,20 @@
         spotView1.tag = 101;
         [self addSubview:spotView1];
         [spotView1 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView.mas_right).offset(xSpace);
-            make.centerY.mas_equalTo(0);
+            make.left.mas_equalTo(spotView.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
     }
-    else if (metronomeStat == KSMetronomeType3V4) {
-        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 3) / 4;
+    else if (metronomeType == KSWidgeMetronomeType3V4) {
+        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 3 - dotSpace * 2) / 2;
         UIImageView *spotView = [self creatSpotImageView];
         spotView.tag = 100;
+        spotView.highlighted = YES;
         [self addSubview:spotView];
         [spotView mas_makeConstraints:^(MASConstraintMaker *make) {
             make.left.mas_equalTo(self.mas_left).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -137,8 +141,8 @@
         spotView1.tag = 101;
         [self addSubview:spotView1];
         [spotView1 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -146,19 +150,20 @@
         spotView2.tag = 102;
         [self addSubview:spotView2];
         [spotView2 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView1.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView1.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
     }
-    else if (metronomeStat == KSMetronomeType4V4) {
-        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 4) / 5;
+    else if (metronomeType == KSWidgeMetronomeType4V4) {
+        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 4 -  dotSpace * 3) / 2;
         UIImageView *spotView = [self creatSpotImageView];
         spotView.tag = 100;
+        spotView.highlighted = YES;
         [self addSubview:spotView];
         [spotView mas_makeConstraints:^(MASConstraintMaker *make) {
             make.left.mas_equalTo(self.mas_left).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -166,8 +171,8 @@
         spotView1.tag = 101;
         [self addSubview:spotView1];
         [spotView1 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -175,8 +180,8 @@
         spotView2.tag = 102;
         [self addSubview:spotView2];
         [spotView2 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView1.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView1.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -184,19 +189,20 @@
         spotView3.tag = 103;
         [self addSubview:spotView3];
         [spotView3 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView2.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView2.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
     }
-    else if (metronomeStat == KSMetronomeType3V8) {
-        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 3) / 4;
+    else if (metronomeType == KSWidgeMetronomeType3V8) {
+        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 3 - dotSpace * 2) / 2;
         UIImageView *spotView = [self creatSpotImageView];
+        spotView.highlighted = YES;
         spotView.tag = 100;
         [self addSubview:spotView];
         [spotView mas_makeConstraints:^(MASConstraintMaker *make) {
             make.left.mas_equalTo(self.mas_left).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -204,8 +210,8 @@
         spotView1.tag = 101;
         [self addSubview:spotView1];
         [spotView1 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -213,19 +219,20 @@
         spotView2.tag = 102;
         [self addSubview:spotView2];
         [spotView2 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView1.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView1.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
     }
-    else if (metronomeStat == KSMetronomeType6V8) {
-        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 6) / 7;
+    else if (metronomeType == KSWidgeMetronomeType6V8) {
+        CGFloat xSpace = (KPortraitWidth - SPOT_WHDTH * 6 - dotSpace * 5) / 2;
         UIImageView *spotView = [self creatSpotImageView];
         spotView.tag = 100;
+        spotView.highlighted = YES;
         [self addSubview:spotView];
         [spotView mas_makeConstraints:^(MASConstraintMaker *make) {
             make.left.mas_equalTo(self.mas_left).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -233,8 +240,8 @@
         spotView1.tag = 101;
         [self addSubview:spotView1];
         [spotView1 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -242,8 +249,8 @@
         spotView2.tag = 102;
         [self addSubview:spotView2];
         [spotView2 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView1.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView1.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -251,8 +258,8 @@
         spotView3.tag = 103;
         [self addSubview:spotView3];
         [spotView3 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView2.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView2.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -260,8 +267,8 @@
         spotView4.tag = 104;
         [self addSubview:spotView4];
         [spotView4 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView3.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView3.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
         
@@ -269,17 +276,17 @@
         spotView5.tag = 105;
         [self addSubview:spotView5];
         [spotView5 mas_makeConstraints:^(MASConstraintMaker *make) {
-            make.left.mas_equalTo(spotView4.mas_right).offset(xSpace);
-            make.bottom.mas_equalTo(self.mas_bottom).offset(-12);
+            make.left.mas_equalTo(spotView4.mas_right).offset(dotSpace);
+            make.centerY.mas_equalTo(self.mas_centerY);
             make.width.height.mas_equalTo(SPOT_WHDTH);
         }];
     }
 }
 
 #pragma mark -- 创建大圆View
-- (UIImageView *)creatSpotImageView{
+- (UIImageView *)creatSpotImageView {
     
-    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"metro_whiteSpot"] highlightedImage:[UIImage imageNamed:@"metro_hightSpot"]];
+    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"metro_bigWhiteSpot"] highlightedImage:[UIImage imageNamed:@"metro_bigHightSpot"]];
     return imageView;
 }
 

+ 1 - 1
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetFunctionView.h

@@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
 
 @interface WidgetFunctionView : UIView
 
-@property (nonatomic, assign) KSMetronomeType currentMetronomeType;
+@property (nonatomic, assign) KSWidgeMetronomeType currentMetronomeType;
 
 @property (nonatomic, assign) int speed;
 

+ 11 - 11
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetFunctionView.m

@@ -56,10 +56,10 @@
 
 
 - (IBAction)onAddButtonClick:(id)sender {
-    if (self.speed < 240) {
+    if (self.speed < 200) {
         self.speed ++;
     }else{
-        self.speed = 240;
+        self.speed = 200;
     }
     [self updateSpeed];
 }
@@ -71,45 +71,45 @@
     }
 }
 
-- (void)setCurrentMetronomeType:(KSMetronomeType)currentMetronomeType {
+- (void)setCurrentMetronomeType:(KSWidgeMetronomeType)currentMetronomeType {
     _currentMetronomeType = currentMetronomeType;
     switch (currentMetronomeType) {
-        case KSMetronomeType1V2:
+        case KSWidgeMetronomeType1V2:
         {
             [self.signatureButton setTitle:@"1/2" forState:UIControlStateNormal];
         }
             break;
-        case KSMetronomeType2V2:
+        case KSWidgeMetronomeType2V2:
         {
             [self.signatureButton setTitle:@"2/2" forState:UIControlStateNormal];
         }
             break;
-        case KSMetronomeType1V4:
+        case KSWidgeMetronomeType1V4:
         {
             [self.signatureButton setTitle:@"1/4" forState:UIControlStateNormal];
         }
             break;
-        case KSMetronomeType2V4:
+        case KSWidgeMetronomeType2V4:
         {
             [self.signatureButton setTitle:@"2/4" forState:UIControlStateNormal];
         }
             break;
-        case KSMetronomeType3V4:
+        case KSWidgeMetronomeType3V4:
         {
             [self.signatureButton setTitle:@"3/4" forState:UIControlStateNormal];
         }
             break;
-        case KSMetronomeType4V4:
+        case KSWidgeMetronomeType4V4:
         {
             [self.signatureButton setTitle:@"4/4" forState:UIControlStateNormal];
         }
             break;
-        case KSMetronomeType3V8:
+        case KSWidgeMetronomeType3V8:
         {
             [self.signatureButton setTitle:@"3/8" forState:UIControlStateNormal];
         }
             break;
-        case KSMetronomeType6V8:
+        case KSWidgeMetronomeType6V8:
         {
             [self.signatureButton setTitle:@"6/8" forState:UIControlStateNormal];
         }

+ 2 - 2
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetSpeedView.h

@@ -28,12 +28,12 @@ NS_ASSUME_NONNULL_BEGIN
 + (instancetype)shareInstance;
 
 /** 节拍类型 */
-@property (nonatomic, assign) KSMetronomeType currentType;
+@property (nonatomic, assign) KSWidgeMetronomeType currentType;
 
 /** 代理 */
 @property (nonatomic, weak) id <MetronomeControlViewDelegate> delegate;
 
-/** 播放速率,范围50~240 */
+/** 播放速率,范围50~200 */
 @property (nonatomic, assign) int speed;
 
 @end

+ 9 - 9
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/WidgetSpeedView.m

@@ -98,25 +98,25 @@
 }
 
 
-- (void)setCurrentType:(KSMetronomeType)currentType {
+- (void)setCurrentType:(KSWidgeMetronomeType)currentType {
     _currentType = currentType;
     switch (currentType) {
-        case KSMetronomeType1V2:
-        case KSMetronomeType2V2:
+        case KSWidgeMetronomeType1V2:
+        case KSWidgeMetronomeType2V2:
         {
             [self.nodeImage setImage:[UIImage imageNamed:@"half_node"]];
         }
             break;
-        case KSMetronomeType1V4:
-        case KSMetronomeType2V4:
-        case KSMetronomeType3V4:
-        case KSMetronomeType4V4:
+        case KSWidgeMetronomeType1V4:
+        case KSWidgeMetronomeType2V4:
+        case KSWidgeMetronomeType3V4:
+        case KSWidgeMetronomeType4V4:
         {
             [self.nodeImage setImage:[UIImage imageNamed:@"quarter_node"]];
         }
             break;
-        case KSMetronomeType3V8:
-        case KSMetronomeType6V8:
+        case KSWidgeMetronomeType3V8:
+        case KSWidgeMetronomeType6V8:
         {
             [self.nodeImage setImage:[UIImage imageNamed:@"eighth_node"]];
         }