Browse Source

首页推荐课程

Steven 3 years ago
parent
commit
bccf1fd346
100 changed files with 6340 additions and 22 deletions
  1. 242 4
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. BIN
      KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/UserInterfaceState.xcuserstate
  3. 32 0
      KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  4. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Course/nav_shade.imageset/Contents.json
  5. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Course/nav_shade.imageset/nav_shade@2x.png
  6. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Course/nav_shade.imageset/nav_shade@3x.png
  7. 6 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/Contents.json
  8. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/homeCourse_notice.imageset/Contents.json
  9. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/homeCourse_notice.imageset/homeCourse_notice@2x.png
  10. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/homeCourse_notice.imageset/homeCourse_notice@3x.png
  11. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_message.imageset/Contents.json
  12. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_message.imageset/home_message@2x.png
  13. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_message.imageset/home_message@3x.png
  14. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_more.imageset/Contents.json
  15. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_more.imageset/home_more@2x.png
  16. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_more.imageset/home_more@3x.png
  17. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_radainLine.imageset/Contents.json
  18. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_radainLine.imageset/home_radainLine@2x.png
  19. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/home_radainLine.imageset/home_radainLine@3x.png
  20. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/introduce_play.imageset/Contents.json
  21. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/introduce_play.imageset/introduce_play@2x.png
  22. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/introduce_play.imageset/introduce_play@3x.png
  23. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/nav_down.imageset/Contents.json
  24. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/nav_down.imageset/nav_down@2x.png
  25. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/nav_down.imageset/nav_down@3x.png
  26. 19 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.h
  27. 29 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.m
  28. 74 0
      KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYCyclePagerTransformLayout.h
  29. 300 0
      KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYCyclePagerTransformLayout.m
  30. 180 0
      KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYCyclePagerView.h
  31. 607 0
      KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYCyclePagerView.m
  32. 47 0
      KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYPageControl.h
  33. 285 0
      KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYPageControl.m
  34. 2 0
      KulexiuForStudent/KulexiuForStudent/Common/Tools/KSVideoHelper.h
  35. 6 0
      KulexiuForStudent/KulexiuForStudent/Common/Tools/KSVideoHelper.m
  36. 15 7
      KulexiuForStudent/KulexiuForStudent/Module/Course/View/CourseNavView.xib
  37. 955 6
      KulexiuForStudent/KulexiuForStudent/Module/Home/Controller/HomeViewController.m
  38. 28 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/Model/HomeLiveGroupModel.h
  39. 151 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/Model/HomeLiveGroupModel.m
  40. 30 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/Model/HomeVideoGroupModel.h
  41. 165 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/Model/HomeVideoGroupModel.m
  42. 29 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/Model/TeacherStyleModel.h
  43. 162 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/Model/TeacherStyleModel.m
  44. 16 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Controller/NoticeMessageViewController.h
  45. 31 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Controller/NoticeMessageViewController.m
  46. 28 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Model/HomeMessageModel.h
  47. 154 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Model/HomeMessageModel.m
  48. 20 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerCell.h
  49. 27 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerCell.m
  50. 44 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerCell.xib
  51. 22 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerView.h
  52. 29 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerView.m
  53. 37 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerView.xib
  54. 30 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeButtonView.h
  55. 28 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeButtonView.m
  56. 77 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeButtonView.xib
  57. 31 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeCourseTipsView.h
  58. 58 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeCourseTipsView.m
  59. 135 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeCourseTipsView.xib
  60. 18 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumCell.h
  61. 27 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumCell.m
  62. 100 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumCell.xib
  63. 26 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumView.h
  64. 48 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumView.m
  65. 82 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumView.xib
  66. 32 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotCourseView.h
  67. 91 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotCourseView.m
  68. 145 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotCourseView.xib
  69. 26 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeInformationCell.h
  70. 63 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeInformationCell.m
  71. 86 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeInformationCell.xib
  72. 26 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeIntroduceView.h
  73. 50 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeIntroduceView.m
  74. 80 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeIntroduceView.xib
  75. 19 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeLiveCouseCell.h
  76. 62 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeLiveCouseCell.m
  77. 155 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeLiveCouseCell.xib
  78. 31 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.h
  79. 47 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.m
  80. 93 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.xib
  81. 19 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeVideoCourseCell.h
  82. 49 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeVideoCourseCell.m
  83. 144 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeVideoCourseCell.xib
  84. 22 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HotInformationHeadView.h
  85. 47 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HotInformationHeadView.m
  86. 69 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HotInformationHeadView.xib
  87. 25 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/KSHomeButton.h
  88. 26 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/KSHomeButton.m
  89. 63 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/KSHomeButton.xib
  90. 22 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/TeacherShowCell.h
  91. 75 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/TeacherShowCell.m
  92. 161 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/TeacherShowCell.xib
  93. 4 0
      KulexiuForStudent/KulexiuForStudent/Module/Login/Controller/SubjectChooseViewController.h
  94. 11 0
      KulexiuForStudent/KulexiuForStudent/Module/Login/Controller/SubjectChooseViewController.m
  95. 1 0
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Model/StudentInfoModel.h
  96. 8 3
      KulexiuForStudent/KulexiuForStudent/Module/Mine/Model/StudentInfoModel.m
  97. 2 2
      KulexiuForStudent/KulexiuForStudent/Module/Mine/View/MineBodyView.xib
  98. BIN
      KulexiuForStudent/build/Debug-iphonesimulator/KulexiuForStudent.app/Assets.car
  99. BIN
      KulexiuForStudent/build/Debug-iphonesimulator/KulexiuForStudent.app/Info.plist
  100. BIN
      KulexiuForStudent/build/Debug-iphonesimulator/KulexiuForStudent.app/KulexiuForStudent

+ 242 - 4
KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj

@@ -423,6 +423,21 @@
 		BC27A076280FF61300F91E27 /* AccompanyDetailBottomView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC27A075280FF61300F91E27 /* AccompanyDetailBottomView.xib */; };
 		BC27A079280FFA2200F91E27 /* EvaluateDetailModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC27A078280FFA2200F91E27 /* EvaluateDetailModel.m */; };
 		BC28582B2809036D0024697C /* StudentInfoModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC28582A2809036D0024697C /* StudentInfoModel.m */; };
+		BC40B9F82811767A00DEC0D1 /* HotInformationHeadView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40B9F72811767A00DEC0D1 /* HotInformationHeadView.m */; };
+		BC40B9FA2811768400DEC0D1 /* HotInformationHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC40B9F92811768400DEC0D1 /* HotInformationHeadView.xib */; };
+		BC40B9FE281177BD00DEC0D1 /* HomeInformationCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40B9FC281177BD00DEC0D1 /* HomeInformationCell.m */; };
+		BC40B9FF281177BD00DEC0D1 /* HomeInformationCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC40B9FD281177BD00DEC0D1 /* HomeInformationCell.xib */; };
+		BC40BA0328117B0A00DEC0D1 /* HomeBannerCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40BA0128117B0A00DEC0D1 /* HomeBannerCell.m */; };
+		BC40BA0428117B0A00DEC0D1 /* HomeBannerCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC40BA0228117B0A00DEC0D1 /* HomeBannerCell.xib */; };
+		BC40BA0C28117B3B00DEC0D1 /* TYPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40BA0828117B3A00DEC0D1 /* TYPageControl.m */; };
+		BC40BA0D28117B3B00DEC0D1 /* TYCyclePagerView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40BA0928117B3A00DEC0D1 /* TYCyclePagerView.m */; };
+		BC40BA0E28117B3B00DEC0D1 /* TYCyclePagerTransformLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40BA0A28117B3A00DEC0D1 /* TYCyclePagerTransformLayout.m */; };
+		BC40BA1828124D3D00DEC0D1 /* NoticeMessageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40BA1728124D3D00DEC0D1 /* NoticeMessageViewController.m */; };
+		BC40BA1B281251ED00DEC0D1 /* HomeMessageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40BA1A281251ED00DEC0D1 /* HomeMessageModel.m */; };
+		BC40BA1F2812552300DEC0D1 /* KSHomeButton.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40BA1C2812552200DEC0D1 /* KSHomeButton.m */; };
+		BC40BA202812552300DEC0D1 /* KSHomeButton.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC40BA1D2812552200DEC0D1 /* KSHomeButton.xib */; };
+		BC40BA23281255F700DEC0D1 /* HomeCourseTipsView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC40BA22281255F700DEC0D1 /* HomeCourseTipsView.m */; };
+		BC40BA252812560100DEC0D1 /* HomeCourseTipsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC40BA242812560100DEC0D1 /* HomeCourseTipsView.xib */; };
 		BC50171227FC0D5600F8BCBC /* SubjectChooseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC50171127FC0D5600F8BCBC /* SubjectChooseViewController.m */; };
 		BC50171527FC0D8300F8BCBC /* SubjectChooseBodyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC50171427FC0D8300F8BCBC /* SubjectChooseBodyView.m */; };
 		BC50171727FC0D8E00F8BCBC /* SubjectChooseBodyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC50171627FC0D8D00F8BCBC /* SubjectChooseBodyView.xib */; };
@@ -543,6 +558,29 @@
 		BCB635AE27F6E06500ACFDCF /* LiveRoomHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCB635AC27F6E06500ACFDCF /* LiveRoomHeadView.xib */; };
 		BCB635B227F6E1A600ACFDCF /* LiveRoomBottomView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCB635B027F6E1A600ACFDCF /* LiveRoomBottomView.m */; };
 		BCB635B327F6E1A600ACFDCF /* LiveRoomBottomView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCB635B127F6E1A600ACFDCF /* LiveRoomBottomView.xib */; };
+		BCBFDF3728110C660052AFE5 /* HomeNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCBFDF3628110C660052AFE5 /* HomeNavView.m */; };
+		BCBFDF3928110C6F0052AFE5 /* HomeNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCBFDF3828110C6F0052AFE5 /* HomeNavView.xib */; };
+		BCBFDF3C281156430052AFE5 /* HomeBannerView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCBFDF3B281156430052AFE5 /* HomeBannerView.m */; };
+		BCBFDF3E2811564C0052AFE5 /* HomeBannerView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCBFDF3D2811564C0052AFE5 /* HomeBannerView.xib */; };
+		BCBFDF41281157340052AFE5 /* HomeButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCBFDF40281157340052AFE5 /* HomeButtonView.m */; };
+		BCBFDF432811573D0052AFE5 /* HomeButtonView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCBFDF422811573D0052AFE5 /* HomeButtonView.xib */; };
+		BCBFDF46281159990052AFE5 /* HomeHotAlbumView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCBFDF45281159990052AFE5 /* HomeHotAlbumView.m */; };
+		BCBFDF48281159A40052AFE5 /* HomeHotAlbumView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCBFDF47281159A40052AFE5 /* HomeHotAlbumView.xib */; };
+		BCBFDF4B28115C6F0052AFE5 /* HomeHotCourseView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCBFDF4A28115C6F0052AFE5 /* HomeHotCourseView.m */; };
+		BCBFDF4D28115C7A0052AFE5 /* HomeHotCourseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCBFDF4C28115C7A0052AFE5 /* HomeHotCourseView.xib */; };
+		BCBFDF5028115D9A0052AFE5 /* HomeIntroduceView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCBFDF4F28115D9A0052AFE5 /* HomeIntroduceView.m */; };
+		BCBFDF5228115DA40052AFE5 /* HomeIntroduceView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCBFDF5128115DA40052AFE5 /* HomeIntroduceView.xib */; };
+		BCFE53E72812765600AD6786 /* HomeHotAlbumCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFE53E52812765600AD6786 /* HomeHotAlbumCell.m */; };
+		BCFE53E82812765600AD6786 /* HomeHotAlbumCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCFE53E62812765600AD6786 /* HomeHotAlbumCell.xib */; };
+		BCFE53EC2812897600AD6786 /* HomeLiveCouseCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFE53EA2812897600AD6786 /* HomeLiveCouseCell.m */; };
+		BCFE53ED2812897600AD6786 /* HomeLiveCouseCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCFE53EB2812897600AD6786 /* HomeLiveCouseCell.xib */; };
+		BCFE53F12812898700AD6786 /* HomeVideoCourseCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFE53EF2812898700AD6786 /* HomeVideoCourseCell.m */; };
+		BCFE53F22812898700AD6786 /* HomeVideoCourseCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCFE53F02812898700AD6786 /* HomeVideoCourseCell.xib */; };
+		BCFE53F628128A9600AD6786 /* TeacherShowCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFE53F428128A9600AD6786 /* TeacherShowCell.m */; };
+		BCFE53F728128A9600AD6786 /* TeacherShowCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCFE53F528128A9600AD6786 /* TeacherShowCell.xib */; };
+		BCFE53FA28129A5600AD6786 /* TeacherStyleModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFE53F828129A5500AD6786 /* TeacherStyleModel.m */; };
+		BCFE53FF2814E1BE00AD6786 /* HomeLiveGroupModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFE53FD2814E1BE00AD6786 /* HomeLiveGroupModel.m */; };
+		BCFE54002814E1BE00AD6786 /* HomeVideoGroupModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCFE53FE2814E1BE00AD6786 /* HomeVideoGroupModel.m */; };
 		C56C141D9D9D478077F14C1E /* Pods_KulexiuForStudent_KulexiuForStudentUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C170A749B6C49F17AC3246 /* Pods_KulexiuForStudent_KulexiuForStudentUITests.framework */; };
 /* End PBXBuildFile section */
 
@@ -1339,6 +1377,31 @@
 		BC27A078280FFA2200F91E27 /* EvaluateDetailModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EvaluateDetailModel.m; sourceTree = "<group>"; };
 		BC2858292809036C0024697C /* StudentInfoModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StudentInfoModel.h; sourceTree = "<group>"; };
 		BC28582A2809036D0024697C /* StudentInfoModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StudentInfoModel.m; sourceTree = "<group>"; };
+		BC40B9F62811767A00DEC0D1 /* HotInformationHeadView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HotInformationHeadView.h; sourceTree = "<group>"; };
+		BC40B9F72811767A00DEC0D1 /* HotInformationHeadView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HotInformationHeadView.m; sourceTree = "<group>"; };
+		BC40B9F92811768400DEC0D1 /* HotInformationHeadView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HotInformationHeadView.xib; sourceTree = "<group>"; };
+		BC40B9FB281177BD00DEC0D1 /* HomeInformationCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeInformationCell.h; sourceTree = "<group>"; };
+		BC40B9FC281177BD00DEC0D1 /* HomeInformationCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeInformationCell.m; sourceTree = "<group>"; };
+		BC40B9FD281177BD00DEC0D1 /* HomeInformationCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeInformationCell.xib; sourceTree = "<group>"; };
+		BC40BA0028117B0A00DEC0D1 /* HomeBannerCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeBannerCell.h; sourceTree = "<group>"; };
+		BC40BA0128117B0A00DEC0D1 /* HomeBannerCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeBannerCell.m; sourceTree = "<group>"; };
+		BC40BA0228117B0A00DEC0D1 /* HomeBannerCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeBannerCell.xib; sourceTree = "<group>"; };
+		BC40BA0628117B3A00DEC0D1 /* TYCyclePagerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYCyclePagerView.h; sourceTree = "<group>"; };
+		BC40BA0728117B3A00DEC0D1 /* TYCyclePagerTransformLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYCyclePagerTransformLayout.h; sourceTree = "<group>"; };
+		BC40BA0828117B3A00DEC0D1 /* TYPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYPageControl.m; sourceTree = "<group>"; };
+		BC40BA0928117B3A00DEC0D1 /* TYCyclePagerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYCyclePagerView.m; sourceTree = "<group>"; };
+		BC40BA0A28117B3A00DEC0D1 /* TYCyclePagerTransformLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYCyclePagerTransformLayout.m; sourceTree = "<group>"; };
+		BC40BA0B28117B3A00DEC0D1 /* TYPageControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYPageControl.h; sourceTree = "<group>"; };
+		BC40BA1628124D3D00DEC0D1 /* NoticeMessageViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NoticeMessageViewController.h; sourceTree = "<group>"; };
+		BC40BA1728124D3D00DEC0D1 /* NoticeMessageViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NoticeMessageViewController.m; sourceTree = "<group>"; };
+		BC40BA19281251EC00DEC0D1 /* HomeMessageModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeMessageModel.h; sourceTree = "<group>"; };
+		BC40BA1A281251ED00DEC0D1 /* HomeMessageModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeMessageModel.m; sourceTree = "<group>"; };
+		BC40BA1C2812552200DEC0D1 /* KSHomeButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSHomeButton.m; sourceTree = "<group>"; };
+		BC40BA1D2812552200DEC0D1 /* KSHomeButton.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSHomeButton.xib; sourceTree = "<group>"; };
+		BC40BA1E2812552300DEC0D1 /* KSHomeButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSHomeButton.h; sourceTree = "<group>"; };
+		BC40BA21281255F700DEC0D1 /* HomeCourseTipsView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeCourseTipsView.h; sourceTree = "<group>"; };
+		BC40BA22281255F700DEC0D1 /* HomeCourseTipsView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeCourseTipsView.m; sourceTree = "<group>"; };
+		BC40BA242812560100DEC0D1 /* HomeCourseTipsView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeCourseTipsView.xib; sourceTree = "<group>"; };
 		BC50171027FC0D5600F8BCBC /* SubjectChooseViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SubjectChooseViewController.h; sourceTree = "<group>"; };
 		BC50171127FC0D5600F8BCBC /* SubjectChooseViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SubjectChooseViewController.m; sourceTree = "<group>"; };
 		BC50171327FC0D8300F8BCBC /* SubjectChooseBodyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SubjectChooseBodyView.h; sourceTree = "<group>"; };
@@ -1573,6 +1636,42 @@
 		BCB635AF27F6E1A600ACFDCF /* LiveRoomBottomView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveRoomBottomView.h; sourceTree = "<group>"; };
 		BCB635B027F6E1A600ACFDCF /* LiveRoomBottomView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveRoomBottomView.m; sourceTree = "<group>"; };
 		BCB635B127F6E1A600ACFDCF /* LiveRoomBottomView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LiveRoomBottomView.xib; sourceTree = "<group>"; };
+		BCBFDF3528110C660052AFE5 /* HomeNavView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeNavView.h; sourceTree = "<group>"; };
+		BCBFDF3628110C660052AFE5 /* HomeNavView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeNavView.m; sourceTree = "<group>"; };
+		BCBFDF3828110C6F0052AFE5 /* HomeNavView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeNavView.xib; sourceTree = "<group>"; };
+		BCBFDF3A281156430052AFE5 /* HomeBannerView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeBannerView.h; sourceTree = "<group>"; };
+		BCBFDF3B281156430052AFE5 /* HomeBannerView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeBannerView.m; sourceTree = "<group>"; };
+		BCBFDF3D2811564C0052AFE5 /* HomeBannerView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeBannerView.xib; sourceTree = "<group>"; };
+		BCBFDF3F281157340052AFE5 /* HomeButtonView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeButtonView.h; sourceTree = "<group>"; };
+		BCBFDF40281157340052AFE5 /* HomeButtonView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeButtonView.m; sourceTree = "<group>"; };
+		BCBFDF422811573D0052AFE5 /* HomeButtonView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeButtonView.xib; sourceTree = "<group>"; };
+		BCBFDF44281159990052AFE5 /* HomeHotAlbumView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeHotAlbumView.h; sourceTree = "<group>"; };
+		BCBFDF45281159990052AFE5 /* HomeHotAlbumView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeHotAlbumView.m; sourceTree = "<group>"; };
+		BCBFDF47281159A40052AFE5 /* HomeHotAlbumView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeHotAlbumView.xib; sourceTree = "<group>"; };
+		BCBFDF4928115C6F0052AFE5 /* HomeHotCourseView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeHotCourseView.h; sourceTree = "<group>"; };
+		BCBFDF4A28115C6F0052AFE5 /* HomeHotCourseView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeHotCourseView.m; sourceTree = "<group>"; };
+		BCBFDF4C28115C7A0052AFE5 /* HomeHotCourseView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeHotCourseView.xib; sourceTree = "<group>"; };
+		BCBFDF4E28115D9A0052AFE5 /* HomeIntroduceView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeIntroduceView.h; sourceTree = "<group>"; };
+		BCBFDF4F28115D9A0052AFE5 /* HomeIntroduceView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeIntroduceView.m; sourceTree = "<group>"; };
+		BCBFDF5128115DA40052AFE5 /* HomeIntroduceView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeIntroduceView.xib; sourceTree = "<group>"; };
+		BCFE53E42812765600AD6786 /* HomeHotAlbumCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeHotAlbumCell.h; sourceTree = "<group>"; };
+		BCFE53E52812765600AD6786 /* HomeHotAlbumCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeHotAlbumCell.m; sourceTree = "<group>"; };
+		BCFE53E62812765600AD6786 /* HomeHotAlbumCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeHotAlbumCell.xib; sourceTree = "<group>"; };
+		BCFE53E92812897600AD6786 /* HomeLiveCouseCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeLiveCouseCell.h; sourceTree = "<group>"; };
+		BCFE53EA2812897600AD6786 /* HomeLiveCouseCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeLiveCouseCell.m; sourceTree = "<group>"; };
+		BCFE53EB2812897600AD6786 /* HomeLiveCouseCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeLiveCouseCell.xib; sourceTree = "<group>"; };
+		BCFE53EE2812898700AD6786 /* HomeVideoCourseCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeVideoCourseCell.h; sourceTree = "<group>"; };
+		BCFE53EF2812898700AD6786 /* HomeVideoCourseCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeVideoCourseCell.m; sourceTree = "<group>"; };
+		BCFE53F02812898700AD6786 /* HomeVideoCourseCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HomeVideoCourseCell.xib; sourceTree = "<group>"; };
+		BCFE53F328128A9600AD6786 /* TeacherShowCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TeacherShowCell.h; sourceTree = "<group>"; };
+		BCFE53F428128A9600AD6786 /* TeacherShowCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TeacherShowCell.m; sourceTree = "<group>"; };
+		BCFE53F528128A9600AD6786 /* TeacherShowCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TeacherShowCell.xib; sourceTree = "<group>"; };
+		BCFE53F828129A5500AD6786 /* TeacherStyleModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TeacherStyleModel.m; sourceTree = "<group>"; };
+		BCFE53F928129A5500AD6786 /* TeacherStyleModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TeacherStyleModel.h; sourceTree = "<group>"; };
+		BCFE53FB2814E1BD00AD6786 /* HomeVideoGroupModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeVideoGroupModel.h; sourceTree = "<group>"; };
+		BCFE53FC2814E1BD00AD6786 /* HomeLiveGroupModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeLiveGroupModel.h; sourceTree = "<group>"; };
+		BCFE53FD2814E1BE00AD6786 /* HomeLiveGroupModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeLiveGroupModel.m; sourceTree = "<group>"; };
+		BCFE53FE2814E1BE00AD6786 /* HomeVideoGroupModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeVideoGroupModel.m; sourceTree = "<group>"; };
 		C9C170A749B6C49F17AC3246 /* Pods_KulexiuForStudent_KulexiuForStudentUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KulexiuForStudent_KulexiuForStudentUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		D5D730A1D1EC18E5028F1AD7 /* Pods-KulexiuForStudent-KulexiuForStudentUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KulexiuForStudent-KulexiuForStudentUITests.release.xcconfig"; path = "Target Support Files/Pods-KulexiuForStudent-KulexiuForStudentUITests/Pods-KulexiuForStudent-KulexiuForStudentUITests.release.xcconfig"; sourceTree = "<group>"; };
 		DD4D637EF600D0BAE869423D /* Pods_KulexiuForStudentTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KulexiuForStudentTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -1869,6 +1968,7 @@
 		275FA1F127E7356A00CFEA2E /* Home */ = {
 			isa = PBXGroup;
 			children = (
+				BC40BA0F28124D0C00DEC0D1 /* NoticeCenter */,
 				275FA1F227E7356A00CFEA2E /* Controller */,
 				275FA1F527E7356A00CFEA2E /* Model */,
 				275FA1F627E7356A00CFEA2E /* View */,
@@ -1888,6 +1988,12 @@
 		275FA1F527E7356A00CFEA2E /* Model */ = {
 			isa = PBXGroup;
 			children = (
+				BCFE53F928129A5500AD6786 /* TeacherStyleModel.h */,
+				BCFE53F828129A5500AD6786 /* TeacherStyleModel.m */,
+				BCFE53FC2814E1BD00AD6786 /* HomeLiveGroupModel.h */,
+				BCFE53FD2814E1BE00AD6786 /* HomeLiveGroupModel.m */,
+				BCFE53FB2814E1BD00AD6786 /* HomeVideoGroupModel.h */,
+				BCFE53FE2814E1BE00AD6786 /* HomeVideoGroupModel.m */,
 			);
 			path = Model;
 			sourceTree = "<group>";
@@ -1895,6 +2001,51 @@
 		275FA1F627E7356A00CFEA2E /* View */ = {
 			isa = PBXGroup;
 			children = (
+				BCBFDF3528110C660052AFE5 /* HomeNavView.h */,
+				BCBFDF3628110C660052AFE5 /* HomeNavView.m */,
+				BCBFDF3828110C6F0052AFE5 /* HomeNavView.xib */,
+				BCBFDF3A281156430052AFE5 /* HomeBannerView.h */,
+				BCBFDF3B281156430052AFE5 /* HomeBannerView.m */,
+				BCBFDF3D2811564C0052AFE5 /* HomeBannerView.xib */,
+				BCBFDF3F281157340052AFE5 /* HomeButtonView.h */,
+				BCBFDF40281157340052AFE5 /* HomeButtonView.m */,
+				BCBFDF422811573D0052AFE5 /* HomeButtonView.xib */,
+				BC40BA1E2812552300DEC0D1 /* KSHomeButton.h */,
+				BC40BA1C2812552200DEC0D1 /* KSHomeButton.m */,
+				BC40BA1D2812552200DEC0D1 /* KSHomeButton.xib */,
+				BCBFDF44281159990052AFE5 /* HomeHotAlbumView.h */,
+				BCBFDF45281159990052AFE5 /* HomeHotAlbumView.m */,
+				BCBFDF47281159A40052AFE5 /* HomeHotAlbumView.xib */,
+				BCBFDF4928115C6F0052AFE5 /* HomeHotCourseView.h */,
+				BCBFDF4A28115C6F0052AFE5 /* HomeHotCourseView.m */,
+				BCBFDF4C28115C7A0052AFE5 /* HomeHotCourseView.xib */,
+				BCBFDF4E28115D9A0052AFE5 /* HomeIntroduceView.h */,
+				BCBFDF4F28115D9A0052AFE5 /* HomeIntroduceView.m */,
+				BCBFDF5128115DA40052AFE5 /* HomeIntroduceView.xib */,
+				BC40B9F62811767A00DEC0D1 /* HotInformationHeadView.h */,
+				BC40B9F72811767A00DEC0D1 /* HotInformationHeadView.m */,
+				BC40B9F92811768400DEC0D1 /* HotInformationHeadView.xib */,
+				BC40B9FB281177BD00DEC0D1 /* HomeInformationCell.h */,
+				BC40B9FC281177BD00DEC0D1 /* HomeInformationCell.m */,
+				BC40B9FD281177BD00DEC0D1 /* HomeInformationCell.xib */,
+				BC40BA0028117B0A00DEC0D1 /* HomeBannerCell.h */,
+				BC40BA0128117B0A00DEC0D1 /* HomeBannerCell.m */,
+				BC40BA0228117B0A00DEC0D1 /* HomeBannerCell.xib */,
+				BC40BA21281255F700DEC0D1 /* HomeCourseTipsView.h */,
+				BC40BA22281255F700DEC0D1 /* HomeCourseTipsView.m */,
+				BC40BA242812560100DEC0D1 /* HomeCourseTipsView.xib */,
+				BCFE53E42812765600AD6786 /* HomeHotAlbumCell.h */,
+				BCFE53E52812765600AD6786 /* HomeHotAlbumCell.m */,
+				BCFE53E62812765600AD6786 /* HomeHotAlbumCell.xib */,
+				BCFE53E92812897600AD6786 /* HomeLiveCouseCell.h */,
+				BCFE53EA2812897600AD6786 /* HomeLiveCouseCell.m */,
+				BCFE53EB2812897600AD6786 /* HomeLiveCouseCell.xib */,
+				BCFE53EE2812898700AD6786 /* HomeVideoCourseCell.h */,
+				BCFE53EF2812898700AD6786 /* HomeVideoCourseCell.m */,
+				BCFE53F02812898700AD6786 /* HomeVideoCourseCell.xib */,
+				BCFE53F328128A9600AD6786 /* TeacherShowCell.h */,
+				BCFE53F428128A9600AD6786 /* TeacherShowCell.m */,
+				BCFE53F528128A9600AD6786 /* TeacherShowCell.xib */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -2618,6 +2769,7 @@
 		2779346E27E324A10010E277 /* ThirdPart */ = {
 			isa = PBXGroup;
 			children = (
+				BC40BA0528117B3A00DEC0D1 /* TYCyclePagerView */,
 				2723B63D27F15B5800E0B90B /* SCIndexView */,
 				2779346F27E324A10010E277 /* KLTAnimateNav */,
 				2779347427E324A10010E277 /* DZSegmentCtrl */,
@@ -3202,6 +3354,54 @@
 			path = View;
 			sourceTree = "<group>";
 		};
+		BC40BA0528117B3A00DEC0D1 /* TYCyclePagerView */ = {
+			isa = PBXGroup;
+			children = (
+				BC40BA0628117B3A00DEC0D1 /* TYCyclePagerView.h */,
+				BC40BA0728117B3A00DEC0D1 /* TYCyclePagerTransformLayout.h */,
+				BC40BA0828117B3A00DEC0D1 /* TYPageControl.m */,
+				BC40BA0928117B3A00DEC0D1 /* TYCyclePagerView.m */,
+				BC40BA0A28117B3A00DEC0D1 /* TYCyclePagerTransformLayout.m */,
+				BC40BA0B28117B3A00DEC0D1 /* TYPageControl.h */,
+			);
+			path = TYCyclePagerView;
+			sourceTree = "<group>";
+		};
+		BC40BA0F28124D0C00DEC0D1 /* NoticeCenter */ = {
+			isa = PBXGroup;
+			children = (
+				BC40BA1028124D0C00DEC0D1 /* Controller */,
+				BC40BA1128124D0C00DEC0D1 /* Model */,
+				BC40BA1228124D0C00DEC0D1 /* View */,
+			);
+			path = NoticeCenter;
+			sourceTree = "<group>";
+		};
+		BC40BA1028124D0C00DEC0D1 /* Controller */ = {
+			isa = PBXGroup;
+			children = (
+				BC40BA1628124D3D00DEC0D1 /* NoticeMessageViewController.h */,
+				BC40BA1728124D3D00DEC0D1 /* NoticeMessageViewController.m */,
+			);
+			path = Controller;
+			sourceTree = "<group>";
+		};
+		BC40BA1128124D0C00DEC0D1 /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				BC40BA19281251EC00DEC0D1 /* HomeMessageModel.h */,
+				BC40BA1A281251ED00DEC0D1 /* HomeMessageModel.m */,
+			);
+			path = Model;
+			sourceTree = "<group>";
+		};
+		BC40BA1228124D0C00DEC0D1 /* View */ = {
+			isa = PBXGroup;
+			children = (
+			);
+			path = View;
+			sourceTree = "<group>";
+		};
 		BCB6340A27F6D29500ACFDCF /* Live */ = {
 			isa = PBXGroup;
 			children = (
@@ -3926,12 +4126,14 @@
 				BCB6359927F6D2AB00ACFDCF /* tick.wav in Resources */,
 				2779355727E324A70010E277 /* KSPremissionAlert.xib in Resources */,
 				2723B5C327F157B100E0B90B /* ChatNavView.xib in Resources */,
+				BCFE53F22812898700AD6786 /* HomeVideoCourseCell.xib in Resources */,
 				2723B5BA27F157B100E0B90B /* ChatAddressHeaderView.xib in Resources */,
 				BC119235280ED97C00A716F7 /* CourseForLiveCell.xib in Resources */,
 				2723B62E27F157D500E0B90B /* GroupApplyChooseAllCell.xib in Resources */,
 				275FA23A27E7356B00CFEA2E /* VefiBodyView.xib in Resources */,
 				BC119258280FA85300A716F7 /* HomeworkListCell.xib in Resources */,
 				2723B63227F157D500E0B90B /* GroupSettingBodyView.xib in Resources */,
+				BCFE53F728128A9600AD6786 /* TeacherShowCell.xib in Resources */,
 				2723B5BF27F157B100E0B90B /* GroupCreateView.xib in Resources */,
 				2723B63727F157D500E0B90B /* ApplyBottomView.xib in Resources */,
 				2723B62F27F157D500E0B90B /* ChatComplainBodyView.xib in Resources */,
@@ -3943,6 +4145,7 @@
 				BC119280280FB10900A716F7 /* AccompanyRemarkCell.xib in Resources */,
 				2723B63527F157D500E0B90B /* GroupApplyChooseCell.xib in Resources */,
 				2723B5C227F157B100E0B90B /* GroupListViewCell.xib in Resources */,
+				BCBFDF432811573D0052AFE5 /* HomeButtonView.xib in Resources */,
 				BC11925A280FA85300A716F7 /* HomeworkSortView.xib in Resources */,
 				2723B62527F157D500E0B90B /* GroupNoticeCell.xib in Resources */,
 				275FA23D27E7356B00CFEA2E /* PasswordBodyView.xib in Resources */,
@@ -3951,10 +4154,13 @@
 				BCB6353027F6D2A300ACFDCF /* SealClass.strings in Resources */,
 				BCB635AE27F6E06500ACFDCF /* LiveRoomHeadView.xib in Resources */,
 				275FA1AD27E734C600CFEA2E /* KSImageAlert.xib in Resources */,
+				BCBFDF5228115DA40052AFE5 /* HomeIntroduceView.xib in Resources */,
 				BC119270280FAF7D00A716F7 /* AccompanyCourseInfoCell.xib in Resources */,
+				BC40BA202812552300DEC0D1 /* KSHomeButton.xib in Resources */,
 				2723B5C427F157B100E0B90B /* KSChatListSearchView.xib in Resources */,
 				2779359B27E324A80010E277 /* TZImagePickerController.bundle in Resources */,
 				277935C327E324A90010E277 /* SDQWMaskCustomView.xib in Resources */,
+				BC40B9FA2811768400DEC0D1 /* HotInformationHeadView.xib in Resources */,
 				275FA24A27E7428D00CFEA2E /* InstrumentChooseView.xib in Resources */,
 				BC27A06E280FF56C00F91E27 /* AccompanyEvaluateCell.xib in Resources */,
 				2723B66327F15CFC00E0B90B /* ModifyNameBodyView.xib in Resources */,
@@ -3962,17 +4168,23 @@
 				BCB6348327F6D29600ACFDCF /* LiveSeatApplyView.xib in Resources */,
 				2723B66A27F15CFC00E0B90B /* PhoneChangeBodyView.xib in Resources */,
 				27F9032D27E87C2E00C08A19 /* KSNetworkAlert.xib in Resources */,
+				BCFE53ED2812897600AD6786 /* HomeLiveCouseCell.xib in Resources */,
 				275FA24527E73E0100CFEA2E /* InstrumentDescView.xib in Resources */,
 				BC11922D280ED8E800A716F7 /* CourseNavView.xib in Resources */,
 				BC11929D280FD2EF00A716F7 /* HomeworkBottomView.xib in Resources */,
 				BCB6348127F6D29600ACFDCF /* LiveSeatApplyCell.xib in Resources */,
 				2723B62D27F157D500E0B90B /* GroupApplyMemberCell.xib in Resources */,
 				BCB6347427F6D29600ACFDCF /* BaseEmoji.plist in Resources */,
+				BC40BA252812560100DEC0D1 /* HomeCourseTipsView.xib in Resources */,
 				27F9032E27E87C2E00C08A19 /* DeviceCheckView.xib in Resources */,
 				275FA23727E7356B00CFEA2E /* LoginBodyView.xib in Resources */,
 				BCB6355927F6D2A300ACFDCF /* class_stop.mp3 in Resources */,
+				BCFE53E82812765600AD6786 /* HomeHotAlbumCell.xib in Resources */,
+				BC40BA0428117B0A00DEC0D1 /* HomeBannerCell.xib in Resources */,
 				BC119239280ED98E00A716F7 /* AccompanyCourseCell.xib in Resources */,
 				BC27A076280FF61300F91E27 /* AccompanyDetailBottomView.xib in Resources */,
+				BCBFDF4D28115C7A0052AFE5 /* HomeHotCourseView.xib in Resources */,
+				BCBFDF3928110C6F0052AFE5 /* HomeNavView.xib in Resources */,
 				27F9033C27E87FE100C08A19 /* MineBodyView.xib in Resources */,
 				27F9032B27E87C2E00C08A19 /* NetworkBodyView.xib in Resources */,
 				2779358F27E324A80010E277 /* WMPlayer.bundle in Resources */,
@@ -3985,13 +4197,16 @@
 				BC11921B280ED6A900A716F7 /* NewClassPopCell.xib in Resources */,
 				2723B66E27F15CFC00E0B90B /* PhoneCheckBodyView.xib in Resources */,
 				BC119217280ED6A900A716F7 /* MyLessonSearchView.xib in Resources */,
+				BCBFDF3E2811564C0052AFE5 /* HomeBannerView.xib in Resources */,
 				2723B5C527F157B100E0B90B /* ContractListCell.xib in Resources */,
+				BCBFDF48281159A40052AFE5 /* HomeHotAlbumView.xib in Resources */,
 				27F9033727E87C8B00C08A19 /* MineNavView.xib in Resources */,
 				BC119215280ED6A900A716F7 /* MyLiveCourseCell.xib in Resources */,
 				BC50171727FC0D8E00F8BCBC /* SubjectChooseBodyView.xib in Resources */,
 				BCB6359D27F6D2AB00ACFDCF /* tock.wav in Resources */,
 				BC0D1F72281015B000C5D9E5 /* VideoCourseCell.xib in Resources */,
 				BC11927B280FB07F00A716F7 /* AccompanyArrangeCell.xib in Resources */,
+				BC40B9FF281177BD00DEC0D1 /* HomeInformationCell.xib in Resources */,
 				275E8AB327E18F8800DD3F6E /* Main.storyboard in Resources */,
 				277935B127E324A90010E277 /* mss_browseLoading@2x.png in Resources */,
 				BC11922C280ED8E800A716F7 /* LTSCalendarBottomView.xib in Resources */,
@@ -4165,6 +4380,7 @@
 				27F9033027E87C2E00C08A19 /* AudioRecordManager.m in Sources */,
 				BCB6355227F6D2A300ACFDCF /* SelectionButton.m in Sources */,
 				2779352527E324A60010E277 /* pinyin.c in Sources */,
+				BCFE53F628128A9600AD6786 /* TeacherShowCell.m in Sources */,
 				2779357B27E324A70010E277 /* ShopButton.m in Sources */,
 				2723B61E27F157D500E0B90B /* GroupNoticeEditController.m in Sources */,
 				BCB6346427F6D29600ACFDCF /* KSLiveChatroomSeatApply.m in Sources */,
@@ -4183,6 +4399,7 @@
 				277935BE27E324A90010E277 /* FSCalendarCalculator.m in Sources */,
 				BCB6347727F6D29600ACFDCF /* LiveRoomLikeLayer.m in Sources */,
 				275FA1DC27E7351900CFEA2E /* KSAQRecordManager.m in Sources */,
+				BC40B9F82811767A00DEC0D1 /* HotInformationHeadView.m in Sources */,
 				BCB6356827F6D2A300ACFDCF /* ApplySpeechResultMessage.m in Sources */,
 				2779351427E324A50010E277 /* NSMutableDictionary+KSSafe.m in Sources */,
 				2779356F27E324A70010E277 /* SkipTextField.m in Sources */,
@@ -4199,6 +4416,7 @@
 				2779356527E324A70010E277 /* KSMediaManager.m in Sources */,
 				2779355C27E324A70010E277 /* KSChoosePicker.m in Sources */,
 				2779356C27E324A70010E277 /* MBProgressHUD+NJ.m in Sources */,
+				BCBFDF5028115D9A0052AFE5 /* HomeIntroduceView.m in Sources */,
 				2779353227E324A60010E277 /* NSDate+Transform.m in Sources */,
 				2779356827E324A70010E277 /* shopview.m in Sources */,
 				2723B64527F15B5900E0B90B /* SCIndexView.m in Sources */,
@@ -4230,6 +4448,7 @@
 				275FA1EB27E7351900CFEA2E /* KSBaseWKWebViewController.m in Sources */,
 				BCB6356727F6D2A300ACFDCF /* MemberChangeMessage.m in Sources */,
 				2779353B27E324A60010E277 /* UrlDecode.m in Sources */,
+				BC40BA23281255F700DEC0D1 /* HomeCourseTipsView.m in Sources */,
 				275FA22C27E7356B00CFEA2E /* CourseViewController.m in Sources */,
 				2779358D27E324A80010E277 /* DZNSegmentedControl.m in Sources */,
 				2779352027E324A60010E277 /* CALayer+Color.m in Sources */,
@@ -4285,6 +4504,7 @@
 				BCB6359727F6D2AB00ACFDCF /* ClassroomTimerManager.m in Sources */,
 				2779352227E324A60010E277 /* UITextView+ZWLimitCounter.m in Sources */,
 				27F9032927E87C2E00C08A19 /* NetworkingCheckController.m in Sources */,
+				BCFE53EC2812897600AD6786 /* HomeLiveCouseCell.m in Sources */,
 				277935A527E324A80010E277 /* MSSBrowseLoadingImageView.m in Sources */,
 				2779353E27E324A60010E277 /* UIDevice+TFDevice.m in Sources */,
 				2723B5C027F157B100E0B90B /* ChatAddressHeaderView.m in Sources */,
@@ -4292,11 +4512,13 @@
 				2779359927E324A80010E277 /* NSBundle+TZImagePicker.m in Sources */,
 				2779358E27E324A80010E277 /* WMPlayerModel.m in Sources */,
 				2779354E27E324A70010E277 /* KSAudioSessionManager.m in Sources */,
+				BCBFDF41281157340052AFE5 /* HomeButtonView.m in Sources */,
 				2779358127E324A80010E277 /* StateView.m in Sources */,
 				2779358C27E324A80010E277 /* AnimationContoller.m in Sources */,
 				2779359027E324A80010E277 /* WMLightView.m in Sources */,
 				2723B5A227F1578300E0B90B /* CreateFansGroupViewController.m in Sources */,
 				BCB6355E27F6D2A300ACFDCF /* ControlDeviceNotifyMessage.m in Sources */,
+				BC40BA1B281251ED00DEC0D1 /* HomeMessageModel.m in Sources */,
 				277935BD27E324A90010E277 /* FSCalendarConstants.m in Sources */,
 				BCB6354527F6D2A300ACFDCF /* RecentSharedVideoCell.m in Sources */,
 				BCB6347027F6D29600ACFDCF /* LiveSeatMember.m in Sources */,
@@ -4319,6 +4541,7 @@
 				BC119234280ED97C00A716F7 /* CourseForLiveCell.m in Sources */,
 				BCB6346027F6D29600ACFDCF /* KSLiveChatroomKickOut.m in Sources */,
 				2779354127E324A60010E277 /* UIView+ShowProgress.m in Sources */,
+				BCFE53E72812765600AD6786 /* HomeHotAlbumCell.m in Sources */,
 				BCB6346627F6D29600ACFDCF /* KSLiveChatroomUserQuit.m in Sources */,
 				BCB6356D27F6D2A300ACFDCF /* RoomMember.m in Sources */,
 				277935B427E324A90010E277 /* FSCalendarDelegationProxy.m in Sources */,
@@ -4376,6 +4599,7 @@
 				2779358027E324A80010E277 /* sortButton.m in Sources */,
 				2779356027E324A70010E277 /* KSRecordStatusView.m in Sources */,
 				2723B62B27F157D500E0B90B /* ApplyMemberModel.m in Sources */,
+				BC40B9FE281177BD00DEC0D1 /* HomeInformationCell.m in Sources */,
 				2779354D27E324A70010E277 /* KSGifRefreshFooter.m in Sources */,
 				BC119288280FB3B100A716F7 /* KSStarView.m in Sources */,
 				275FA22F27E7356B00CFEA2E /* ShopMallViewController.m in Sources */,
@@ -4431,11 +4655,14 @@
 				BCB6359427F6D2AB00ACFDCF /* NewClassRoomViewController.m in Sources */,
 				BCB6356027F6D2A300ACFDCF /* WhiteboardMessage.m in Sources */,
 				2779354F27E324A70010E277 /* VoLRUManager.m in Sources */,
+				BC40BA0C28117B3B00DEC0D1 /* TYPageControl.m in Sources */,
+				BC40BA0D28117B3B00DEC0D1 /* TYCyclePagerView.m in Sources */,
 				2779356727E324A70010E277 /* UIColor+Hex.m in Sources */,
 				BCB6345E27F6D29600ACFDCF /* KSLiveChatroomLeave.m in Sources */,
 				BC11929B280FD2E800A716F7 /* HomeworkBottomView.m in Sources */,
 				275FA1E727E7351900CFEA2E /* KSWebSocketManager.m in Sources */,
 				277935AE27E324A80010E277 /* MSSBrowseRemindView.m in Sources */,
+				BCBFDF46281159990052AFE5 /* HomeHotAlbumView.m in Sources */,
 				2779356A27E324A70010E277 /* YKNodeModel.m in Sources */,
 				BC119244280EDA2400A716F7 /* NSObject+KSDateFormatter.m in Sources */,
 				277935CE27E324A90010E277 /* ALCalendarConfig.m in Sources */,
@@ -4446,12 +4673,14 @@
 				277935AD27E324A80010E277 /* MSSBrowseZoomScrollView.m in Sources */,
 				BCB6348227F6D29600ACFDCF /* SeatContentView.m in Sources */,
 				2723B68227F15D3D00E0B90B /* ModifyPhoneChangeController.m in Sources */,
+				BC40BA1F2812552300DEC0D1 /* KSHomeButton.m in Sources */,
 				277935C827E324A90010E277 /* TADotView.m in Sources */,
 				BC1191FF280ED64E00A716F7 /* MyCourseViewController.m in Sources */,
 				BC119298280FBCB400A716F7 /* UIView+ExtensionForDotLine.m in Sources */,
 				BCB635A927F6D93300ACFDCF /* KSChatVideoView.m in Sources */,
 				2779353027E324A60010E277 /* NSDate+Extension.m in Sources */,
 				BCB6356627F6D2A300ACFDCF /* DeviceMessage.m in Sources */,
+				BCBFDF3728110C660052AFE5 /* HomeNavView.m in Sources */,
 				277935D127E324A90010E277 /* ALCalendarCollectionView.m in Sources */,
 				2779355427E324A70010E277 /* VoNetWorking.m in Sources */,
 				275FA1EE27E7351900CFEA2E /* KSBaseViewController.m in Sources */,
@@ -4470,6 +4699,7 @@
 				277935BB27E324A90010E277 /* FSCalendarSeparatorDecorationView.m in Sources */,
 				275FA1DF27E7351900CFEA2E /* RCConnectionManager.m in Sources */,
 				275FA22B27E7356B00CFEA2E /* HomeViewController.m in Sources */,
+				BCFE53F12812898700AD6786 /* HomeVideoCourseCell.m in Sources */,
 				277935C027E324A90010E277 /* FSCalendarTransitionCoordinator.m in Sources */,
 				2779355B27E324A70010E277 /* KSStatusView.m in Sources */,
 				2779355227E324A70010E277 /* VoMemoryCache.m in Sources */,
@@ -4516,6 +4746,7 @@
 				BC11922A280ED8E800A716F7 /* LTSCalendarBottomView.m in Sources */,
 				BCB6353E27F6D2A300ACFDCF /* TimeStampMessage.m in Sources */,
 				2779354027E324A60010E277 /* UIImage+Property.m in Sources */,
+				BCFE54002814E1BE00AD6786 /* HomeVideoGroupModel.m in Sources */,
 				2779356627E324A70010E277 /* ShopMessBtn.m in Sources */,
 				BC11921D280ED6A900A716F7 /* NewClassPopCell.m in Sources */,
 				277935B727E324A90010E277 /* FSCalendarStickyHeader.m in Sources */,
@@ -4524,10 +4755,12 @@
 				BCB6356F27F6D2A300ACFDCF /* Classroom.m in Sources */,
 				2779351B27E324A60010E277 /* UIControl+ButtonAction.m in Sources */,
 				BCB6354F27F6D2A300ACFDCF /* KSWhiteboardControl.m in Sources */,
+				BCBFDF3C281156430052AFE5 /* HomeBannerView.m in Sources */,
 				27F9032F27E87C2E00C08A19 /* AudioPlayManager.m in Sources */,
 				2779357C27E324A70010E277 /* NSString+MD5.m in Sources */,
 				2779355D27E324A70010E277 /* KSHoldButton.m in Sources */,
 				2723B62027F157D500E0B90B /* GroupNoticeCell.m in Sources */,
+				BC40BA0328117B0A00DEC0D1 /* HomeBannerCell.m in Sources */,
 				BCB6356327F6D2A300ACFDCF /* RoleChangedMessage.m in Sources */,
 				277935A627E324A80010E277 /* MSSBrowseLocalViewController.m in Sources */,
 				BCB6348427F6D29600ACFDCF /* KSChatroomTextCell.m in Sources */,
@@ -4540,6 +4773,7 @@
 				BCB6356927F6D2A300ACFDCF /* TurnPageMessage.m in Sources */,
 				277935CA27E324A90010E277 /* TAAnimatedDotView.m in Sources */,
 				2779353527E324A60010E277 /* NSObject+ReadDocument.m in Sources */,
+				BC40BA0E28117B3B00DEC0D1 /* TYCyclePagerTransformLayout.m in Sources */,
 				277935C227E324A90010E277 /* QWdynamicModel.m in Sources */,
 				2779357E27E324A80010E277 /* KSInputView.m in Sources */,
 				BCB6354927F6D2A300ACFDCF /* PersonListSectionView.m in Sources */,
@@ -4571,6 +4805,7 @@
 				2779357527E324A70010E277 /* LifeButton.m in Sources */,
 				27F9032C27E87C2E00C08A19 /* KSNetworkAlert.m in Sources */,
 				2779353627E324A60010E277 /* CALayer+Layout.m in Sources */,
+				BC40BA1828124D3D00DEC0D1 /* NoticeMessageViewController.m in Sources */,
 				275FA22D27E7356B00CFEA2E /* ChatViewController.m in Sources */,
 				BCB6354127F6D2A300ACFDCF /* VideoListCell.m in Sources */,
 				2723B5A427F1578300E0B90B /* KSChatConversationViewController.m in Sources */,
@@ -4588,10 +4823,12 @@
 				BCB6348027F6D29600ACFDCF /* LiveSeatApplyView.m in Sources */,
 				2779357F27E324A80010E277 /* KeyChainTools.m in Sources */,
 				2723B61927F157D500E0B90B /* KSSearchResultModel.m in Sources */,
+				BCBFDF4B28115C6F0052AFE5 /* HomeHotCourseView.m in Sources */,
 				BC27A074280FF60B00F91E27 /* AccompanyDetailBottomView.m in Sources */,
 				275FA1E327E7351900CFEA2E /* WeakWebViewScriptMessageDelegate.m in Sources */,
 				2779351F27E324A60010E277 /* UITextView+ZWPlaceHolder.m in Sources */,
 				2779353C27E324A60010E277 /* UIButton+Property.m in Sources */,
+				BCFE53FF2814E1BE00AD6786 /* HomeLiveGroupModel.m in Sources */,
 				277935CC27E324A90010E277 /* SDQWMaskCustomView.m in Sources */,
 				BCB6354627F6D2A300ACFDCF /* UpgradeDidApplyView.m in Sources */,
 				2779351727E324A60010E277 /* NSObject+KSSwizzling.m in Sources */,
@@ -4602,6 +4839,7 @@
 				2723B66627F15CFC00E0B90B /* AboutUsBodyView.m in Sources */,
 				277935BC27E324A90010E277 /* FSCalendarExtensions.m in Sources */,
 				2779356227E324A70010E277 /* KSRecordPowerAnimationView.m in Sources */,
+				BCFE53FA28129A5600AD6786 /* TeacherStyleModel.m in Sources */,
 				2779355527E324A70010E277 /* DiskFreeSpaceManager.m in Sources */,
 				2779352E27E324A60010E277 /* NSDictionary+Extension.m in Sources */,
 				2779355127E324A70010E277 /* VoCacheManager.m in Sources */,
@@ -4796,7 +5034,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 1.0.0;
-				DEVELOPMENT_TEAM = P664H7S5LL;
+				DEVELOPMENT_TEAM = B2AP53HHTU;
 				ENABLE_BITCODE = NO;
 				GCC_PREFIX_HEADER = "$(SRCROOT)/KulexiuForStudent/Common/Define/PrefixHeader.pch";
 				GENERATE_INFOPLIST_FILE = YES;
@@ -4821,7 +5059,7 @@
 					"@executable_path/Frameworks",
 				);
 				MARKETING_VERSION = 1.0.0;
-				PRODUCT_BUNDLE_IDENTIFIER = com.JingMing.KulexiuForStudent;
+				PRODUCT_BUNDLE_IDENTIFIER = com.Colexiu.KulexiuForStudent;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_EMIT_LOC_STRINGS = YES;
 				TARGETED_DEVICE_FAMILY = "1,2";
@@ -4836,7 +5074,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CODE_SIGN_STYLE = Automatic;
 				CURRENT_PROJECT_VERSION = 1.0.0;
-				DEVELOPMENT_TEAM = P664H7S5LL;
+				DEVELOPMENT_TEAM = B2AP53HHTU;
 				ENABLE_BITCODE = NO;
 				GCC_PREFIX_HEADER = "$(SRCROOT)/KulexiuForStudent/Common/Define/PrefixHeader.pch";
 				GENERATE_INFOPLIST_FILE = YES;
@@ -4861,7 +5099,7 @@
 					"@executable_path/Frameworks",
 				);
 				MARKETING_VERSION = 1.0.0;
-				PRODUCT_BUNDLE_IDENTIFIER = com.JingMing.KulexiuForStudent;
+				PRODUCT_BUNDLE_IDENTIFIER = com.Colexiu.KulexiuForStudent;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_EMIT_LOC_STRINGS = YES;
 				TARGETED_DEVICE_FAMILY = "1,2";

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


+ 32 - 0
KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -52,5 +52,37 @@
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "85F6799F-87FB-4066-950A-042BBCF48277"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "KulexiuForStudent/Module/Home/Controller/HomeViewController.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "794"
+            endingLineNumber = "794"
+            landmarkName = "-homeCourseChooseAction:"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "A085F06F-9154-4262-B0F9-974A805509C6"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "KulexiuForStudent/Module/Home/Controller/HomeViewController.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "797"
+            endingLineNumber = "797"
+            landmarkName = "-homeCourseChooseAction:"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
    </Breakpoints>
 </Bucket>

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Course/nav_shade.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Course/nav_shade.imageset/nav_shade@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Course/nav_shade.imageset/nav_shade@3x.png


+ 6 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Home/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

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

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

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


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


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

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

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


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


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

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

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


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


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

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

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


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


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

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

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


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


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

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

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


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


+ 19 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.h

@@ -453,6 +453,25 @@ NS_ASSUME_NONNULL_BEGIN
 /// @param faliure 失败
 + (void)videoLessonGroupRequest:(NSString *)post page:(NSInteger)page rows:(NSInteger)rows success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
 
+
+#pragma mark ---- 首页-老师风采
+// /api-student/teacher/stylePage
+
+/// 首页获取老师风采
+/// @param post post
+/// @param page 分页
+/// @param rows 条数
+/// @param success 成功
+/// @param faliure 失败
++ (void)homeQueryTeacherStyle:(NSString *)post page:(NSInteger)page rows:(NSInteger)rows success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
+
+// /api-student/courseSchedule/queryLiveAndVideo
+
+/// 首页-直播课&视频课
+/// @param get get
+/// @param success 成功
+/// @param faliure 失败
++ (void)homeQueryLiveAndVideo:(NSString *)get success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
 @end
 
 NS_ASSUME_NONNULL_END

+ 29 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/KSNetworkingManager.m

@@ -975,4 +975,33 @@
     [self request:post andWithUrl:url and:parm success:success faliure:faliure];
 }
 
+#pragma mark ---- 首页-老师风采
+
+// /api-student/teacher/stylePage
+
+/// 首页获取老师风采
+/// @param post post
+/// @param page 分页
+/// @param rows 条数
+/// @param success 成功
+/// @param faliure 失败
++ (void)homeQueryTeacherStyle:(NSString *)post page:(NSInteger)page rows:(NSInteger)rows success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    [self configRequestMethodJSON];
+    NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-student/teacher/stylePage"];
+    NSMutableDictionary *parm = [NSMutableDictionary dictionary];
+    [parm setValue:@(page) forKey:@"page"];
+    [parm setValue:@(rows) forKey:@"rows"];
+    [self request:post andWithUrl:url and:parm success:success faliure:faliure];
+}
+
+// /api-student/courseSchedule/queryLiveAndVideo
+
+/// 首页-直播课&视频课
+/// @param get get
+/// @param success 成功
+/// @param faliure 失败
++ (void)homeQueryLiveAndVideo:(NSString *)get success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
+    NSString *url = [NSString stringWithFormat:@"%@%@",hostURL, @"/api-student/courseSchedule/queryLiveAndVideo"];
+    [self request:get andWithUrl:url and:nil success:success faliure:faliure];
+}
 @end

+ 74 - 0
KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYCyclePagerTransformLayout.h

@@ -0,0 +1,74 @@
+//
+//  TYCyclePagerViewLayout.h
+//  TYCyclePagerViewDemo
+//
+//  Created by tany on 2017/6/19.
+//  Copyright © 2017年 tany. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(NSUInteger, TYCyclePagerTransformLayoutType) {
+    TYCyclePagerTransformLayoutLinear,
+    TYCyclePagerTransformLayoutNormal,
+    TYCyclePagerTransformLayoutCoverflow,
+};
+
+@class TYCyclePagerTransformLayout;
+@protocol TYCyclePagerTransformLayoutDelegate <NSObject>
+
+// initialize layout attributes
+- (void)pagerViewTransformLayout:(TYCyclePagerTransformLayout *)pagerViewTransformLayout initializeTransformAttributes:(UICollectionViewLayoutAttributes *)attributes;
+
+// apply layout attributes
+- (void)pagerViewTransformLayout:(TYCyclePagerTransformLayout *)pagerViewTransformLayout applyTransformToAttributes:(UICollectionViewLayoutAttributes *)attributes;
+
+@end
+
+
+@interface TYCyclePagerViewLayout : NSObject
+
+@property (nonatomic, assign) CGSize itemSize;
+@property (nonatomic, assign) CGFloat itemSpacing;
+@property (nonatomic, assign) UIEdgeInsets sectionInset;
+
+@property (nonatomic, assign) TYCyclePagerTransformLayoutType layoutType;
+
+@property (nonatomic, assign) CGFloat minimumScale; // sacle default 0.8
+@property (nonatomic, assign) CGFloat minimumAlpha; // alpha default 1.0
+@property (nonatomic, assign) CGFloat maximumAngle; // angle is % default 0.2
+
+@property (nonatomic, assign) BOOL isInfiniteLoop;  // infinte scroll
+@property (nonatomic, assign) CGFloat rateOfChange; // scale and angle change rate
+@property (nonatomic, assign) BOOL adjustSpacingWhenScroling; 
+
+/**
+ pageView cell item vertical centering
+ */
+@property (nonatomic, assign) BOOL itemVerticalCenter;
+
+/**
+ first and last item horizontalc enter, when isInfiniteLoop is NO
+ */
+@property (nonatomic, assign) BOOL itemHorizontalCenter;
+
+// sectionInset
+@property (nonatomic, assign, readonly) UIEdgeInsets onlyOneSectionInset;
+@property (nonatomic, assign, readonly) UIEdgeInsets firstSectionInset;
+@property (nonatomic, assign, readonly) UIEdgeInsets lastSectionInset;
+@property (nonatomic, assign, readonly) UIEdgeInsets middleSectionInset;
+
+@end
+
+
+@interface TYCyclePagerTransformLayout : UICollectionViewFlowLayout
+
+@property (nonatomic, strong) TYCyclePagerViewLayout *layout;
+
+@property (nonatomic, weak, nullable) id<TYCyclePagerTransformLayoutDelegate> delegate;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 300 - 0
KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYCyclePagerTransformLayout.m

@@ -0,0 +1,300 @@
+//
+//  TYCyclePagerViewLayout.m
+//  TYCyclePagerViewDemo
+//
+//  Created by tany on 2017/6/19.
+//  Copyright © 2017年 tany. All rights reserved.
+//
+
+#import "TYCyclePagerTransformLayout.h"
+
+typedef NS_ENUM(NSUInteger, TYTransformLayoutItemDirection) {
+    TYTransformLayoutItemLeft,
+    TYTransformLayoutItemCenter,
+    TYTransformLayoutItemRight,
+};
+
+
+@interface TYCyclePagerTransformLayout () {
+    struct {
+        unsigned int applyTransformToAttributes   :1;
+        unsigned int initializeTransformAttributes   :1;
+    }_delegateFlags;
+}
+
+@property (nonatomic, assign) BOOL applyTransformToAttributesDelegate;
+
+@end
+
+
+@interface TYCyclePagerViewLayout ()
+
+@property (nonatomic, weak) UIView *pageView;
+
+@end
+
+
+@implementation TYCyclePagerTransformLayout
+
+- (instancetype)init {
+    if (self = [super init]) {
+        self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
+    }
+    return self;
+}
+
+- (instancetype)initWithCoder:(NSCoder *)aDecoder {
+    if (self = [super initWithCoder:aDecoder]) {
+        self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
+    }
+    return self;
+}
+
+#pragma mark - getter setter
+
+- (void)setDelegate:(id<TYCyclePagerTransformLayoutDelegate>)delegate {
+    _delegate = delegate;
+    _delegateFlags.initializeTransformAttributes = [delegate respondsToSelector:@selector(pagerViewTransformLayout:initializeTransformAttributes:)];
+    _delegateFlags.applyTransformToAttributes = [delegate respondsToSelector:@selector(pagerViewTransformLayout:applyTransformToAttributes:)];
+}
+
+- (void)setLayout:(TYCyclePagerViewLayout *)layout {
+    _layout = layout;
+    _layout.pageView = self.collectionView;
+    self.itemSize = _layout.itemSize;
+    self.minimumInteritemSpacing = _layout.itemSpacing;
+    self.minimumLineSpacing = _layout.itemSpacing;
+}
+
+- (CGSize)itemSize {
+    if (!_layout) {
+        return [super itemSize];
+    }
+    return _layout.itemSize;
+}
+
+- (CGFloat)minimumLineSpacing {
+    if (!_layout) {
+        return [super minimumLineSpacing];
+    }
+    return _layout.itemSpacing;
+}
+
+- (CGFloat)minimumInteritemSpacing {
+    if (!_layout) {
+        return [super minimumInteritemSpacing];
+    }
+    return _layout.itemSpacing;
+}
+
+- (TYTransformLayoutItemDirection)directionWithCenterX:(CGFloat)centerX {
+    TYTransformLayoutItemDirection direction= TYTransformLayoutItemRight;
+    CGFloat contentCenterX = self.collectionView.contentOffset.x + CGRectGetWidth(self.collectionView.frame)/2;
+    if (ABS(centerX - contentCenterX) < 0.5) {
+        direction = TYTransformLayoutItemCenter;
+    }else if (centerX - contentCenterX < 0) {
+        direction = TYTransformLayoutItemLeft;
+    }
+    return direction;
+}
+
+#pragma mark - layout
+
+-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
+{
+    return _layout.layoutType == TYCyclePagerTransformLayoutNormal ? [super shouldInvalidateLayoutForBoundsChange:newBounds] : YES;
+}
+
+- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
+    if (_delegateFlags.applyTransformToAttributes || _layout.layoutType != TYCyclePagerTransformLayoutNormal) {
+        NSArray *attributesArray = [[NSArray alloc] initWithArray:[super layoutAttributesForElementsInRect:rect] copyItems:YES];
+        CGRect visibleRect = {self.collectionView.contentOffset,self.collectionView.bounds.size};
+        for (UICollectionViewLayoutAttributes *attributes in attributesArray) {
+            if (!CGRectIntersectsRect(visibleRect, attributes.frame)) {
+                continue;
+            }
+            if (_delegateFlags.applyTransformToAttributes) {
+                [_delegate pagerViewTransformLayout:self applyTransformToAttributes:attributes];
+            }else {
+                [self applyTransformToAttributes:attributes layoutType:_layout.layoutType];
+            }
+        }
+        return attributesArray;
+    }
+    return [super layoutAttributesForElementsInRect:rect];
+}
+
+- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
+    UICollectionViewLayoutAttributes *attributes = [super layoutAttributesForItemAtIndexPath:indexPath];
+    if (_delegateFlags.initializeTransformAttributes) {
+        [_delegate pagerViewTransformLayout:self initializeTransformAttributes:attributes];
+    }else if(_layout.layoutType != TYCyclePagerTransformLayoutNormal){
+        [self initializeTransformAttributes:attributes layoutType:_layout.layoutType];
+    }
+    return attributes;
+}
+
+#pragma mark - transform
+
+- (void)initializeTransformAttributes:(UICollectionViewLayoutAttributes *)attributes layoutType:(TYCyclePagerTransformLayoutType)layoutType {
+    switch (layoutType) {
+        case TYCyclePagerTransformLayoutLinear:
+            [self applyLinearTransformToAttributes:attributes scale:_layout.minimumScale alpha:_layout.minimumAlpha];
+            break;
+        case TYCyclePagerTransformLayoutCoverflow:
+        {
+            [self applyCoverflowTransformToAttributes:attributes angle:_layout.maximumAngle alpha:_layout.minimumAlpha];
+            break;
+        }
+        default:
+            break;
+    }
+}
+
+- (void)applyTransformToAttributes:(UICollectionViewLayoutAttributes *)attributes layoutType:(TYCyclePagerTransformLayoutType)layoutType {
+    switch (layoutType) {
+        case TYCyclePagerTransformLayoutLinear:
+            [self applyLinearTransformToAttributes:attributes];
+            break;
+        case TYCyclePagerTransformLayoutCoverflow:
+            [self applyCoverflowTransformToAttributes:attributes];
+            break;
+        default:
+            break;
+    }
+}
+
+#pragma mark - LinearTransform
+
+- (void)applyLinearTransformToAttributes:(UICollectionViewLayoutAttributes *)attributes {
+    CGFloat collectionViewWidth = self.collectionView.frame.size.width;
+    if (collectionViewWidth <= 0) {
+        return;
+    }
+    CGFloat centetX = self.collectionView.contentOffset.x + collectionViewWidth/2;
+    CGFloat delta = ABS(attributes.center.x - centetX);
+    CGFloat scale = MAX(1 - delta/collectionViewWidth*_layout.rateOfChange, _layout.minimumScale);
+    CGFloat alpha = MAX(1 - delta/collectionViewWidth, _layout.minimumAlpha);
+    [self applyLinearTransformToAttributes:attributes scale:scale alpha:alpha];
+}
+
+- (void)applyLinearTransformToAttributes:(UICollectionViewLayoutAttributes *)attributes scale:(CGFloat)scale alpha:(CGFloat)alpha {
+    CGAffineTransform transform = CGAffineTransformMakeScale(scale, scale);
+    if (_layout.adjustSpacingWhenScroling) {
+        TYTransformLayoutItemDirection direction = [self directionWithCenterX:attributes.center.x];
+        CGFloat translate = 0;
+        switch (direction) {
+            case TYTransformLayoutItemLeft:
+                translate = 1.15 * attributes.size.width*(1-scale)/2;
+                break;
+            case TYTransformLayoutItemRight:
+                translate = -1.15 * attributes.size.width*(1-scale)/2;
+                break;
+            default:
+                // center
+                scale = 1.0;
+                alpha = 1.0;
+                break;
+        }
+        transform = CGAffineTransformTranslate(transform,translate, 0);
+    }
+    attributes.transform = transform;
+    attributes.alpha = alpha;
+}
+
+#pragma mark - CoverflowTransform
+
+- (void)applyCoverflowTransformToAttributes:(UICollectionViewLayoutAttributes *)attributes{
+    CGFloat collectionViewWidth = self.collectionView.frame.size.width;
+    if (collectionViewWidth <= 0) {
+        return;
+    }
+    CGFloat centetX = self.collectionView.contentOffset.x + collectionViewWidth/2;
+    CGFloat delta = ABS(attributes.center.x - centetX);
+    CGFloat angle = MIN(delta/collectionViewWidth*(1-_layout.rateOfChange), _layout.maximumAngle);
+    CGFloat alpha = MAX(1 - delta/collectionViewWidth, _layout.minimumAlpha);
+    [self applyCoverflowTransformToAttributes:attributes angle:angle alpha:alpha];
+}
+
+- (void)applyCoverflowTransformToAttributes:(UICollectionViewLayoutAttributes *)attributes angle:(CGFloat)angle alpha:(CGFloat)alpha {
+    TYTransformLayoutItemDirection direction = [self directionWithCenterX:attributes.center.x];
+    CATransform3D transform3D = CATransform3DIdentity;
+    transform3D.m34 = -0.002;
+    CGFloat translate = 0;
+    switch (direction) {
+        case TYTransformLayoutItemLeft:
+            translate = (1-cos(angle*1.2*M_PI))*attributes.size.width;
+            break;
+        case TYTransformLayoutItemRight:
+            translate = -(1-cos(angle*1.2*M_PI))*attributes.size.width;
+            angle = -angle;
+            break;
+        default:
+            // center
+            angle = 0;
+            alpha = 1;
+            break;
+    }
+
+    transform3D = CATransform3DRotate(transform3D, M_PI*angle, 0, 1, 0);
+    if (_layout.adjustSpacingWhenScroling) {
+        transform3D = CATransform3DTranslate(transform3D, translate, 0, 0);
+    }
+    attributes.transform3D = transform3D;
+    attributes.alpha = alpha;
+
+}
+@end
+
+
+@implementation TYCyclePagerViewLayout
+
+- (instancetype)init {
+    if (self = [super init]) {
+        _itemVerticalCenter = YES;
+        _minimumScale = 0.8;
+        _minimumAlpha = 1.0;
+        _maximumAngle = 0.2;
+        _rateOfChange = 0.4;
+        _adjustSpacingWhenScroling = YES;
+    }
+    return self;
+}
+
+#pragma mark - getter
+
+- (UIEdgeInsets)onlyOneSectionInset {
+    CGFloat leftSpace = _pageView && !_isInfiniteLoop && _itemHorizontalCenter ? (CGRectGetWidth(_pageView.frame) - _itemSize.width)/2 : _sectionInset.left;
+    CGFloat rightSpace = _pageView && !_isInfiniteLoop && _itemHorizontalCenter ? (CGRectGetWidth(_pageView.frame) - _itemSize.width)/2 : _sectionInset.right;
+    if (_itemVerticalCenter) {
+        CGFloat verticalSpace = (CGRectGetHeight(_pageView.frame) - _itemSize.height)/2;
+        return UIEdgeInsetsMake(verticalSpace, leftSpace, verticalSpace, rightSpace);
+    }
+    return UIEdgeInsetsMake(_sectionInset.top, leftSpace, _sectionInset.bottom, rightSpace);
+}
+
+- (UIEdgeInsets)firstSectionInset {
+    if (_itemVerticalCenter) {
+        CGFloat verticalSpace = (CGRectGetHeight(_pageView.frame) - _itemSize.height)/2;
+        return UIEdgeInsetsMake(verticalSpace, _sectionInset.left, verticalSpace, _itemSpacing);
+    }
+    return UIEdgeInsetsMake(_sectionInset.top, _sectionInset.left, _sectionInset.bottom, _itemSpacing);
+}
+
+- (UIEdgeInsets)lastSectionInset {
+    if (_itemVerticalCenter) {
+        CGFloat verticalSpace = (CGRectGetHeight(_pageView.frame) - _itemSize.height)/2;
+        return UIEdgeInsetsMake(verticalSpace, 0, verticalSpace, _sectionInset.right);
+    }
+    return UIEdgeInsetsMake(_sectionInset.top, 0, _sectionInset.bottom, _sectionInset.right);
+}
+
+- (UIEdgeInsets)middleSectionInset {
+    if (_itemVerticalCenter) {
+        CGFloat verticalSpace = (CGRectGetHeight(_pageView.frame) - _itemSize.height)/2;
+        return UIEdgeInsetsMake(verticalSpace, 0, verticalSpace, _itemSpacing);
+    }
+    return _sectionInset;
+}
+
+@end

+ 180 - 0
KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYCyclePagerView.h

@@ -0,0 +1,180 @@
+//
+//  TYCyclePagerView.h
+//  TYCyclePagerViewDemo
+//
+//  Created by tany on 2017/6/14.
+//  Copyright © 2017年 tany. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+#import "TYCyclePagerTransformLayout.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef struct {
+    NSInteger index;
+    NSInteger section;
+}TYIndexSection;
+
+// pagerView scrolling direction
+typedef NS_ENUM(NSUInteger, TYPagerScrollDirection) {
+    TYPagerScrollDirectionLeft,
+    TYPagerScrollDirectionRight,
+};
+
+@class TYCyclePagerView;
+@protocol TYCyclePagerViewDataSource <NSObject>
+
+- (NSInteger)numberOfItemsInPagerView:(TYCyclePagerView *)pageView;
+
+- (__kindof UICollectionViewCell *)pagerView:(TYCyclePagerView *)pagerView cellForItemAtIndex:(NSInteger)index;
+
+/**
+ return pagerView layout,and cache layout
+ */
+- (TYCyclePagerViewLayout *)layoutForPagerView:(TYCyclePagerView *)pageView;
+
+@end
+
+@protocol TYCyclePagerViewDelegate <NSObject>
+
+@optional
+
+/**
+ pagerView did scroll to new index page
+ */
+- (void)pagerView:(TYCyclePagerView *)pageView didScrollFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex;
+
+/**
+ pagerView did selected item cell
+ */
+- (void)pagerView:(TYCyclePagerView *)pageView didSelectedItemCell:(__kindof UICollectionViewCell *)cell atIndex:(NSInteger)index;
+- (void)pagerView:(TYCyclePagerView *)pageView didSelectedItemCell:(__kindof UICollectionViewCell *)cell atIndexSection:(TYIndexSection)indexSection;
+
+// custom layout
+- (void)pagerView:(TYCyclePagerView *)pageView initializeTransformAttributes:(UICollectionViewLayoutAttributes *)attributes;
+
+- (void)pagerView:(TYCyclePagerView *)pageView applyTransformToAttributes:(UICollectionViewLayoutAttributes *)attributes;
+
+
+// scrollViewDelegate
+
+- (void)pagerViewDidScroll:(TYCyclePagerView *)pageView;
+
+- (void)pagerViewWillBeginDragging:(TYCyclePagerView *)pageView;
+
+- (void)pagerViewDidEndDragging:(TYCyclePagerView *)pageView willDecelerate:(BOOL)decelerate;
+
+- (void)pagerViewWillBeginDecelerating:(TYCyclePagerView *)pageView;
+
+- (void)pagerViewDidEndDecelerating:(TYCyclePagerView *)pageView;
+
+- (void)pagerViewWillBeginScrollingAnimation:(TYCyclePagerView *)pageView;
+
+- (void)pagerViewDidEndScrollingAnimation:(TYCyclePagerView *)pageView;
+
+@end
+
+
+@interface TYCyclePagerView : UIView
+
+// will be automatically resized to track the size of the pagerView
+@property (nonatomic, strong, nullable) UIView *backgroundView; 
+
+@property (nonatomic, weak, nullable) id<TYCyclePagerViewDataSource> dataSource;
+@property (nonatomic, weak, nullable) id<TYCyclePagerViewDelegate> delegate;
+
+// pager view, don't set dataSource and delegate
+@property (nonatomic, weak, readonly) UICollectionView *collectionView;
+// pager view layout
+@property (nonatomic, strong, readonly) TYCyclePagerViewLayout *layout;
+
+/**
+ is infinite cycle pageview
+ */
+@property (nonatomic, assign) BOOL isInfiniteLoop;
+
+/**
+ pagerView automatic scroll time interval, default 0,disable automatic
+ */
+@property (nonatomic, assign) CGFloat autoScrollInterval;
+
+@property (nonatomic, assign) BOOL reloadDataNeedResetIndex;
+
+/**
+ current page index
+ */
+@property (nonatomic, assign, readonly) NSInteger curIndex;
+@property (nonatomic, assign, readonly) TYIndexSection indexSection;
+
+// scrollView property
+@property (nonatomic, assign, readonly) CGPoint contentOffset;
+@property (nonatomic, assign, readonly) BOOL tracking;
+@property (nonatomic, assign, readonly) BOOL dragging;
+@property (nonatomic, assign, readonly) BOOL decelerating;
+
+
+/**
+ reload data, !!important!!: will clear layout and call delegate layoutForPagerView
+ */
+- (void)reloadData;
+
+/**
+ update data is reload data, but not clear layuot
+ */
+- (void)updateData;
+
+/**
+ if you only want update layout
+ */
+- (void)setNeedUpdateLayout;
+
+/**
+ will set layout nil and call delegate->layoutForPagerView
+ */
+- (void)setNeedClearLayout;
+
+/**
+ current index cell in pagerView
+ */
+- (__kindof UICollectionViewCell * _Nullable)curIndexCell;
+
+/**
+ visible cells in pageView
+ */
+- (NSArray<__kindof UICollectionViewCell *> *_Nullable)visibleCells;
+
+
+/**
+ visible pageView indexs, maybe repeat index
+ */
+- (NSArray *)visibleIndexs;
+
+/**
+ scroll to item at index
+ */
+- (void)scrollToItemAtIndex:(NSInteger)index animate:(BOOL)animate;
+- (void)scrollToItemAtIndexSection:(TYIndexSection)indexSection animate:(BOOL)animate;
+/**
+ scroll to next or pre item
+ */
+- (void)scrollToNearlyIndexAtDirection:(TYPagerScrollDirection)direction animate:(BOOL)animate;
+
+/**
+ register pager view cell with class
+ */
+- (void)registerClass:(Class)Class forCellWithReuseIdentifier:(NSString *)identifier;
+
+/**
+ register pager view cell with nib
+ */
+- (void)registerNib:(UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;
+
+/**
+ dequeue reusable cell for pagerView
+ */
+- (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 607 - 0
KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYCyclePagerView.m

@@ -0,0 +1,607 @@
+//
+//  TYCyclePagerView.m
+//  TYCyclePagerViewDemo
+//
+//  Created by tany on 2017/6/14.
+//  Copyright © 2017年 tany. All rights reserved.
+//
+
+#import "TYCyclePagerView.h"
+
+NS_INLINE BOOL TYEqualIndexSection(TYIndexSection indexSection1,TYIndexSection indexSection2) {
+    return indexSection1.index == indexSection2.index && indexSection1.section == indexSection2.section;
+}
+
+NS_INLINE TYIndexSection TYMakeIndexSection(NSInteger index, NSInteger section) {
+    TYIndexSection indexSection;
+    indexSection.index = index;
+    indexSection.section = section;
+    return indexSection;
+}
+
+@interface TYCyclePagerView () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, TYCyclePagerTransformLayoutDelegate> {
+    struct {
+        unsigned int pagerViewDidScroll   :1;
+        unsigned int didScrollFromIndexToNewIndex   :1;
+        unsigned int initializeTransformAttributes   :1;
+        unsigned int applyTransformToAttributes   :1;
+    }_delegateFlags;
+    struct {
+        unsigned int cellForItemAtIndex   :1;
+        unsigned int layoutForPagerView   :1;
+    }_dataSourceFlags;
+}
+
+// UI
+@property (nonatomic, weak) UICollectionView *collectionView;
+@property (nonatomic, strong) TYCyclePagerViewLayout *layout;
+@property (nonatomic, strong) NSTimer *timer;
+
+// Data
+@property (nonatomic, assign) NSInteger numberOfItems;
+
+@property (nonatomic, assign) NSInteger dequeueSection;
+@property (nonatomic, assign) TYIndexSection beginDragIndexSection;
+@property (nonatomic, assign) NSInteger firstScrollIndex;
+
+@property (nonatomic, assign) BOOL needClearLayout;
+@property (nonatomic, assign) BOOL didReloadData;
+@property (nonatomic, assign) BOOL didLayout;
+@property (nonatomic, assign) BOOL needResetIndex;
+
+@end
+
+#define kPagerViewMaxSectionCount 200
+#define kPagerViewMinSectionCount 18
+
+@implementation TYCyclePagerView
+
+#pragma mark - life Cycle
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    if (self = [super initWithFrame:frame]) {
+        [self configureProperty];
+        
+        [self addCollectionView];
+    }
+    return self;
+}
+
+- (instancetype)initWithCoder:(NSCoder *)aDecoder {
+    if (self = [super initWithCoder:aDecoder]) {
+        [self configureProperty];
+        
+        [self addCollectionView];
+    }
+    return self;
+}
+
+- (void)configureProperty {
+    _needResetIndex = NO;
+    _didReloadData = NO;
+    _didLayout = NO;
+    _autoScrollInterval = 0;
+    _isInfiniteLoop = YES;
+    _beginDragIndexSection.index = 0;
+    _beginDragIndexSection.section = 0;
+    _indexSection.index = -1;
+    _indexSection.section = -1;
+    _firstScrollIndex = -1;
+}
+
+- (void)addCollectionView {
+    TYCyclePagerTransformLayout *layout = [[TYCyclePagerTransformLayout alloc]init];
+    UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:layout];
+    layout.delegate = _delegateFlags.applyTransformToAttributes ? self : nil;;
+    collectionView.backgroundColor = [UIColor clearColor];
+    collectionView.dataSource = self;
+    collectionView.delegate = self;
+    collectionView.pagingEnabled = NO;
+    collectionView.decelerationRate = 1-0.0076;
+    if ([collectionView respondsToSelector:@selector(setPrefetchingEnabled:)]) {
+        collectionView.prefetchingEnabled = NO;
+    }
+    collectionView.showsHorizontalScrollIndicator = NO;
+    collectionView.showsVerticalScrollIndicator = NO;
+    [self addSubview:collectionView];
+    _collectionView = collectionView;
+}
+
+- (void)willMoveToSuperview:(UIView *)newSuperview {
+    if (!newSuperview) {
+        [self removeTimer];
+    }else {
+        [self removeTimer];
+        if (_autoScrollInterval > 0) {
+            [self addTimer];
+        }
+    }
+}
+
+
+#pragma mark - timer
+
+- (void)addTimer {
+    if (_timer || _autoScrollInterval <= 0) {
+        return;
+    }
+    _timer = [NSTimer timerWithTimeInterval:_autoScrollInterval target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];
+    [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
+}
+
+- (void)removeTimer {
+    if (!_timer) {
+        return;
+    }
+    [_timer invalidate];
+    _timer = nil;
+}
+
+- (void)timerFired:(NSTimer *)timer {
+    if (!self.superview || !self.window || _numberOfItems == 0 || self.tracking) {
+        return;
+    }
+    
+    [self scrollToNearlyIndexAtDirection:TYPagerScrollDirectionRight animate:YES];
+}
+
+#pragma mark - getter
+
+- (TYCyclePagerViewLayout *)layout {
+    if (!_layout) {
+        if (_dataSourceFlags.layoutForPagerView) {
+            _layout = [_dataSource layoutForPagerView:self];
+            _layout.isInfiniteLoop = _isInfiniteLoop;
+        }
+        if (_layout.itemSize.width <= 0 || _layout.itemSize.height <= 0) {
+            _layout = nil;
+        }
+    }
+    return _layout;
+}
+
+- (NSInteger)curIndex {
+    return _indexSection.index;
+}
+
+- (CGPoint)contentOffset {
+    return _collectionView.contentOffset;
+}
+
+- (BOOL)tracking {
+    return _collectionView.tracking;
+}
+
+- (BOOL)dragging {
+    return _collectionView.dragging;
+}
+
+- (BOOL)decelerating {
+    return _collectionView.decelerating;
+}
+
+- (UIView *)backgroundView {
+    return _collectionView.backgroundView;
+}
+
+- (__kindof UICollectionViewCell *)curIndexCell {
+    return [_collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:_indexSection.index inSection:_indexSection.section]];
+}
+
+- (NSArray<__kindof UICollectionViewCell *> *)visibleCells {
+    return _collectionView.visibleCells;
+}
+
+- (NSArray *)visibleIndexs {
+    NSMutableArray *indexs = [NSMutableArray array];
+    for (NSIndexPath *indexPath in _collectionView.indexPathsForVisibleItems) {
+        [indexs addObject:@(indexPath.item)];
+    }
+    return [indexs copy];
+}
+
+#pragma mark - setter
+
+- (void)setBackgroundView:(UIView *)backgroundView {
+    [_collectionView setBackgroundView:backgroundView];
+}
+
+- (void)setAutoScrollInterval:(CGFloat)autoScrollInterval {
+    _autoScrollInterval = autoScrollInterval;
+    [self removeTimer];
+    if (autoScrollInterval > 0 && self.superview) {
+        [self addTimer];
+    }
+}
+
+- (void)setDelegate:(id<TYCyclePagerViewDelegate>)delegate {
+    _delegate = delegate;
+    _delegateFlags.pagerViewDidScroll = [delegate respondsToSelector:@selector(pagerViewDidScroll:)];
+    _delegateFlags.didScrollFromIndexToNewIndex = [delegate respondsToSelector:@selector(pagerView:didScrollFromIndex:toIndex:)];
+    _delegateFlags.initializeTransformAttributes = [delegate respondsToSelector:@selector(pagerView:initializeTransformAttributes:)];
+    _delegateFlags.applyTransformToAttributes = [delegate respondsToSelector:@selector(pagerView:applyTransformToAttributes:)];
+    if (self.collectionView && self.collectionView.collectionViewLayout) {
+        ((TYCyclePagerTransformLayout *)self.collectionView.collectionViewLayout).delegate = _delegateFlags.applyTransformToAttributes ? self : nil;
+    }
+}
+
+- (void)setDataSource:(id<TYCyclePagerViewDataSource>)dataSource {
+    _dataSource = dataSource;
+    _dataSourceFlags.cellForItemAtIndex = [dataSource respondsToSelector:@selector(pagerView:cellForItemAtIndex:)];
+    _dataSourceFlags.layoutForPagerView = [dataSource respondsToSelector:@selector(layoutForPagerView:)];
+}
+
+#pragma mark - public
+
+- (void)reloadData {
+    _didReloadData = YES;
+    _needResetIndex = YES;
+    [self setNeedClearLayout];
+    [self clearLayout];
+    [self updateData];
+}
+
+// not clear layout
+- (void)updateData {
+    [self updateLayout];
+    _numberOfItems = [_dataSource numberOfItemsInPagerView:self];
+    [_collectionView reloadData];
+    if (!_didLayout && !CGRectIsEmpty(self.collectionView.frame) && _indexSection.index < 0) {
+        _didLayout = YES;
+    }
+    BOOL needResetIndex = _needResetIndex && _reloadDataNeedResetIndex;
+    _needResetIndex = NO;
+    if (needResetIndex) {
+        [self removeTimer];
+    }
+    [self resetPagerViewAtIndex:(_indexSection.index < 0 && !CGRectIsEmpty(self.collectionView.frame)) || needResetIndex ? 0 :_indexSection.index];
+    if (needResetIndex) {
+        [self addTimer];
+    }
+}
+
+- (void)scrollToNearlyIndexAtDirection:(TYPagerScrollDirection)direction animate:(BOOL)animate {
+    TYIndexSection indexSection = [self nearlyIndexPathAtDirection:direction];
+    [self scrollToItemAtIndexSection:indexSection animate:animate];
+}
+
+- (void)scrollToItemAtIndex:(NSInteger)index animate:(BOOL)animate {
+    if (!_didLayout && _didReloadData) {
+        _firstScrollIndex = index;
+    }else {
+        _firstScrollIndex = -1;
+    }
+    if (!_isInfiniteLoop) {
+        [self scrollToItemAtIndexSection:TYMakeIndexSection(index, 0) animate:animate];
+        return;
+    }
+
+    [self scrollToItemAtIndexSection:TYMakeIndexSection(index, index >= self.curIndex ? _indexSection.section : _indexSection.section+1) animate:animate];
+}
+
+- (void)scrollToItemAtIndexSection:(TYIndexSection)indexSection animate:(BOOL)animate {
+    if (_numberOfItems <= 0 || ![self isValidIndexSection:indexSection]) {
+        //NSLog(@"scrollToItemAtIndex: item indexSection is invalid!");
+        return;
+    }
+    
+    if (animate && [_delegate respondsToSelector:@selector(pagerViewWillBeginScrollingAnimation:)]) {
+        [_delegate pagerViewWillBeginScrollingAnimation:self];
+    }
+    CGFloat offset = [self caculateOffsetXAtIndexSection:indexSection];
+    [_collectionView setContentOffset:CGPointMake(offset, _collectionView.contentOffset.y) animated:animate];
+}
+
+- (void)registerClass:(Class)Class forCellWithReuseIdentifier:(NSString *)identifier {
+    [_collectionView registerClass:Class forCellWithReuseIdentifier:identifier];
+}
+
+- (void)registerNib:(UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier {
+    [_collectionView registerNib:nib forCellWithReuseIdentifier:identifier];
+}
+
+- (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index {
+    UICollectionViewCell *cell = [_collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:[NSIndexPath indexPathForItem:index inSection:_dequeueSection]];
+    return cell;
+}
+
+#pragma mark - configure layout
+
+- (void)updateLayout {
+    if (!self.layout) {
+        return;
+    }
+    self.layout.isInfiniteLoop = _isInfiniteLoop;
+    ((TYCyclePagerTransformLayout *)_collectionView.collectionViewLayout).layout = self.layout;
+}
+
+- (void)clearLayout {
+    if (_needClearLayout) {
+        _layout = nil;
+        _needClearLayout = NO;
+    }
+}
+
+- (void)setNeedClearLayout {
+    _needClearLayout = YES;
+}
+
+- (void)setNeedUpdateLayout {
+    if (!self.layout) {
+        return;
+    }
+    [self clearLayout];
+    [self updateLayout];
+    [_collectionView.collectionViewLayout invalidateLayout];
+    [self resetPagerViewAtIndex:_indexSection.index < 0 ? 0 :_indexSection.index];
+}
+
+#pragma mark - pager index
+
+- (BOOL)isValidIndexSection:(TYIndexSection)indexSection {
+    return indexSection.index >= 0 && indexSection.index < _numberOfItems && indexSection.section >= 0 && indexSection.section < kPagerViewMaxSectionCount;
+}
+
+- (TYIndexSection)nearlyIndexPathAtDirection:(TYPagerScrollDirection)direction{
+    return [self nearlyIndexPathForIndexSection:_indexSection direction:direction];
+}
+
+- (TYIndexSection)nearlyIndexPathForIndexSection:(TYIndexSection)indexSection direction:(TYPagerScrollDirection)direction {
+    if (indexSection.index < 0 || indexSection.index >= _numberOfItems) {
+        return indexSection;
+    }
+    
+    if (!_isInfiniteLoop) {
+        if (direction == TYPagerScrollDirectionRight && indexSection.index == _numberOfItems - 1) {
+            return _autoScrollInterval > 0 ? TYMakeIndexSection(0, 0) : indexSection;
+        } else if (direction == TYPagerScrollDirectionRight) {
+            return TYMakeIndexSection(indexSection.index+1, 0);
+        }
+        
+        if (indexSection.index == 0) {
+            return _autoScrollInterval > 0 ? TYMakeIndexSection(_numberOfItems - 1, 0) : indexSection;
+        }
+        return TYMakeIndexSection(indexSection.index-1, 0);
+    }
+    
+    if (direction == TYPagerScrollDirectionRight) {
+        if (indexSection.index < _numberOfItems-1) {
+            return TYMakeIndexSection(indexSection.index+1, indexSection.section);
+        }
+        if (indexSection.section >= kPagerViewMaxSectionCount-1) {
+            return TYMakeIndexSection(indexSection.index, kPagerViewMaxSectionCount-1);
+        }
+        return TYMakeIndexSection(0, indexSection.section+1);
+    }
+    
+    if (indexSection.index > 0) {
+        return TYMakeIndexSection(indexSection.index-1, indexSection.section);
+    }
+    if (indexSection.section <= 0) {
+        return TYMakeIndexSection(indexSection.index, 0);
+    }
+    return TYMakeIndexSection(_numberOfItems-1, indexSection.section-1);
+}
+
+- (TYIndexSection)caculateIndexSectionWithOffsetX:(CGFloat)offsetX {
+    if (_numberOfItems <= 0) {
+        return TYMakeIndexSection(0, 0);
+    }
+     UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)_collectionView.collectionViewLayout;
+    CGFloat leftEdge = _isInfiniteLoop ? _layout.sectionInset.left : _layout.onlyOneSectionInset.left;
+    CGFloat width = CGRectGetWidth(_collectionView.frame);
+    CGFloat middleOffset = offsetX + width/2;
+    CGFloat itemWidth = layout.itemSize.width + layout.minimumInteritemSpacing;
+    NSInteger curIndex = 0;
+    NSInteger curSection = 0;
+    if (middleOffset - leftEdge >= 0) {
+        NSInteger itemIndex = (middleOffset - leftEdge+layout.minimumInteritemSpacing/2)/itemWidth;
+        if (itemIndex < 0) {
+            itemIndex = 0;
+        }else if (itemIndex >= _numberOfItems*kPagerViewMaxSectionCount) {
+            itemIndex = _numberOfItems*kPagerViewMaxSectionCount-1;
+        }
+        curIndex = itemIndex%_numberOfItems;
+        curSection = itemIndex/_numberOfItems;
+    }
+    return TYMakeIndexSection(curIndex, curSection);
+}
+
+- (CGFloat)caculateOffsetXAtIndexSection:(TYIndexSection)indexSection{
+    if (_numberOfItems == 0) {
+        return 0;
+    }
+    UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)_collectionView.collectionViewLayout;
+    UIEdgeInsets edge = _isInfiniteLoop ? _layout.sectionInset : _layout.onlyOneSectionInset;
+    CGFloat leftEdge = edge.left;
+    CGFloat rightEdge = edge.right;
+    CGFloat width = CGRectGetWidth(_collectionView.frame);
+    CGFloat itemWidth = layout.itemSize.width + layout.minimumInteritemSpacing;
+    CGFloat offsetX = 0;
+    if (!_isInfiniteLoop && !_layout.itemHorizontalCenter && indexSection.index == _numberOfItems - 1) {
+        offsetX = leftEdge + itemWidth*(indexSection.index + indexSection.section*_numberOfItems) - (width - itemWidth) -  layout.minimumInteritemSpacing + rightEdge;
+    }else {
+        offsetX = leftEdge + itemWidth*(indexSection.index + indexSection.section*_numberOfItems) - layout.minimumInteritemSpacing/2 - (width - itemWidth)/2;
+    }
+    return MAX(offsetX, 0);
+}
+
+- (void)resetPagerViewAtIndex:(NSInteger)index {
+    if (_didLayout && _firstScrollIndex >= 0) {
+        index = _firstScrollIndex;
+        _firstScrollIndex = -1;
+    }
+    if (index < 0) {
+        return;
+    }
+    if (index >= _numberOfItems) {
+        index = 0;
+    }
+    [self scrollToItemAtIndexSection:TYMakeIndexSection(index, _isInfiniteLoop ? kPagerViewMaxSectionCount/3 : 0) animate:NO];
+    if (!_isInfiniteLoop && _indexSection.index < 0) {
+        [self scrollViewDidScroll:_collectionView];
+    }
+}
+
+- (void)recyclePagerViewIfNeed {
+    if (!_isInfiniteLoop) {
+        return;
+    }
+    if (_indexSection.section > kPagerViewMaxSectionCount - kPagerViewMinSectionCount || _indexSection.section < kPagerViewMinSectionCount) {
+        [self resetPagerViewAtIndex:_indexSection.index];
+    }
+}
+
+#pragma mark - UICollectionViewDataSource
+
+- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
+    return _isInfiniteLoop ? kPagerViewMaxSectionCount : 1;
+}
+
+- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
+    _numberOfItems = [_dataSource numberOfItemsInPagerView:self];
+    return _numberOfItems;
+}
+
+- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
+    _dequeueSection = indexPath.section;
+    if (_dataSourceFlags.cellForItemAtIndex) {
+       return [_dataSource pagerView:self cellForItemAtIndex:indexPath.row];
+    }
+    NSAssert(NO, @"pagerView cellForItemAtIndex: is nil!");
+    return nil;
+}
+
+#pragma mark - UICollectionViewDelegateFlowLayout
+
+- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
+    if (!_isInfiniteLoop) {
+        return _layout.onlyOneSectionInset;
+    }
+    if (section == 0 ) {
+        return _layout.firstSectionInset;
+    }else if (section == kPagerViewMaxSectionCount -1) {
+        return _layout.lastSectionInset;
+    }
+    return _layout.middleSectionInset;
+}
+
+- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
+    UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
+    if ([_delegate respondsToSelector:@selector(pagerView:didSelectedItemCell:atIndex:)]) {
+        [_delegate pagerView:self didSelectedItemCell:cell atIndex:indexPath.item];
+    }
+    if ([_delegate respondsToSelector:@selector(pagerView:didSelectedItemCell:atIndexSection:)]) {
+        [_delegate pagerView:self didSelectedItemCell:cell atIndexSection:TYMakeIndexSection(indexPath.item, indexPath.section)];
+    }
+}
+
+#pragma mark - UIScrollViewDelegate
+
+- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
+    if (!_didLayout) {
+        return;
+    }
+    TYIndexSection newIndexSection =  [self caculateIndexSectionWithOffsetX:scrollView.contentOffset.x];
+    if (_numberOfItems <= 0 || ![self isValidIndexSection:newIndexSection]) {
+        NSLog(@"inVlaidIndexSection:(%ld,%ld)!",(long)newIndexSection.index,(long)newIndexSection.section);
+        return;
+    }
+    TYIndexSection indexSection = _indexSection;
+    _indexSection = newIndexSection;
+    
+    if (_delegateFlags.pagerViewDidScroll) {
+        [_delegate pagerViewDidScroll:self];
+    }
+    
+    if (_delegateFlags.didScrollFromIndexToNewIndex && !TYEqualIndexSection(_indexSection, indexSection)) {
+        //NSLog(@"curIndex %ld",(long)_indexSection.index);
+        [_delegate pagerView:self didScrollFromIndex:MAX(indexSection.index, 0) toIndex:_indexSection.index];
+    }
+}
+
+- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
+    if (_autoScrollInterval > 0) {
+        [self removeTimer];
+    }
+    _beginDragIndexSection = [self caculateIndexSectionWithOffsetX:scrollView.contentOffset.x];
+    if ([_delegate respondsToSelector:@selector(pagerViewWillBeginDragging:)]) {
+        [_delegate pagerViewWillBeginDragging:self];
+    }
+}
+
+- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
+    if (fabs(velocity.x) < 0.35 || !TYEqualIndexSection(_beginDragIndexSection, _indexSection)) {
+        targetContentOffset->x = [self caculateOffsetXAtIndexSection:_indexSection];
+        return;
+    }
+    TYPagerScrollDirection direction = TYPagerScrollDirectionRight;
+    if ((scrollView.contentOffset.x < 0 && targetContentOffset->x <= 0) || (targetContentOffset->x < scrollView.contentOffset.x && scrollView.contentOffset.x < scrollView.contentSize.width - scrollView.frame.size.width)) {
+        direction = TYPagerScrollDirectionLeft;
+    }
+    TYIndexSection indexSection = [self nearlyIndexPathForIndexSection:_indexSection direction:direction];
+    targetContentOffset->x = [self caculateOffsetXAtIndexSection:indexSection];
+}
+
+- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
+    if (_autoScrollInterval > 0) {
+        [self addTimer];
+    }
+    if ([_delegate respondsToSelector:@selector(pagerViewDidEndDragging:willDecelerate:)]) {
+        [_delegate pagerViewDidEndDragging:self willDecelerate:decelerate];
+    }
+}
+
+- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
+    if ([_delegate respondsToSelector:@selector(pagerViewWillBeginDecelerating:)]) {
+        [_delegate pagerViewWillBeginDecelerating:self];
+    }
+}
+
+- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
+    [self recyclePagerViewIfNeed];
+    if ([_delegate respondsToSelector:@selector(pagerViewDidEndDecelerating:)]) {
+        [_delegate pagerViewDidEndDecelerating:self];
+    }
+}
+
+- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
+    [self recyclePagerViewIfNeed];
+    if ([_delegate respondsToSelector:@selector(pagerViewDidEndScrollingAnimation:)]) {
+        [_delegate pagerViewDidEndScrollingAnimation:self];
+    }
+}
+
+#pragma mark - TYCyclePagerTransformLayoutDelegate
+
+- (void)pagerViewTransformLayout:(TYCyclePagerTransformLayout *)pagerViewTransformLayout initializeTransformAttributes:(UICollectionViewLayoutAttributes *)attributes {
+    if (_delegateFlags.initializeTransformAttributes) {
+        [_delegate pagerView:self initializeTransformAttributes:attributes];
+    }
+}
+
+- (void)pagerViewTransformLayout:(TYCyclePagerTransformLayout *)pagerViewTransformLayout applyTransformToAttributes:(UICollectionViewLayoutAttributes *)attributes {
+    if (_delegateFlags.applyTransformToAttributes) {
+        [_delegate pagerView:self applyTransformToAttributes:attributes];
+    }
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    BOOL needUpdateLayout = !CGRectEqualToRect(_collectionView.frame, self.bounds);
+    _collectionView.frame = self.bounds;
+    if ((_indexSection.section < 0 || needUpdateLayout) && (_numberOfItems > 0 || _didReloadData)) {
+        _didLayout = YES;
+        [self setNeedUpdateLayout];
+    }
+}
+
+- (void)dealloc {
+    ((TYCyclePagerTransformLayout *)_collectionView.collectionViewLayout).delegate = nil;
+    _collectionView.delegate = nil;
+    _collectionView.dataSource = nil;
+}
+
+@end
+
+

+ 47 - 0
KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYPageControl.h

@@ -0,0 +1,47 @@
+//
+//  TYPageControl.h
+//  TYCyclePagerViewDemo
+//
+//  Created by tany on 2017/6/20.
+//  Copyright © 2017年 tany. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TYPageControl : UIControl
+
+@property (nonatomic, assign) NSInteger numberOfPages;          // default is 0
+@property (nonatomic, assign) NSInteger currentPage;            // default is 0. value pinned to 0..numberOfPages-1
+
+@property (nonatomic, assign) BOOL hidesForSinglePage;          // hide the the indicator if there is only one page. default is NO
+
+@property (nonatomic, assign) CGFloat pageIndicatorSpaing;
+@property (nonatomic, assign) UIEdgeInsets contentInset; // center will ignore this
+@property (nonatomic, assign ,readonly) CGSize contentSize; // real content size
+
+// override super 
+//@property (nonatomic, assign) UIControlContentVerticalAlignment contentVerticalAlignment;     // how to position content vertically inside control. default is center
+//@property (nonatomic, assign) UIControlContentHorizontalAlignment contentHorizontalAlignment; // how to position content hozontally inside control. default is center
+
+// indicatorTint color
+@property (nullable, nonatomic,strong) UIColor *pageIndicatorTintColor;
+@property (nullable, nonatomic,strong) UIColor *currentPageIndicatorTintColor;
+
+// indicator image
+@property (nullable, nonatomic,strong) UIImage *pageIndicatorImage;
+@property (nullable, nonatomic,strong) UIImage *currentPageIndicatorImage;
+
+@property (nonatomic, assign) UIViewContentMode indicatorImageContentMode; // default is UIViewContentModeCenter
+
+@property (nonatomic, assign) CGSize pageIndicatorSize; // indicator size
+@property (nonatomic, assign) CGSize currentPageIndicatorSize; // default pageIndicatorSize
+
+@property (nonatomic, assign) CGFloat animateDuring; // default 0.3
+
+- (void)setCurrentPage:(NSInteger)currentPage animate:(BOOL)animate;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 285 - 0
KulexiuForStudent/KulexiuForStudent/Common/ThirdPart/TYCyclePagerView/TYPageControl.m

@@ -0,0 +1,285 @@
+//
+//  TYPageControl.m
+//  TYCyclePagerViewDemo
+//
+//  Created by tany on 2017/6/20.
+//  Copyright © 2017年 tany. All rights reserved.
+//
+
+#import "TYPageControl.h"
+
+@interface TYPageControl ()
+// UI
+@property (nonatomic, strong) NSArray<UIImageView *> *indicatorViews;
+
+// Data
+@property (nonatomic, assign) BOOL forceUpdate;
+
+@end
+
+@implementation TYPageControl
+
+#pragma mark - life cycle
+
+- (instancetype)initWithFrame:(CGRect)frame {
+    if (self = [super initWithFrame:frame]) {
+        [self configurePropertys];
+    }
+    return self;
+}
+
+- (instancetype)initWithCoder:(NSCoder *)aDecoder {
+    if (self = [super initWithCoder:aDecoder]) {
+        [self configurePropertys];
+    }
+    return self;
+}
+
+- (void)configurePropertys {
+    self.userInteractionEnabled = NO;
+    _forceUpdate = NO;
+    _animateDuring = 0.3;
+    _pageIndicatorSpaing = 10;
+    _indicatorImageContentMode = UIViewContentModeCenter;
+    _pageIndicatorSize = CGSizeMake(6,6);
+    _currentPageIndicatorSize = _pageIndicatorSize;
+    _pageIndicatorTintColor = [UIColor colorWithRed:128/255. green:128/255. blue:128/255. alpha:1];
+    _currentPageIndicatorTintColor = [UIColor whiteColor];
+}
+
+- (void)willMoveToSuperview:(UIView *)newSuperview {
+    [super willMoveToSuperview:newSuperview];
+    if (newSuperview) {
+        _forceUpdate = YES;
+        [self updateIndicatorViews];
+        _forceUpdate = NO;
+    }
+}
+
+#pragma mark - getter setter
+
+- (CGSize)contentSize {
+    CGFloat width = (_indicatorViews.count - 1) * (_pageIndicatorSize.width + _pageIndicatorSpaing) + _pageIndicatorSize.width + _contentInset.left +_contentInset.right;
+    CGFloat height = _currentPageIndicatorSize.height + _contentInset.top + _contentInset.bottom;
+    return CGSizeMake(width, height);
+}
+
+- (void)setNumberOfPages:(NSInteger)numberOfPages {
+    if (numberOfPages == _numberOfPages) {
+        return;
+    }
+    _numberOfPages = numberOfPages;
+    if (_currentPage >= numberOfPages) {
+        _currentPage = 0;
+    }
+    [self updateIndicatorViews];
+    if (_indicatorViews.count > 0) {
+        [self setNeedsLayout];
+    }
+}
+
+- (void)setCurrentPage:(NSInteger)currentPage {
+    if (_currentPage == currentPage || _indicatorViews.count <= currentPage) {
+        return;
+    }
+    _currentPage = currentPage;
+    if (!CGSizeEqualToSize(_currentPageIndicatorSize, _pageIndicatorSize)) {
+        [self setNeedsLayout];
+    }
+    [self updateIndicatorViewsBehavior];
+    if (self.userInteractionEnabled) {
+        [self sendActionsForControlEvents:UIControlEventValueChanged];
+    }
+}
+
+- (void)setCurrentPage:(NSInteger)currentPage animate:(BOOL)animate {
+    if (animate) {
+        [UIView animateWithDuration:_animateDuring animations:^{
+            [self setCurrentPage:currentPage];
+        }];
+    }else {
+        [self setCurrentPage:currentPage];
+    }
+}
+
+- (void)setPageIndicatorImage:(UIImage *)pageIndicatorImage {
+    _pageIndicatorImage = pageIndicatorImage;
+    [self updateIndicatorViewsBehavior];
+}
+
+- (void)setCurrentPageIndicatorImage:(UIImage *)currentPageIndicatorImage {
+    _currentPageIndicatorImage = currentPageIndicatorImage;
+    [self updateIndicatorViewsBehavior];
+}
+
+- (void)setPageIndicatorTintColor:(UIColor *)pageIndicatorTintColor {
+    _pageIndicatorTintColor = pageIndicatorTintColor;
+    [self updateIndicatorViewsBehavior];
+}
+
+- (void)setCurrentPageIndicatorTintColor:(UIColor *)currentPageIndicatorTintColor {
+    _currentPageIndicatorTintColor = currentPageIndicatorTintColor;
+    [self updateIndicatorViewsBehavior];
+}
+
+- (void)setPageIndicatorSize:(CGSize)pageIndicatorSize {
+    if (CGSizeEqualToSize(_pageIndicatorSize, pageIndicatorSize)) {
+        return;
+    }
+    _pageIndicatorSize = pageIndicatorSize;
+    if (CGSizeEqualToSize(_currentPageIndicatorSize, CGSizeZero) || (_currentPageIndicatorSize.width < pageIndicatorSize.width && _currentPageIndicatorSize.height < pageIndicatorSize.height)) {
+        _currentPageIndicatorSize = pageIndicatorSize;
+    }
+    if (_indicatorViews.count > 0) {
+        [self setNeedsLayout];
+    }
+}
+
+- (void)setPageIndicatorSpaing:(CGFloat)pageIndicatorSpaing {
+    _pageIndicatorSpaing = pageIndicatorSpaing;
+    if (_indicatorViews.count > 0) {
+        [self setNeedsLayout];
+    }
+}
+
+- (void)setCurrentPageIndicatorSize:(CGSize)currentPageIndicatorSize {
+    if (CGSizeEqualToSize(_currentPageIndicatorSize, currentPageIndicatorSize)) {
+        return;
+    }
+    _currentPageIndicatorSize = currentPageIndicatorSize;
+    if (_indicatorViews.count > 0) {
+        [self setNeedsLayout];
+    }
+}
+
+- (void)setContentHorizontalAlignment:(UIControlContentHorizontalAlignment)contentHorizontalAlignment {
+    [super setContentHorizontalAlignment:contentHorizontalAlignment];
+    if (_indicatorViews.count > 0) {
+        [self setNeedsLayout];
+    }
+}
+
+- (void)setContentVerticalAlignment:(UIControlContentVerticalAlignment)contentVerticalAlignment {
+    [super setContentVerticalAlignment:contentVerticalAlignment];
+    if (_indicatorViews.count > 0) {
+        [self setNeedsLayout];
+    }
+}
+
+#pragma mark - update indicator
+
+- (void)updateIndicatorViews {
+    if (!self.superview && !_forceUpdate) {
+        return;
+    }
+    if (_indicatorViews.count == _numberOfPages) {
+        [self updateIndicatorViewsBehavior];
+        return;
+    }
+    NSMutableArray *indicatorViews = _indicatorViews ? [_indicatorViews mutableCopy] :[NSMutableArray array];
+    if (indicatorViews.count < _numberOfPages) {
+        for (NSInteger idx = indicatorViews.count; idx < _numberOfPages; ++idx) {
+            UIImageView *indicatorView = [[UIImageView alloc]init];
+            indicatorView.contentMode = _indicatorImageContentMode;
+            [self addSubview:indicatorView];
+            [indicatorViews addObject:indicatorView];
+        }
+    }else if (indicatorViews.count > _numberOfPages) {
+        for (NSInteger idx = indicatorViews.count - 1; idx >= _numberOfPages; --idx) {
+            UIImageView *indicatorView = indicatorViews[idx];
+            [indicatorView removeFromSuperview];
+            [indicatorViews removeObjectAtIndex:idx];
+        }
+    }
+    _indicatorViews = [indicatorViews copy];
+    [self updateIndicatorViewsBehavior];
+}
+
+- (void)updateIndicatorViewsBehavior {
+    if (_indicatorViews.count == 0 || (!self.superview && !_forceUpdate)) {
+        return;
+    }
+    if (_hidesForSinglePage && _indicatorViews.count == 1) {
+        UIImageView *indicatorView = _indicatorViews.lastObject;
+        indicatorView.hidden = YES;
+        return;
+    }
+    NSInteger index = 0;
+    for (UIImageView *indicatorView in _indicatorViews) {
+        if (_pageIndicatorImage) {
+            indicatorView.contentMode = _indicatorImageContentMode;
+            indicatorView.image = _currentPage == index ? _currentPageIndicatorImage : _pageIndicatorImage;
+        }else {
+            indicatorView.image = nil;
+            indicatorView.backgroundColor = _currentPage == index ? _currentPageIndicatorTintColor : _pageIndicatorTintColor;
+        }
+        indicatorView.hidden = NO;
+        ++index;
+    }
+}
+
+#pragma mark - layout
+
+- (void)layoutIndicatorViews {
+    if (_indicatorViews.count == 0) {
+        return;
+    }
+    CGFloat orignX = 0;
+    CGFloat centerY = 0;
+    CGFloat pageIndicatorSpaing = _pageIndicatorSpaing;
+    switch (self.contentHorizontalAlignment) {
+        case UIControlContentHorizontalAlignmentCenter:
+            // ignore contentInset
+            orignX = (CGRectGetWidth(self.frame) - (_indicatorViews.count - 1) * (_pageIndicatorSize.width + _pageIndicatorSpaing) - _currentPageIndicatorSize.width)/2;
+            break;
+        case UIControlContentHorizontalAlignmentLeft:
+            orignX = _contentInset.left;
+            break;
+        case UIControlContentHorizontalAlignmentRight:
+            orignX = CGRectGetWidth(self.frame) - ((_indicatorViews.count - 1) * (_pageIndicatorSize.width + _pageIndicatorSpaing) + _currentPageIndicatorSize.width) - _contentInset.right;
+            break;
+        case UIControlContentHorizontalAlignmentFill:
+            orignX = _contentInset.left;
+            if (_indicatorViews.count > 1) {
+                pageIndicatorSpaing = (CGRectGetWidth(self.frame) - _contentInset.left - _contentInset.right - _pageIndicatorSize.width - (_indicatorViews.count - 1) * _pageIndicatorSize.width)/(_indicatorViews.count - 1);
+            }
+            break;
+        default:
+            break;
+    }
+    switch (self.contentVerticalAlignment) {
+        case UIControlContentVerticalAlignmentCenter:
+            centerY = CGRectGetHeight(self.frame)/2;
+            break;
+        case UIControlContentVerticalAlignmentTop:
+            centerY = _contentInset.top + _currentPageIndicatorSize.height/2;
+            break;
+        case UIControlContentVerticalAlignmentBottom:
+            centerY = CGRectGetHeight(self.frame) - _currentPageIndicatorSize.height/2 - _contentInset.bottom;
+            break;
+        case UIControlContentVerticalAlignmentFill:
+            centerY = (CGRectGetHeight(self.frame) - _contentInset.top - _contentInset.bottom)/2 + _contentInset.top;
+            break;
+        default:
+            break;
+    }
+    NSInteger index = 0;
+    for (UIImageView *indicatorView in _indicatorViews) {
+        if (_pageIndicatorImage) {
+            indicatorView.layer.cornerRadius = 0;
+        }else {
+            indicatorView.layer.cornerRadius = _currentPage == index ? _currentPageIndicatorSize.height/2 : _pageIndicatorSize.height/2;
+        }
+        CGSize size = index == _currentPage ? _currentPageIndicatorSize : _pageIndicatorSize;
+        indicatorView.frame = CGRectMake(orignX, centerY - size.height/2, size.width, size.height);
+        orignX += size.width + pageIndicatorSpaing;
+        ++index;
+    }
+}
+
+- (void)layoutSubviews {
+    [super layoutSubviews];
+    [self layoutIndicatorViews];
+}
+
+@end

+ 2 - 0
KulexiuForStudent/KulexiuForStudent/Common/Tools/KSVideoHelper.h

@@ -13,6 +13,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 + (void)getVideoPreviewImageUrl:(NSString *)videoUrl forImageView:(UIImageView *)imageView placeholder:(UIImage *)placeHolder;
 
++ (NSInteger)getVideoDuration:(NSString *)videoUrl;
+
 @end
 
 NS_ASSUME_NONNULL_END

+ 6 - 0
KulexiuForStudent/KulexiuForStudent/Common/Tools/KSVideoHelper.m

@@ -60,7 +60,13 @@
         });
           
     });
+}
 
++ (NSInteger)getVideoDuration:(NSString *)videoUrl {
+    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL URLWithString:videoUrl] options:nil];
+    float second = asset.duration.value / asset.duration.timescale;
+    NSString *duration = [NSString stringWithFormat:@"%.0f",second];
+    return [duration integerValue];
 }
 
 @end

+ 15 - 7
KulexiuForStudent/KulexiuForStudent/Module/Course/View/CourseNavView.xib

@@ -13,6 +13,9 @@
             <rect key="frame" x="0.0" y="0.0" width="414" height="96"/>
             <autoresizingMask key="autoresizingMask"/>
             <subviews>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="nav_shade" translatesAutoresizingMaskIntoConstraints="NO" id="2Mn-lH-wbE">
+                    <rect key="frame" x="0.0" y="0.0" width="414" height="96"/>
+                </imageView>
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="39y-6W-6HN">
                     <rect key="frame" x="0.0" y="95" width="414" height="1"/>
                     <color key="backgroundColor" red="0.94901960784313721" green="0.94901960784313721" blue="0.94901960784313721" alpha="1" colorSpace="calibratedRGB"/>
@@ -21,7 +24,7 @@
                     </constraints>
                 </view>
                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2022年9月" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GTO-1Q-b8D">
-                    <rect key="frame" x="161" y="50" width="92" height="25"/>
+                    <rect key="frame" x="161" y="57.5" width="92" height="25"/>
                     <constraints>
                         <constraint firstAttribute="height" constant="25" id="TrO-ED-Ma7"/>
                     </constraints>
@@ -29,15 +32,15 @@
                     <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
                     <nil key="highlightedColor"/>
                 </label>
-                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="down_arrow" translatesAutoresizingMaskIntoConstraints="NO" id="Aty-TD-8f6">
-                    <rect key="frame" x="258" y="59.5" width="8" height="6"/>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="sort_down" translatesAutoresizingMaskIntoConstraints="NO" id="Aty-TD-8f6">
+                    <rect key="frame" x="258" y="67" width="8" height="6"/>
                     <constraints>
                         <constraint firstAttribute="height" constant="6" id="FGW-RQ-sze"/>
                         <constraint firstAttribute="width" constant="8" id="FOk-8J-bnb"/>
                     </constraints>
                 </imageView>
                 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cUO-Eu-mKa">
-                    <rect key="frame" x="161" y="42.5" width="105" height="40"/>
+                    <rect key="frame" x="161" y="50" width="105" height="40"/>
                     <constraints>
                         <constraint firstAttribute="height" constant="40" id="rgA-0Q-cHA"/>
                     </constraints>
@@ -47,17 +50,21 @@
                     </connections>
                 </button>
             </subviews>
-            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
             <constraints>
+                <constraint firstAttribute="trailing" secondItem="2Mn-lH-wbE" secondAttribute="trailing" id="0Gu-Hc-JCq"/>
                 <constraint firstAttribute="trailing" secondItem="39y-6W-6HN" secondAttribute="trailing" id="0Sc-7V-pPL"/>
                 <constraint firstItem="Aty-TD-8f6" firstAttribute="leading" secondItem="GTO-1Q-b8D" secondAttribute="trailing" constant="5" id="5aF-jm-Cpl"/>
+                <constraint firstAttribute="bottom" secondItem="2Mn-lH-wbE" secondAttribute="bottom" id="Bbq-2t-Nex"/>
                 <constraint firstItem="Aty-TD-8f6" firstAttribute="centerY" secondItem="GTO-1Q-b8D" secondAttribute="centerY" id="KGA-yE-Id2"/>
-                <constraint firstItem="39y-6W-6HN" firstAttribute="top" secondItem="GTO-1Q-b8D" secondAttribute="bottom" constant="20" id="Um0-5Z-VgP"/>
                 <constraint firstAttribute="bottom" secondItem="39y-6W-6HN" secondAttribute="bottom" id="Wn3-ho-ctn"/>
+                <constraint firstItem="39y-6W-6HN" firstAttribute="top" secondItem="cUO-Eu-mKa" secondAttribute="bottom" constant="5" id="ZXO-fp-tR2"/>
                 <constraint firstItem="39y-6W-6HN" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="ad9-yT-IV2"/>
                 <constraint firstItem="Aty-TD-8f6" firstAttribute="trailing" secondItem="cUO-Eu-mKa" secondAttribute="trailing" id="deD-vu-Bdf"/>
+                <constraint firstItem="2Mn-lH-wbE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="eV7-kq-Eb2"/>
                 <constraint firstItem="GTO-1Q-b8D" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="fnH-cs-lh8"/>
                 <constraint firstItem="GTO-1Q-b8D" firstAttribute="leading" secondItem="cUO-Eu-mKa" secondAttribute="leading" id="k3o-sg-pI4"/>
+                <constraint firstItem="2Mn-lH-wbE" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="vUC-b8-U6j"/>
                 <constraint firstItem="GTO-1Q-b8D" firstAttribute="centerY" secondItem="cUO-Eu-mKa" secondAttribute="centerY" id="vpg-A7-bif"/>
             </constraints>
             <nil key="simulatedTopBarMetrics"/>
@@ -71,6 +78,7 @@
         </view>
     </objects>
     <resources>
-        <image name="down_arrow" width="8" height="6"/>
+        <image name="nav_shade" width="375" height="90"/>
+        <image name="sort_down" width="8" height="6"/>
     </resources>
 </document>

+ 955 - 6
KulexiuForStudent/KulexiuForStudent/Module/Home/Controller/HomeViewController.m

@@ -6,9 +6,91 @@
 //
 
 #import "HomeViewController.h"
+#import "KSBaseWKWebViewController.h"
+#import "NoticeMessageViewController.h"
 #import "SubjectChooseViewController.h"
+#import "HomeNavView.h"
+#import "HomeBannerView.h"
+#import <UIButton+WebCache.h>
+#import "TYCyclePagerView.h"
+#import "TYPageControl.h"
+#import "HomeBannerCell.h"
 
-@interface HomeViewController ()
+#import "HomeBannerView.h"
+#import "HomeBannerCell.h"
+#import "HomeButtonView.h"
+#import "KSHomeButton.h"
+
+#import "HomeHotAlbumView.h"
+#import "HomeHotAlbumCell.h"
+
+#import "HomeHotCourseView.h"
+#import "HomeIntroduceView.h"
+#import "TeacherShowCell.h"
+#import "HotInformationHeadView.h"
+#import "TeacherStyleModel.h"
+
+#import "HomeInformationCell.h"
+#import "HomeMessageModel.h"
+
+#import "StudentInfoModel.h"
+#import "UserInfoManager.h"
+
+#import "HomeCourseTipsView.h"
+
+#import "HomeLiveCouseCell.h"
+#import "HomeLiveGroupModel.h"
+#import "HomeVideoCourseCell.h"
+#import "HomeVideoGroupModel.h"
+
+#define BUTTONWIDTH (80)
+#define BUTTONHEIGHT (80)
+
+@interface HomeViewController ()<TYCyclePagerViewDataSource,TYCyclePagerViewDelegate,UITableViewDelegate,UITableViewDataSource,UIScrollViewDelegate,UICollectionViewDelegate, UICollectionViewDelegateFlowLayout,UICollectionViewDataSource>
+
+@property (nonatomic, strong) UITableView *tableView;
+
+@property (nonatomic, strong) HomeNavView *navView;
+
+@property (nonatomic, strong) UIView *tableHeaderView;  // headView;
+
+@property (nonatomic, strong) TYPageControl *pageControl;
+@property (nonatomic, strong) HomeBannerView *bannerView;  // banner container
+@property (nonatomic, strong) TYCyclePagerView *bannerScroll; // 活动
+@property (nonatomic, strong) NSMutableArray *bannerArray; // banner 数据
+
+@property (nonatomic, strong) HomeButtonView *buttonContainer; // button container
+@property (nonatomic, strong) UIScrollView *buttonScrollView;
+@property (nonatomic, strong) NSMutableArray *buttonArray; // button 内容
+@property (nonatomic, assign) NSInteger buttonDotWidth;
+
+@property (nonatomic, strong) HomeHotAlbumView *albumView; // albumView container
+@property (nonatomic, strong) NSMutableArray *albumArray;  // 热门专辑
+@property (nonatomic, strong) UICollectionView *albumCollectionView; // 专辑容器
+
+@property (nonatomic, strong) HomeHotCourseView *courseView; // course container
+@property (nonatomic, strong) UIScrollView *courseScroll;    // 课程scroll
+@property (nonatomic, strong) UITableView *liveCourseTable;  // 直播课table
+@property (nonatomic, strong) UITableView *videoCourseTable; // 视频课table
+@property (nonatomic, strong) NSMutableArray *videoCourseArray;
+@property (nonatomic, strong) NSMutableArray *liveCourseArray;
+
+@property (nonatomic, strong) HomeIntroduceView *teacherView; // teacher container
+@property (nonatomic, strong) UICollectionView *infoCollectionView; // 老师风采简介
+@property (nonatomic, strong) NSMutableArray *teacherArray;
+
+
+@property (nonatomic, strong) HotInformationHeadView *informationHeadView; // information Header
+
+@property (nonatomic, strong) StudentInfoModel *mineInfo;
+
+@property (nonatomic, assign) BOOL hasCourseTips;
+
+@property (nonatomic, strong) HomeCourseTipsView *tipsCourseView;
+
+@property (nonatomic, assign) BOOL isChooseLive; // 是否选择直播课
+
+@property (nonatomic, assign) NSInteger courseCount;
 
 @end
 
@@ -17,24 +99,891 @@
 - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view.
-    [self requstSubject];
+    self.ks_prefersNavigationBarHidden = YES;
+    self.isChooseLive = YES;
+    [self configNavView];
+//    [self requestUserInfo];
+    [self configUI];
 }
 
-- (void)requstSubject {
-    [KSNetworkingManager studentQuerySubject:KS_GET success:^(NSDictionary * _Nonnull dic) {
-        if ([dic integerValueForKey:@"code"] == 200) {
-            [self showInstrumentView];
+- (void)viewWillAppear:(BOOL)animated {
+    [super viewWillAppear:animated];
+    [self requestData];
+}
+
+- (void)configNavView {
+    [self.scrollView removeFromSuperview];
+    [self.view addSubview:self.navView];
+    [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.mas_equalTo(self.view);
+        make.height.mas_equalTo(kNaviBarHeight);
+    }];
+}
+
+
+- (void)configUI {
+    [self.scrollView removeFromSuperview];
+    [self.view addSubview:self.tableView];
+    [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.bottom.mas_equalTo(self.view);
+        make.top.mas_equalTo(self.navView.mas_bottom);
+    }];
+    if (@available(iOS 11.0, *)) {
+        self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
+    } else {
+        // Fallback on earlier versions
+        self.automaticallyAdjustsScrollViewInsets = NO;
+    }
+    self.tableView.tableHeaderView = self.tableHeaderView;
+    MJWeakSelf;
+    self.tableView.mj_header = [KSGifRefreshHeader headerWithRefreshingBlock:^{
+        [weakSelf requestData];
+    }];
+}
+
+- (void)requestData {
+    [self requestUserInfo]; // 获取老师声部
+    // 栅栏函数
+    [self requestCourseInfo];
+    [self requestTeacherStyle];
+}
+
+- (void)requestCourseInfo {
+    [KSNetworkingManager homeQueryLiveAndVideo:KS_GET success:^(NSDictionary * _Nonnull dic) {
+        if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
+            NSDictionary *sourceDic = [dic dictionaryValueForKey:@"data"];
+            NSArray *liveList = [sourceDic arrayValueForKey:@"liveList"];
+            NSMutableArray *liveCourse = [NSMutableArray array];
+            for (NSDictionary *parm in liveList) {
+                HomeLiveGroupModel *model = [[HomeLiveGroupModel alloc] initWithDictionary:parm];
+                [liveCourse addObject:model];
+            }
+            self.liveCourseArray = [NSMutableArray arrayWithArray:liveCourse];
+            
+            NSArray *videoList = [sourceDic arrayValueForKey:@"videoList"];
+            NSMutableArray *videoCourse = [NSMutableArray array];
+            for (NSDictionary *parm in videoList) {
+                HomeVideoGroupModel *model = [[HomeVideoGroupModel alloc] initWithDictionary:parm];
+                [videoCourse addObject:model];
+            }
+            self.videoCourseArray = [NSMutableArray arrayWithArray:videoCourse];
+        }
+        else {
+            [self MBPShow:MESSAGEKEY];
         }
     } faliure:^(NSError * _Nonnull error) {
         
     }];
 }
 
+
+- (void)requestUserInfo {
+    [KSNetworkingManager queryStudentInfoRequest:KS_GET success:^(NSDictionary * _Nonnull dic) {
+        if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
+            self.mineInfo = [[StudentInfoModel alloc] initWithDictionary:[dic dictionaryValueForKey:@"data"]];
+            NSString *rongToken = UserDefault(RongTokenKey);
+            if ([NSString isEmptyString:rongToken]) {
+                [USER_MANAGER queryUserInfoConnectRongCloud:YES];
+            }
+            [self refreshNavView];
+        }
+        else {
+            [self MBPShow:MESSAGEKEY];
+        }
+    } faliure:^(NSError * _Nonnull error) {
+        
+    }];
+}
+
+- (void)requestTeacherStyle {
+    
+    [KSNetworkingManager homeQueryTeacherStyle:KS_POST page:1 rows:10 success:^(NSDictionary * _Nonnull dic) {
+        [self.tableView.mj_header endRefreshing];
+        if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
+            NSArray *sourceArray = [[dic dictionaryValueForKey:@"data"] arrayValueForKey:@"rows"];
+            NSMutableArray *styleArray = [NSMutableArray array];
+            for (NSDictionary *parm in sourceArray) {
+                TeacherStyleModel *model = [[TeacherStyleModel alloc] initWithDictionary:parm];
+                [styleArray addObject:model];
+            }
+            self.teacherArray = [NSMutableArray arrayWithArray:styleArray];
+        }
+        else {
+            [self MBPShow:MESSAGEKEY];
+        }
+        // 回调
+        [self refreshUIDisplay];
+    } faliure:^(NSError * _Nonnull error) {
+        [self.tableView.mj_header endRefreshing];
+    }];
+}
+
+- (void)refreshNavView {
+    NSString *subjectName = @"";
+    if ([NSString isEmptyString:self.mineInfo.subjectName]) {
+        subjectName = @"请选择乐器";
+    }
+    else {
+        subjectName = self.mineInfo.subjectName;
+    }
+    self.navView.subjectName.text = subjectName;
+}
+
+- (void)refreshUIDisplay {
+    [self.tableHeaderView removeAllSubViews];
+    
+    CGFloat tableHeaderHeight = 0.0f;
+    
+    NSMutableArray *banner = [NSMutableArray array];
+    
+    for (NSInteger i = 0; i < 4; i++) {
+        HomeMessageModel *model = [[HomeMessageModel alloc] init];
+        [banner addObject:model];
+    }
+    self.bannerArray = [NSMutableArray arrayWithArray:banner];
+    
+    if (self.bannerArray.count) {
+        [self.tableHeaderView addSubview:self.bannerView];
+        CGFloat bannerHeight = [HomeBannerView getViewHeight];
+        tableHeaderHeight += bannerHeight;
+        [self.bannerView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.tableHeaderView);
+            make.top.mas_equalTo(self.tableHeaderView.mas_top);
+            make.height.mas_equalTo(bannerHeight);
+        }];
+        [self refreshBannaerView];
+    }
+
+    NSMutableArray *buttonArr = [NSMutableArray array];
+    
+    for (NSInteger i = 0; i < 4; i++) {
+        HomeMessageModel *model = [[HomeMessageModel alloc] init];
+        [buttonArr addObject:model];
+    }
+    self.buttonArray = [NSMutableArray arrayWithArray:buttonArr];
+    
+    if (self.buttonArray.count) {
+        [self.tableHeaderView addSubview:self.buttonContainer];
+        CGFloat buttonViewHeight = [HomeButtonView getViewHeight];
+        [self.buttonContainer mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.tableHeaderView);
+            make.top.mas_equalTo(self.tableHeaderView.mas_top).offset(tableHeaderHeight);
+            make.height.mas_equalTo(buttonViewHeight);
+        }];
+        tableHeaderHeight += buttonViewHeight;
+        [self showButtonMessage];
+    }
+    
+    // 如果有最近课程
+    self.hasCourseTips = YES;
+    if (self.hasCourseTips) { // 课程提醒
+        [self.tableHeaderView addSubview:self.tipsCourseView];
+        CGFloat tipsViewHeight = [HomeCourseTipsView getViewHeight];
+        [self.tipsCourseView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.tableHeaderView);
+            make.top.mas_equalTo(self.tableHeaderView.mas_top).offset(tableHeaderHeight);
+            make.height.mas_equalTo(tipsViewHeight);
+        }];
+        tableHeaderHeight += tipsViewHeight;
+        // 渲染页面
+    }
+    
+    NSMutableArray *albumArr = [NSMutableArray array];
+    for (NSInteger i = 0; i < 10; i++) {
+        HomeMessageModel *model = [[HomeMessageModel alloc] init];
+        [albumArr addObject:model];
+    }
+    self.albumArray = [NSMutableArray arrayWithArray:albumArr];
+    
+    if (self.albumArray.count) { // 热门专辑
+        [self.tableHeaderView addSubview:self.albumView];
+        CGFloat albumHeight = [HomeHotAlbumView getViewHeight];
+        [self.albumView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.tableHeaderView);
+            make.top.mas_equalTo(self.tableHeaderView.mas_top).offset(tableHeaderHeight);
+            make.height.mas_equalTo(albumHeight);
+        }];
+        tableHeaderHeight += albumHeight;
+    }
+    
+    // 课程
+    if (self.liveCourseArray.count && self.videoCourseArray.count) {
+        self.courseCount = self.liveCourseArray.count >= self.videoCourseArray.count ? self.videoCourseArray.count : self.liveCourseArray.count;
+        [self.tableHeaderView addSubview:self.courseView];
+        // 根据课程返回数据显示高度
+        CGFloat courseViewHeight = [self.courseView getViewHeightWithCount:self.courseCount];
+        [self.courseView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.tableHeaderView);
+            make.top.mas_equalTo(self.tableHeaderView.mas_top).offset(tableHeaderHeight);
+            make.height.mas_equalTo(courseViewHeight);
+        }];
+        [self.courseScroll removeAllSubViews];
+        self.courseScroll.contentSize = CGSizeMake(KPortraitWidth * 2, courseViewHeight - 59);
+        [self.courseScroll addSubview:self.liveCourseTable];
+        [self.liveCourseTable mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(self.courseScroll);
+            make.top.bottom.mas_equalTo(self.courseView.courseContainer);
+            make.width.mas_equalTo(KPortraitWidth);
+        }];
+        [self.courseScroll addSubview:self.videoCourseTable];
+        [self.videoCourseTable mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.mas_equalTo(_courseScroll.mas_left).offset(KPortraitWidth);
+            make.top.bottom.mas_equalTo(self.courseView.courseContainer);
+            make.width.mas_equalTo(KPortraitWidth);
+        }];
+        tableHeaderHeight += courseViewHeight;
+        [self.liveCourseTable reloadData];
+        [self.videoCourseTable reloadData];
+    }
+    if (self.teacherArray.count) {
+        [self.tableHeaderView addSubview:self.teacherView];
+        CGFloat teacherContentHeight = [self.teacherView getViewHeightWithSourceCount:self.teacherArray.count];
+        
+        [self.teacherView mas_remakeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.tableHeaderView);
+            make.top.mas_equalTo(self.tableHeaderView.mas_top).offset(tableHeaderHeight);
+            make.height.mas_equalTo(teacherContentHeight);
+        }];
+        tableHeaderHeight += teacherContentHeight;
+    }
+    
+    [self.tableHeaderView addSubview:self.informationHeadView];
+    CGFloat informationHeadHeight = [HotInformationHeadView getViewHeight];
+    [self.informationHeadView mas_remakeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.mas_equalTo(self.tableHeaderView);
+        make.top.mas_equalTo(self.tableHeaderView.mas_top).offset(tableHeaderHeight);
+        make.height.mas_equalTo(informationHeadHeight);
+    }];
+    tableHeaderHeight += informationHeadHeight;
+    
+    // test
+    NSMutableArray *sourceArray = [NSMutableArray array];
+    
+    for (NSInteger i = 0; i < 4; i++) {
+        HomeMessageModel *model = [[HomeMessageModel alloc] init];
+        [sourceArray addObject:model];
+    }
+    self.dataArray = [NSMutableArray arrayWithArray:sourceArray];
+    
+    self.tableHeaderView.frame = CGRectMake(0, 0, KPortraitWidth, tableHeaderHeight);
+    [self.tableView reloadData];
+}
+
+- (void)refreshBannaerView {
+    if (self.bannerArray.count > 1) {
+        self.bannerScroll.autoScrollInterval = 3.0f;
+        [self.bannerScroll addSubview:self.pageControl];
+    }
+    else {
+        self.bannerScroll.autoScrollInterval = 0;
+        [self.pageControl removeFromSuperview];
+    }
+    _pageControl.numberOfPages = self.bannerArray.count;
+    [self.bannerScroll reloadData];
+}
+
+- (void)showButtonMessage {
+    // 添加按钮
+    if (self.buttonArray.count > 4) { // 大于4个显示底部滚动视图
+        self.buttonContainer.buttonPageCtrl.hidden = NO;
+        self.buttonContainer.buttonDotLeft.constant = 0;
+        NSInteger addPage = (self.buttonArray.count % 4) > 0 ? 1 : 0;
+        NSInteger pageCount = self.buttonArray.count / 4 + addPage;
+        self.buttonDotWidth = 36 / pageCount;
+        self.buttonContainer.buttonDotWidth.constant = self.buttonDotWidth;
+        self.buttonScrollView.contentSize = CGSizeMake(kScreenWidth * pageCount, BUTTONHEIGHT);
+    }
+    else {
+        self.buttonContainer.buttonPageCtrl.hidden = YES;
+        self.buttonScrollView.contentSize = CGSizeMake(kScreenWidth, BUTTONHEIGHT);
+    }
+        
+    self.buttonScrollView.contentOffset = CGPointMake(0, 0);
+    [self.buttonScrollView removeAllSubViews];
+    CGFloat buttonSpace = (kScreenWidth - 4 * BUTTONWIDTH) / 5;
+    for (NSInteger i = 0; i < self.buttonArray.count; i++) {
+        HomeMessageModel *model = self.buttonArray[i];
+        KSHomeButton *buttonView = [KSHomeButton shareInstance];
+        [buttonView.buttonImage sd_setImageWithURL:[NSURL URLWithString:model.coverImage]];
+        buttonView.buttonTitle.text = model.title;
+        buttonView.frame = CGRectMake(buttonSpace + (i % 4) * (BUTTONWIDTH + buttonSpace) + (i / 4) * KPortraitWidth, 0, BUTTONWIDTH, BUTTONHEIGHT);
+        buttonView.actionButton.tag = 3000 + i;
+        [buttonView.actionButton addTarget:self action:@selector(HomeTopButtonAction:) forControlEvents:UIControlEventTouchUpInside];
+        [self.buttonScrollView addSubview:buttonView];
+    }
+}
+
+- (void)HomeTopButtonAction:(UIButton *)sender {
+    NSInteger index = sender.tag - 3000;
+    if ([self checkIsLoginToLoginView:YES]) {
+        HomeMessageModel *model = self.buttonArray[index];
+        if (![NSString isEmptyString:model.linkUrl]) {
+            KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
+            webCtrl.url = model.linkUrl;
+            [self.navigationController pushViewController:webCtrl animated:YES];
+        }
+    }
+}
+
+#pragma mark - TYCyclePagerViewDataSource代理
+- (NSInteger)numberOfItemsInPagerView:(TYCyclePagerView *)pageView {
+    return self.bannerArray.count;
+}
+
+- (UICollectionViewCell *)pagerView:(TYCyclePagerView *)pagerView cellForItemAtIndex:(NSInteger)index {
+    HomeMessageModel *model = self.bannerArray[index];
+    HomeBannerCell *cell = [pagerView dequeueReusableCellWithReuseIdentifier:@"HomeBannerCell" forIndex:index];
+    [cell configCellWithModel:model];
+    return cell;
+}
+
+- (TYCyclePagerViewLayout *)layoutForPagerView:(TYCyclePagerView *)pageView {
+    TYCyclePagerViewLayout *layout = [[TYCyclePagerViewLayout alloc]init];
+    layout.itemSize = CGSizeMake(CGRectGetWidth(pageView.frame), CGRectGetHeight(pageView.frame));
+    layout.itemSpacing = 0;
+    return layout;
+    
+}
+
+- (void)pagerView:(TYCyclePagerView *)pageView didScrollFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex {
+    if (pageView == self.bannerScroll) {
+        [self.pageControl setCurrentPage:toIndex animate:YES];
+    }
+}
+
+- (void)pagerView:(TYCyclePagerView *)pageView didSelectedItemCell:(__kindof UICollectionViewCell *)cell atIndex:(NSInteger)index {
+    
+    HomeMessageModel *model = self.bannerArray[index];
+    if (![NSString isEmptyString:model.linkUrl]) {
+        KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
+        webCtrl.url = model.linkUrl;
+        [self.navigationController pushViewController:webCtrl animated:YES];
+    }
+}
+
+
+#pragma mark ----- table data source
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
+    if (tableView == self.tableView) { // 资讯
+        return self.dataArray.count;
+    }
+    else if (tableView == self.liveCourseTable) {  // 直播课列表
+        return self.courseCount;
+    }
+    else { // 视频课列表
+        return self.courseCount;
+    }
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
+    if (tableView == self.tableView) {
+        HomeMessageModel *model = self.dataArray[indexPath.row];
+        HomeInformationCell *cell = [tableView dequeueReusableCellWithIdentifier:@"HomeInformationCell"];
+        ROWINDEX rowIndex = ROWINDEX_MIDDLE;
+        if (indexPath.row == 0) {
+            rowIndex = ROWINDEX_TOP;
+        }
+        else if (indexPath.row == self.dataArray.count - 1) {
+            rowIndex = ROWINDEX_BOTTOM;
+        }
+        [cell configCellWithSource:model rowIndex:rowIndex];
+        return cell;
+    }
+    else if (tableView == self.liveCourseTable) {
+        HomeLiveGroupModel *model = self.liveCourseArray[indexPath.row];
+        HomeLiveCouseCell *cell = [tableView dequeueReusableCellWithIdentifier:@"HomeLiveCouseCell"];
+        [cell configWithSource:model];
+        return cell;
+    }
+    else  {
+        HomeVideoGroupModel *model = self.videoCourseArray[indexPath.row];
+        HomeVideoCourseCell *cell = [tableView dequeueReusableCellWithIdentifier:@"HomeVideoCourseCell"];
+        [cell configWithSource:model];
+        return cell;
+    }
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
+    if (tableView == self.tableView) {
+        HomeMessageModel *model = self.dataArray[indexPath.row];
+        if (![NSString isEmptyString:model.linkUrl]) {
+            KSBaseWKWebViewController *webCtrl = [[KSBaseWKWebViewController alloc] init];
+            webCtrl.url = model.linkUrl;
+            [self.navigationController pushViewController:webCtrl animated:YES];
+        }
+    }
+    else if (tableView == self.liveCourseTable) { // 直播课详情
+        HomeLiveGroupModel *model = self.liveCourseArray[indexPath.row];
+        KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+        NSString *url = [NSString stringWithFormat:@"%@%@%@", WEBHOST, @"/#/liveDetail?groupId=",model.courseGroupId];
+        ctrl.url = url;
+        [self.navigationController pushViewController:ctrl animated:YES];
+    }
+    else if (tableView == self.videoCourseTable) { //
+        HomeVideoGroupModel *model = self.videoCourseArray[indexPath.row];
+        NSString *url = [NSString stringWithFormat:@"%@%@%@", WEBHOST, @"/#/videoDetail?groupId=",model.videoGroupId];
+        KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+        ctrl.url = url;
+        [self.navigationController pushViewController:ctrl animated:YES];
+    }
+}
+
+
+#pragma mark ---- collection data source
+- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
+    return 1;
+}
+
+- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
+    if (collectionView == self.albumCollectionView) {
+        return self.albumArray.count;
+    }
+    else  { // 老师风采
+        return self.teacherArray.count;
+    }
+}
+
+- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
+    if (collectionView == self.albumCollectionView) {
+        HomeHotAlbumCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"HomeHotAlbumCell" forIndexPath:indexPath];
+        return cell;
+    }
+    else {
+        TeacherStyleModel *model = self.teacherArray[indexPath.item];
+        TeacherShowCell *showCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TeacherShowCell" forIndexPath:indexPath];
+        MJWeakSelf;
+        [showCell configWithStyleModel:model callback:^(NSString *videoUrl) {
+            [weakSelf playVideo:videoUrl];
+        }];
+        return showCell;
+    }
+}
+
+- (void)playVideo:(NSString *)videoUrl {
+    if ([NSString isEmptyString:videoUrl]) {
+        return;
+    }
+    // 播放视频
+}
+
+- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
+    if (collectionView == self.albumCollectionView) { // 专辑详情
+        
+    }
+    else { // 老师风采详情
+        TeacherStyleModel *model = self.teacherArray[indexPath.item];
+        [self displayTeacherDetail:model.userId];
+    }
+}
+
+- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
+    if (collectionView == self.albumCollectionView) {
+        return CGSizeMake(120, 140);
+    }
+    else {
+        return CGSizeMake((KPortraitWidth - 28 - 11) / 2.0f, 164);
+    }
+}
+
+// 老师风采
+- (void)displayTeacherDetail:(NSString *)teacherId {
+    KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+    ctrl.url = [NSString stringWithFormat:@"%@%@%@", WEBHOST, @"/#/teacherHome?teacherId=",teacherId];
+    [self.navigationController pushViewController:ctrl animated:YES];
+}
+
+#pragma mark ---- scroll view delegate
+- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
+    if (scrollView == self.buttonScrollView) {
+        NSInteger index = (NSInteger)(scrollView.contentOffset.x / kScreenWidth);
+        
+        [UIView animateWithDuration:0.3f animations:^{
+            self.buttonContainer.buttonDotLeft.constant = index * self.buttonDotWidth;
+        }];
+    }
+    else if (scrollView == self.courseScroll) {
+        NSLog(@"------");
+    }
+}
+    
+
+
+
+#pragma mark ---- lazying
+- (NSMutableArray *)buttonArray {
+    if (!_buttonArray) {
+        _buttonArray = [NSMutableArray array];
+    }
+    return _buttonArray;
+}
+
+- (NSMutableArray *)bannerArray {
+    if (!_bannerArray) {
+        _bannerArray = [NSMutableArray array];
+    }
+    return _bannerArray;
+}
+
+- (NSMutableArray *)albumArray {
+    if (!_albumArray) {
+        _albumArray = [NSMutableArray array];
+    }
+    return _albumArray;
+}
+
+- (NSMutableArray *)liveCourseArray {
+    if (!_liveCourseArray) {
+        _liveCourseArray = [NSMutableArray array];
+    }
+    return _liveCourseArray;
+}
+
+- (NSMutableArray *)videoCourseArray {
+    if (!_videoCourseArray) {
+        _videoCourseArray = [NSMutableArray array];
+    }
+    return _videoCourseArray;
+}
+
+- (NSMutableArray *)teacherArray {
+    if (!_teacherArray) {
+        _teacherArray = [NSMutableArray array];
+    }
+    return _teacherArray;
+}
+#pragma mark ----- 最近上课
+
+- (HomeCourseTipsView *)tipsCourseView {
+    if (!_tipsCourseView) {
+        _tipsCourseView = [HomeCourseTipsView shareInstance];
+        MJWeakSelf;
+        [_tipsCourseView joinRoomCallback:^(COURSETYPE type, NSString * _Nonnull courseId) {
+            [weakSelf joinRoomAction:type courseId:courseId];
+        }];
+    }
+    return _tipsCourseView;
+}
+
+- (void)joinRoomAction:(COURSETYPE)type courseId:(NSString *)courseId {
+    if (type == COURSETYPE_ACCOMPANY) { // 陪练课详情
+        
+    }
+    else { // 直播课详情
+        
+    }
+}
+
+#pragma mark ----- 专辑
+- (HomeHotAlbumView *)albumView {
+    if (!_albumView) {
+        _albumView = [HomeHotAlbumView shareInstance];
+        MJWeakSelf;
+        [_albumView homeAlbumMore:^{
+            [weakSelf moreAlbumDetail];
+        }];
+        [_albumView.albumContentView addSubview:self.albumCollectionView];
+        [self.albumCollectionView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.bottom.top.mas_equalTo(_albumView.albumContentView);
+        }];
+    }
+    return _albumView;
+}
+
+- (UICollectionView *)albumCollectionView {
+    if (!_albumCollectionView) {
+        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
+        layout.sectionInset = UIEdgeInsetsMake(12, 14, 12, 14);
+        layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
+        _albumCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
+        _albumCollectionView.backgroundColor = [UIColor clearColor];
+        _albumCollectionView.delegate = self;
+        _albumCollectionView.dataSource = self;
+        _albumCollectionView.showsVerticalScrollIndicator = NO;
+        _albumCollectionView.showsHorizontalScrollIndicator = NO;
+        [_albumCollectionView registerNib:[UINib nibWithNibName:@"HomeHotAlbumCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:@"HomeHotAlbumCell"];
+    }
+    return _albumCollectionView;
+}
+
+- (void)moreAlbumDetail {
+    KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+    ctrl.url = [NSString stringWithFormat:@"%@%@", WEBHOST, @""];
+    [self.navigationController pushViewController:ctrl animated:YES];
+}
+
+#pragma mark ------ 推荐课程
+- (HomeHotCourseView *)courseView {
+    if (!_courseView) {
+        _courseView = [HomeHotCourseView shareInstance];
+        MJWeakSelf;
+        [_courseView courseActionCallback:^(COURSE_ACTION action) {
+            [weakSelf homeCourseChooseAction:action];
+        }];
+        [_courseView.courseContainer addSubview:self.courseScroll];
+        [self.courseScroll mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.bottom.top.mas_equalTo(_courseView.courseContainer);
+        }];
+    }
+    return _courseView;
+}
+
+- (UIScrollView *)courseScroll {
+    if (!_courseScroll) {
+        _courseScroll = [[UIScrollView alloc] initWithFrame:CGRectZero];
+        _courseScroll.pagingEnabled = YES;
+        _courseScroll.scrollEnabled = NO;
+        _courseScroll.showsHorizontalScrollIndicator = NO;
+        _courseScroll.showsVerticalScrollIndicator = NO;
+        _courseScroll.delegate = self;
+    }
+    return _courseScroll;
+}
+
+- (UITableView *)liveCourseTable {
+    if (!_liveCourseTable) {
+        _liveCourseTable = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
+        _liveCourseTable.delegate = self;
+        _liveCourseTable.dataSource = self;
+        _liveCourseTable.rowHeight = 126;
+        _liveCourseTable.separatorStyle = UITableViewCellSeparatorStyleNone;
+        _liveCourseTable.backgroundColor = [UIColor clearColor];
+        _liveCourseTable.showsVerticalScrollIndicator = NO;
+        [_liveCourseTable registerNib:[UINib nibWithNibName:@"HomeLiveCouseCell" bundle:nil] forCellReuseIdentifier:@"HomeLiveCouseCell"];
+        _liveCourseTable.scrollEnabled = NO;
+    }
+    return _liveCourseTable;
+}
+
+- (UITableView *)videoCourseTable {
+    if (!_videoCourseTable) {
+        _videoCourseTable = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
+        _videoCourseTable.delegate = self;
+        _videoCourseTable.dataSource = self;
+        _videoCourseTable.rowHeight = 126;
+        _videoCourseTable.separatorStyle = UITableViewCellSeparatorStyleNone;
+        _videoCourseTable.backgroundColor = [UIColor clearColor];
+        _videoCourseTable.showsVerticalScrollIndicator = NO;
+        [_videoCourseTable registerNib:[UINib nibWithNibName:@"HomeVideoCourseCell" bundle:nil] forCellReuseIdentifier:@"HomeVideoCourseCell"];
+        _videoCourseTable.scrollEnabled = NO;
+    }
+    return _videoCourseTable;
+}
+
+- (void)homeCourseChooseAction:(COURSE_ACTION)action {
+    switch (action) {
+        case COURSE_ACTION_LIVE:
+        {
+            if (self.isChooseLive == YES) {
+                return;
+            }
+            self.isChooseLive = YES;
+        }
+            break;
+        case COURSE_ACTION_VIDEO:
+        {
+            if (self.isChooseLive == NO) {
+                return;
+            }
+            self.isChooseLive = NO;
+        }
+            break;
+        case COURSE_ACTION_MORE: // 更多
+        {
+            NSString *url = @"";
+            if (self.isChooseLive) { // 直播课 列表
+                url = [NSString stringWithFormat:@"%@%@", WEBHOST, @"/#/liveClass"];
+            }
+            else { // 视频课列表
+                url = [NSString stringWithFormat:@"%@%@", WEBHOST, @"/#/videoClass"];
+            }
+            KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+            ctrl.url = url;
+            [self.navigationController pushViewController:ctrl animated:YES];
+        }
+            break;
+        default:
+            break;
+    }
+}
+
+- (void)setIsChooseLive:(BOOL)isChooseLive {
+    _isChooseLive = isChooseLive;
+    // 切换
+    [UIView animateWithDuration:0.3f animations:^{
+        if (isChooseLive) {
+            [self.courseScroll setContentOffset:CGPointZero animated:YES];
+        }
+        else {
+            [self.courseScroll setContentOffset:CGPointMake(KPortraitWidth, 0) animated:YES];
+        }
+    }];
+}
+
+#pragma mark --- 老师风采
+- (HomeIntroduceView *)teacherView {
+    if (!_teacherView) {
+        _teacherView = [HomeIntroduceView shareInstance];
+        MJWeakSelf;
+        [_teacherView introduceMore:^{
+            [weakSelf teacherMoreIntorduce];
+        }];
+        [_teacherView.teacherContainer addSubview:self.infoCollectionView];
+        [self.infoCollectionView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.bottom.top.mas_equalTo(_teacherView.teacherContainer);
+            make.left.mas_equalTo(_teacherView.mas_left).offset(14);
+            make.right.mas_equalTo(_teacherView.mas_right).offset(-14);
+        }];
+    }
+    return _teacherView;
+}
+
+- (void)teacherMoreIntorduce {
+    KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+    ctrl.url = [NSString stringWithFormat:@"%@%@", WEBHOST, @"/#/teacherList"];
+    [self.navigationController pushViewController:ctrl animated:YES];
+}
+
+
+- (UICollectionView *)infoCollectionView {
+    if (!_infoCollectionView) {
+        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
+        layout.scrollDirection = UICollectionViewScrollDirectionVertical;
+        _infoCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
+        _infoCollectionView.backgroundColor = [UIColor clearColor];
+        _infoCollectionView.delegate = self;
+        _infoCollectionView.dataSource = self;
+        _infoCollectionView.showsVerticalScrollIndicator = NO;
+        _infoCollectionView.showsHorizontalScrollIndicator = NO;
+        [_infoCollectionView registerNib:[UINib nibWithNibName:@"TeacherShowCell" bundle:[NSBundle mainBundle]] forCellWithReuseIdentifier:@"TeacherShowCell"];
+    }
+    return _infoCollectionView;
+}
+
+
+#pragma mark ---- button container
+- (HomeButtonView *)buttonContainer {
+    if (!_buttonContainer) {
+        _buttonContainer = [HomeButtonView shareInstance];
+        [_buttonContainer.buttonContentView addSubview:self.buttonScrollView];
+    }
+    return _buttonContainer;
+}
+
+- (UIScrollView *)buttonScrollView {
+    if (!_buttonScrollView) {
+        _buttonScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, KPortraitWidth, BUTTONHEIGHT)];
+        _buttonScrollView.backgroundColor = [UIColor clearColor];
+        _buttonScrollView.pagingEnabled = YES;
+        _buttonScrollView.showsHorizontalScrollIndicator = NO;
+        _buttonScrollView.showsVerticalScrollIndicator = NO;
+        _buttonScrollView.delegate = self;
+    }
+    return _buttonScrollView;
+}
+
+
+- (UIView *)tableHeaderView {
+    if (!_tableHeaderView) {
+        _tableHeaderView = [[UIView alloc] initWithFrame:CGRectZero];
+        _tableHeaderView.backgroundColor = [UIColor clearColor];
+    }
+    return _tableHeaderView;
+}
+
+- (HomeBannerView *)bannerView {
+    if (!_bannerView) {
+        _bannerView = [HomeBannerView shareInstance];
+        [_bannerView.bannerContentView addSubview:self.bannerScroll];
+    }
+    return _bannerView;
+}
+
+- (TYCyclePagerView *)bannerScroll {
+    if (!_bannerScroll) {
+        _bannerScroll = [[TYCyclePagerView alloc] init];
+        _bannerScroll.backgroundColor = [UIColor clearColor];
+        _bannerScroll.frame = CGRectMake(0, 0, kScreenWidth - 28, (kScreenWidth - 28) / 347 * 132);
+        _bannerScroll.isInfiniteLoop = YES;
+        _bannerScroll.autoScrollInterval = 3.0f;
+        _bannerScroll.reloadDataNeedResetIndex = YES;
+        _bannerScroll.dataSource = self;
+        _bannerScroll.delegate = self;
+        [_bannerScroll registerNib:[UINib nibWithNibName:@"HomeBannerCell" bundle:nil] forCellWithReuseIdentifier:@"HomeBannerCell"];
+    }
+    return _bannerScroll;
+}
+
+#pragma mark ---- 更多资讯
+- (HotInformationHeadView *)informationHeadView {
+    if (!_informationHeadView) {
+        _informationHeadView = [HotInformationHeadView shareInstance];
+        
+        MJWeakSelf;
+        [_informationHeadView moreInformationCallback:^{
+            [weakSelf moreInformation];
+        }];
+    }
+    return _informationHeadView;
+}
+
+- (void)moreInformation {
+    KSBaseWKWebViewController *ctrl = [[KSBaseWKWebViewController alloc] init];
+    ctrl.url = [NSString stringWithFormat:@"%@%@", WEBHOST, @"/#/teacherList"];
+    [self.navigationController pushViewController:ctrl animated:YES];
+}
+
+- (UITableView *)tableView {
+    if (!_tableView) {
+        _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
+        _tableView.delegate = self;
+        _tableView.dataSource = self;
+        _tableView.rowHeight = 108;
+        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
+        _tableView.backgroundColor = [UIColor clearColor];
+        _tableView.showsVerticalScrollIndicator = NO;
+        [_tableView registerNib:[UINib nibWithNibName:@"HomeInformationCell" bundle:nil] forCellReuseIdentifier:@"HomeInformationCell"];
+        UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 10)];
+        bottomView.backgroundColor = [UIColor clearColor];
+        _tableView.tableFooterView = bottomView;
+    }
+    return _tableView;
+}
+- (HomeNavView *)navView {
+    if (!_navView) {
+        _navView = [HomeNavView shareInstance];
+        MJWeakSelf;
+        [_navView homeNavAction:^(NAVACTION action) {
+            [weakSelf navAction:action];
+        }];
+    }
+    return _navView;
+}
+
+- (void)navAction:(NAVACTION)action {
+    if (action == NAVACTION_SUBJECT) {
+        [self showInstrumentView];;
+    }
+    else { // 消息中心
+        NoticeMessageViewController *ctrl = [[NoticeMessageViewController alloc] init];
+        [self.navigationController pushViewController:ctrl animated:YES];
+    }
+}
+
 - (void)showInstrumentView {
     SubjectChooseViewController *ctrl = [[SubjectChooseViewController alloc] init];
+    MJWeakSelf;
+    [ctrl chooseSubjectCallback:^{
+        [weakSelf requestUserInfo];
+    }];
     [self.navigationController pushViewController:ctrl animated:YES];
 }
 
+
+
+
+- (void)dealloc {
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
 /*
 #pragma mark - Navigation
 

+ 28 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/Model/HomeLiveGroupModel.h

@@ -0,0 +1,28 @@
+//
+//  HomeLiveGroupModel.h
+//
+//  Created by Steven  on 2022/4/24
+//  Copyright (c) 2022 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+
+@interface HomeLiveGroupModel : NSObject <NSCoding, NSCopying>
+
+@property (nonatomic, strong) NSString *courseGroupId;
+@property (nonatomic, strong) NSString *backgroundPic;
+@property (nonatomic, strong) NSString *avatar;
+@property (nonatomic, assign) double courseGroupPrice;
+@property (nonatomic, strong) NSString *teacherId;
+@property (nonatomic, strong) NSString *teacherName;
+@property (nonatomic, strong) NSString *courseStartTime;
+@property (nonatomic, assign) double courseNum;
+@property (nonatomic, strong) NSString *courseGroupName;
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+- (NSDictionary *)dictionaryRepresentation;
+
+@end

+ 151 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/Model/HomeLiveGroupModel.m

@@ -0,0 +1,151 @@
+//
+//  HomeLiveGroupModel.m
+//
+//  Created by Steven  on 2022/4/24
+//  Copyright (c) 2022 __MyCompanyName__. All rights reserved.
+//
+
+#import "HomeLiveGroupModel.h"
+
+
+NSString *const kHomeLiveGroupModelCourseGroupId = @"courseGroupId";
+NSString *const kHomeLiveGroupModelBackgroundPic = @"backgroundPic";
+NSString *const kHomeLiveGroupModelAvatar = @"avatar";
+NSString *const kHomeLiveGroupModelCourseGroupPrice = @"courseGroupPrice";
+NSString *const kHomeLiveGroupModelTeacherId = @"teacherId";
+NSString *const kHomeLiveGroupModelTeacherName = @"teacherName";
+NSString *const kHomeLiveGroupModelCourseStartTime = @"courseStartTime";
+NSString *const kHomeLiveGroupModelCourseNum = @"courseNum";
+NSString *const kHomeLiveGroupModelCourseGroupName = @"courseGroupName";
+
+
+@interface HomeLiveGroupModel ()
+
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
+
+@end
+
+@implementation HomeLiveGroupModel
+
+@synthesize courseGroupId = _courseGroupId;
+@synthesize backgroundPic = _backgroundPic;
+@synthesize avatar = _avatar;
+@synthesize courseGroupPrice = _courseGroupPrice;
+@synthesize teacherId = _teacherId;
+@synthesize teacherName = _teacherName;
+@synthesize courseStartTime = _courseStartTime;
+@synthesize courseNum = _courseNum;
+@synthesize courseGroupName = _courseGroupName;
+
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
+{
+    return [[self alloc] initWithDictionary:dict];
+}
+
+- (instancetype)initWithDictionary:(NSDictionary *)dict
+{
+    self = [super init];
+    
+    // This check serves to make sure that a non-NSDictionary object
+    // passed into the model class doesn't break the parsing.
+    if(self && [dict isKindOfClass:[NSDictionary class]]) {
+            self.courseGroupId = [self objectOrNilForKey:kHomeLiveGroupModelCourseGroupId fromDictionary:dict];
+            self.backgroundPic = [self objectOrNilForKey:kHomeLiveGroupModelBackgroundPic fromDictionary:dict];
+            self.avatar = [self objectOrNilForKey:kHomeLiveGroupModelAvatar fromDictionary:dict];
+            self.courseGroupPrice = [[self objectOrNilForKey:kHomeLiveGroupModelCourseGroupPrice fromDictionary:dict] doubleValue];
+            self.teacherId = [self objectOrNilForKey:kHomeLiveGroupModelTeacherId fromDictionary:dict];
+            self.teacherName = [self objectOrNilForKey:kHomeLiveGroupModelTeacherName fromDictionary:dict];
+            self.courseStartTime = [self objectOrNilForKey:kHomeLiveGroupModelCourseStartTime fromDictionary:dict];
+            self.courseNum = [[self objectOrNilForKey:kHomeLiveGroupModelCourseNum fromDictionary:dict] doubleValue];
+            self.courseGroupName = [self objectOrNilForKey:kHomeLiveGroupModelCourseGroupName fromDictionary:dict];
+
+    }
+    
+    return self;
+    
+}
+
+- (NSDictionary *)dictionaryRepresentation
+{
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    [mutableDict setValue:self.courseGroupId forKey:kHomeLiveGroupModelCourseGroupId];
+    [mutableDict setValue:self.backgroundPic forKey:kHomeLiveGroupModelBackgroundPic];
+    [mutableDict setValue:self.avatar forKey:kHomeLiveGroupModelAvatar];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.courseGroupPrice] forKey:kHomeLiveGroupModelCourseGroupPrice];
+    [mutableDict setValue:self.teacherId forKey:kHomeLiveGroupModelTeacherId];
+    [mutableDict setValue:self.teacherName forKey:kHomeLiveGroupModelTeacherName];
+    [mutableDict setValue:self.courseStartTime forKey:kHomeLiveGroupModelCourseStartTime];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.courseNum] forKey:kHomeLiveGroupModelCourseNum];
+    [mutableDict setValue:self.courseGroupName forKey:kHomeLiveGroupModelCourseGroupName];
+
+    return [NSDictionary dictionaryWithDictionary:mutableDict];
+}
+
+- (NSString *)description 
+{
+    return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
+}
+
+#pragma mark - Helper Method
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
+{
+    id object = [dict objectForKey:aKey];
+    return [object isEqual:[NSNull null]] ? nil : object;
+}
+
+
+#pragma mark - NSCoding Methods
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+    self = [super init];
+
+    self.courseGroupId = [aDecoder decodeObjectForKey:kHomeLiveGroupModelCourseGroupId];
+    self.backgroundPic = [aDecoder decodeObjectForKey:kHomeLiveGroupModelBackgroundPic];
+    self.avatar = [aDecoder decodeObjectForKey:kHomeLiveGroupModelAvatar];
+    self.courseGroupPrice = [aDecoder decodeDoubleForKey:kHomeLiveGroupModelCourseGroupPrice];
+    self.teacherId = [aDecoder decodeObjectForKey:kHomeLiveGroupModelTeacherId];
+    self.teacherName = [aDecoder decodeObjectForKey:kHomeLiveGroupModelTeacherName];
+    self.courseStartTime = [aDecoder decodeObjectForKey:kHomeLiveGroupModelCourseStartTime];
+    self.courseNum = [aDecoder decodeDoubleForKey:kHomeLiveGroupModelCourseNum];
+    self.courseGroupName = [aDecoder decodeObjectForKey:kHomeLiveGroupModelCourseGroupName];
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+
+    [aCoder encodeObject:_courseGroupId forKey:kHomeLiveGroupModelCourseGroupId];
+    [aCoder encodeObject:_backgroundPic forKey:kHomeLiveGroupModelBackgroundPic];
+    [aCoder encodeObject:_avatar forKey:kHomeLiveGroupModelAvatar];
+    [aCoder encodeDouble:_courseGroupPrice forKey:kHomeLiveGroupModelCourseGroupPrice];
+    [aCoder encodeObject:_teacherId forKey:kHomeLiveGroupModelTeacherId];
+    [aCoder encodeObject:_teacherName forKey:kHomeLiveGroupModelTeacherName];
+    [aCoder encodeObject:_courseStartTime forKey:kHomeLiveGroupModelCourseStartTime];
+    [aCoder encodeDouble:_courseNum forKey:kHomeLiveGroupModelCourseNum];
+    [aCoder encodeObject:_courseGroupName forKey:kHomeLiveGroupModelCourseGroupName];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    HomeLiveGroupModel *copy = [[HomeLiveGroupModel alloc] init];
+    
+    if (copy) {
+
+        copy.courseGroupId = [self.courseGroupId copyWithZone:zone];
+        copy.backgroundPic = [self.backgroundPic copyWithZone:zone];
+        copy.avatar = [self.avatar copyWithZone:zone];
+        copy.courseGroupPrice = self.courseGroupPrice;
+        copy.teacherId = [self.teacherId copyWithZone:zone];
+        copy.teacherName = [self.teacherName copyWithZone:zone];
+        copy.courseStartTime = [self.courseStartTime copyWithZone:zone];
+        copy.courseNum = self.courseNum;
+        copy.courseGroupName = [self.courseGroupName copyWithZone:zone];
+    }
+    
+    return copy;
+}
+
+
+@end

+ 30 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/Model/HomeVideoGroupModel.h

@@ -0,0 +1,30 @@
+//
+//  HomeVideoGroupModel.h
+//
+//  Created by Steven  on 2022/4/24
+//  Copyright (c) 2022 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+
+@interface HomeVideoGroupModel : NSObject <NSCoding, NSCopying>
+
+@property (nonatomic, strong) NSString *avatar;
+@property (nonatomic, strong) NSString *lessonCoverUrl;
+@property (nonatomic, strong) NSString *videoGroupId;
+@property (nonatomic, assign) double lessonPrice;
+@property (nonatomic, strong) NSString *teacherName;
+@property (nonatomic, strong) NSString *subjectId;
+@property (nonatomic, strong) NSString *subjectName;
+@property (nonatomic, assign) double lessonCount;
+@property (nonatomic, strong) NSString *teacherId;
+@property (nonatomic, strong) NSString *videoGroupName;
+@property (nonatomic, strong) NSString *createTime;
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+- (NSDictionary *)dictionaryRepresentation;
+
+@end

+ 165 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/Model/HomeVideoGroupModel.m

@@ -0,0 +1,165 @@
+//
+//  HomeVideoGroupModel.m
+//
+//  Created by Steven  on 2022/4/24
+//  Copyright (c) 2022 __MyCompanyName__. All rights reserved.
+//
+
+#import "HomeVideoGroupModel.h"
+
+
+NSString *const kHomeVideoGroupModelAvatar = @"avatar";
+NSString *const kHomeVideoGroupModelLessonCoverUrl = @"lessonCoverUrl";
+NSString *const kHomeVideoGroupModelVideoGroupId = @"videoGroupId";
+NSString *const kHomeVideoGroupModelLessonPrice = @"lessonPrice";
+NSString *const kHomeVideoGroupModelTeacherName = @"teacherName";
+NSString *const kHomeVideoGroupModelSubjectId = @"subjectId";
+NSString *const kHomeVideoGroupModelSubjectName = @"subjectName";
+NSString *const kHomeVideoGroupModelLessonCount = @"lessonCount";
+NSString *const kHomeVideoGroupModelTeacherId = @"teacherId";
+NSString *const kHomeVideoGroupModelVideoGroupName = @"videoGroupName";
+NSString *const kHomeVideoGroupModelCreateTime = @"createTime";
+
+
+@interface HomeVideoGroupModel ()
+
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
+
+@end
+
+@implementation HomeVideoGroupModel
+
+@synthesize avatar = _avatar;
+@synthesize lessonCoverUrl = _lessonCoverUrl;
+@synthesize videoGroupId = _videoGroupId;
+@synthesize lessonPrice = _lessonPrice;
+@synthesize teacherName = _teacherName;
+@synthesize subjectId = _subjectId;
+@synthesize subjectName = _subjectName;
+@synthesize lessonCount = _lessonCount;
+@synthesize teacherId = _teacherId;
+@synthesize videoGroupName = _videoGroupName;
+@synthesize createTime = _createTime;
+
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
+{
+    return [[self alloc] initWithDictionary:dict];
+}
+
+- (instancetype)initWithDictionary:(NSDictionary *)dict
+{
+    self = [super init];
+    
+    // This check serves to make sure that a non-NSDictionary object
+    // passed into the model class doesn't break the parsing.
+    if(self && [dict isKindOfClass:[NSDictionary class]]) {
+            self.avatar = [self objectOrNilForKey:kHomeVideoGroupModelAvatar fromDictionary:dict];
+            self.lessonCoverUrl = [self objectOrNilForKey:kHomeVideoGroupModelLessonCoverUrl fromDictionary:dict];
+            self.videoGroupId = [self objectOrNilForKey:kHomeVideoGroupModelVideoGroupId fromDictionary:dict];
+            self.lessonPrice = [[self objectOrNilForKey:kHomeVideoGroupModelLessonPrice fromDictionary:dict] doubleValue];
+            self.teacherName = [self objectOrNilForKey:kHomeVideoGroupModelTeacherName fromDictionary:dict];
+            self.subjectId = [self objectOrNilForKey:kHomeVideoGroupModelSubjectId fromDictionary:dict];
+            self.subjectName = [self objectOrNilForKey:kHomeVideoGroupModelSubjectName fromDictionary:dict];
+            self.lessonCount = [[self objectOrNilForKey:kHomeVideoGroupModelLessonCount fromDictionary:dict] doubleValue];
+            self.teacherId = [self objectOrNilForKey:kHomeVideoGroupModelTeacherId fromDictionary:dict];
+            self.videoGroupName = [self objectOrNilForKey:kHomeVideoGroupModelVideoGroupName fromDictionary:dict];
+            self.createTime = [self objectOrNilForKey:kHomeVideoGroupModelCreateTime fromDictionary:dict];
+
+    }
+    
+    return self;
+    
+}
+
+- (NSDictionary *)dictionaryRepresentation
+{
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    [mutableDict setValue:self.avatar forKey:kHomeVideoGroupModelAvatar];
+    [mutableDict setValue:self.lessonCoverUrl forKey:kHomeVideoGroupModelLessonCoverUrl];
+    [mutableDict setValue:self.videoGroupId forKey:kHomeVideoGroupModelVideoGroupId];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.lessonPrice] forKey:kHomeVideoGroupModelLessonPrice];
+    [mutableDict setValue:self.teacherName forKey:kHomeVideoGroupModelTeacherName];
+    [mutableDict setValue:self.subjectId forKey:kHomeVideoGroupModelSubjectId];
+    [mutableDict setValue:self.subjectName forKey:kHomeVideoGroupModelSubjectName];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.lessonCount] forKey:kHomeVideoGroupModelLessonCount];
+    [mutableDict setValue:self.teacherId forKey:kHomeVideoGroupModelTeacherId];
+    [mutableDict setValue:self.videoGroupName forKey:kHomeVideoGroupModelVideoGroupName];
+    [mutableDict setValue:self.createTime forKey:kHomeVideoGroupModelCreateTime];
+
+    return [NSDictionary dictionaryWithDictionary:mutableDict];
+}
+
+- (NSString *)description 
+{
+    return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
+}
+
+#pragma mark - Helper Method
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
+{
+    id object = [dict objectForKey:aKey];
+    return [object isEqual:[NSNull null]] ? nil : object;
+}
+
+
+#pragma mark - NSCoding Methods
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+    self = [super init];
+
+    self.avatar = [aDecoder decodeObjectForKey:kHomeVideoGroupModelAvatar];
+    self.lessonCoverUrl = [aDecoder decodeObjectForKey:kHomeVideoGroupModelLessonCoverUrl];
+    self.videoGroupId = [aDecoder decodeObjectForKey:kHomeVideoGroupModelVideoGroupId];
+    self.lessonPrice = [aDecoder decodeDoubleForKey:kHomeVideoGroupModelLessonPrice];
+    self.teacherName = [aDecoder decodeObjectForKey:kHomeVideoGroupModelTeacherName];
+    self.subjectId = [aDecoder decodeObjectForKey:kHomeVideoGroupModelSubjectId];
+    self.subjectName = [aDecoder decodeObjectForKey:kHomeVideoGroupModelSubjectName];
+    self.lessonCount = [aDecoder decodeDoubleForKey:kHomeVideoGroupModelLessonCount];
+    self.teacherId = [aDecoder decodeObjectForKey:kHomeVideoGroupModelTeacherId];
+    self.videoGroupName = [aDecoder decodeObjectForKey:kHomeVideoGroupModelVideoGroupName];
+    self.createTime = [aDecoder decodeObjectForKey:kHomeVideoGroupModelCreateTime];
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+
+    [aCoder encodeObject:_avatar forKey:kHomeVideoGroupModelAvatar];
+    [aCoder encodeObject:_lessonCoverUrl forKey:kHomeVideoGroupModelLessonCoverUrl];
+    [aCoder encodeObject:_videoGroupId forKey:kHomeVideoGroupModelVideoGroupId];
+    [aCoder encodeDouble:_lessonPrice forKey:kHomeVideoGroupModelLessonPrice];
+    [aCoder encodeObject:_teacherName forKey:kHomeVideoGroupModelTeacherName];
+    [aCoder encodeObject:_subjectId forKey:kHomeVideoGroupModelSubjectId];
+    [aCoder encodeObject:_subjectName forKey:kHomeVideoGroupModelSubjectName];
+    [aCoder encodeDouble:_lessonCount forKey:kHomeVideoGroupModelLessonCount];
+    [aCoder encodeObject:_teacherId forKey:kHomeVideoGroupModelTeacherId];
+    [aCoder encodeObject:_videoGroupName forKey:kHomeVideoGroupModelVideoGroupName];
+    [aCoder encodeObject:_createTime forKey:kHomeVideoGroupModelCreateTime];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    HomeVideoGroupModel *copy = [[HomeVideoGroupModel alloc] init];
+    
+    if (copy) {
+
+        copy.avatar = [self.avatar copyWithZone:zone];
+        copy.lessonCoverUrl = [self.lessonCoverUrl copyWithZone:zone];
+        copy.videoGroupId = [self.videoGroupId copyWithZone:zone];
+        copy.lessonPrice = self.lessonPrice;
+        copy.teacherName = [self.teacherName copyWithZone:zone];
+        copy.subjectId = [self.subjectId copyWithZone:zone];
+        copy.subjectName = [self.subjectName copyWithZone:zone];
+        copy.lessonCount = self.lessonCount;
+        copy.teacherId = [self.teacherId copyWithZone:zone];
+        copy.videoGroupName = [self.videoGroupName copyWithZone:zone];
+        copy.createTime = [self.createTime copyWithZone:zone];
+    }
+    
+    return copy;
+}
+
+
+@end

+ 29 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/Model/TeacherStyleModel.h

@@ -0,0 +1,29 @@
+//
+//  TeacherStyleModel.h
+//
+//  Created by Steven  on 2022/4/22
+//  Copyright (c) 2022 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+
+@interface TeacherStyleModel : NSObject <NSCoding, NSCopying>
+
+@property (nonatomic, strong) NSString *browse;
+@property (nonatomic, strong) NSString *userId;
+@property (nonatomic, strong) NSString *avatar;
+@property (nonatomic, strong) NSString *internalBaseClassIdentifier;
+@property (nonatomic, strong) NSString *updateTime;
+@property (nonatomic, strong) NSString *describe;
+@property (nonatomic, strong) NSString *username;
+@property (nonatomic, strong) NSString *videoUrl;
+@property (nonatomic, strong) NSString *createTime;
+@property (nonatomic, strong) NSString *liveFlag;
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+- (NSDictionary *)dictionaryRepresentation;
+
+@end

+ 162 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/Model/TeacherStyleModel.m

@@ -0,0 +1,162 @@
+//
+//  TeacherStyleModel.m
+//
+//  Created by Steven  on 2022/4/22
+//  Copyright (c) 2022 __MyCompanyName__. All rights reserved.
+//
+
+#import "TeacherStyleModel.h"
+
+
+NSString *const kTeacherStyleModelBrowse = @"browse";
+NSString *const kTeacherStyleModelUserId = @"userId";
+NSString *const kTeacherStyleModelAvatar = @"avatar";
+NSString *const kTeacherStyleModelId = @"id";
+NSString *const kTeacherStyleModelUpdateTime = @"updateTime";
+NSString *const kTeacherStyleModelDescribe = @"describe";
+NSString *const kTeacherStyleModelUsername = @"username";
+NSString *const kTeacherStyleModelVideoUrl = @"videoUrl";
+NSString *const kTeacherStyleModelCreateTime = @"createTime";
+NSString *const kTeacherStyleModelLiveFlag = @"liveFlag";
+
+
+@interface TeacherStyleModel ()
+
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
+
+@end
+
+@implementation TeacherStyleModel
+
+@synthesize browse = _browse;
+@synthesize userId = _userId;
+@synthesize avatar = _avatar;
+@synthesize internalBaseClassIdentifier = _internalBaseClassIdentifier;
+@synthesize updateTime = _updateTime;
+@synthesize describe = _describe;
+@synthesize username = _username;
+@synthesize videoUrl = _videoUrl;
+@synthesize createTime = _createTime;
+@synthesize liveFlag = _liveFlag;
+
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
+{
+    return [[self alloc] initWithDictionary:dict];
+}
+
+- (instancetype)initWithDictionary:(NSDictionary *)dict
+{
+    self = [super init];
+    
+    // This check serves to make sure that a non-NSDictionary object
+    // passed into the model class doesn't break the parsing.
+    if(self && [dict isKindOfClass:[NSDictionary class]]) {
+            self.browse = [self objectOrNilForKey:kTeacherStyleModelBrowse fromDictionary:dict];
+            self.userId = [self objectOrNilForKey:kTeacherStyleModelUserId fromDictionary:dict];
+            self.avatar = [self objectOrNilForKey:kTeacherStyleModelAvatar fromDictionary:dict];
+            self.internalBaseClassIdentifier = [self objectOrNilForKey:kTeacherStyleModelId fromDictionary:dict];
+            self.updateTime = [self objectOrNilForKey:kTeacherStyleModelUpdateTime fromDictionary:dict];
+            self.describe = [self objectOrNilForKey:kTeacherStyleModelDescribe fromDictionary:dict];
+            self.username = [self objectOrNilForKey:kTeacherStyleModelUsername fromDictionary:dict];
+            self.videoUrl = [self objectOrNilForKey:kTeacherStyleModelVideoUrl fromDictionary:dict];
+            self.createTime = [self objectOrNilForKey:kTeacherStyleModelCreateTime fromDictionary:dict];
+            self.liveFlag = [self objectOrNilForKey:kTeacherStyleModelLiveFlag fromDictionary:dict];
+
+    }
+    
+    return self;
+    
+}
+
+- (NSDictionary *)dictionaryRepresentation
+{
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    [mutableDict setValue:self.browse forKey:kTeacherStyleModelBrowse];
+    [mutableDict setValue:self.userId forKey:kTeacherStyleModelUserId];
+    [mutableDict setValue:self.avatar forKey:kTeacherStyleModelAvatar];
+    [mutableDict setValue:self.internalBaseClassIdentifier forKey:kTeacherStyleModelId];
+    [mutableDict setValue:self.updateTime forKey:kTeacherStyleModelUpdateTime];
+    [mutableDict setValue:self.describe forKey:kTeacherStyleModelDescribe];
+    [mutableDict setValue:self.username forKey:kTeacherStyleModelUsername];
+    [mutableDict setValue:self.videoUrl forKey:kTeacherStyleModelVideoUrl];
+    [mutableDict setValue:self.createTime forKey:kTeacherStyleModelCreateTime];
+    [mutableDict setValue:self.liveFlag forKey:kTeacherStyleModelLiveFlag];
+
+    return [NSDictionary dictionaryWithDictionary:mutableDict];
+}
+
+- (NSString *)description 
+{
+    return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
+}
+
+#pragma mark - Helper Method
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
+{
+    id object = [dict objectForKey:aKey];
+    if ([object isKindOfClass:[NSNumber class]]) {
+        NSNumber *number = object;
+        object = [number stringValue];
+    }
+    return [object isEqual:[NSNull null]] ? nil : object;
+}
+
+
+#pragma mark - NSCoding Methods
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+    self = [super init];
+
+    self.browse = [aDecoder decodeObjectForKey:kTeacherStyleModelBrowse];
+    self.userId = [aDecoder decodeObjectForKey:kTeacherStyleModelUserId];
+    self.avatar = [aDecoder decodeObjectForKey:kTeacherStyleModelAvatar];
+    self.internalBaseClassIdentifier = [aDecoder decodeObjectForKey:kTeacherStyleModelId];
+    self.updateTime = [aDecoder decodeObjectForKey:kTeacherStyleModelUpdateTime];
+    self.describe = [aDecoder decodeObjectForKey:kTeacherStyleModelDescribe];
+    self.username = [aDecoder decodeObjectForKey:kTeacherStyleModelUsername];
+    self.videoUrl = [aDecoder decodeObjectForKey:kTeacherStyleModelVideoUrl];
+    self.createTime = [aDecoder decodeObjectForKey:kTeacherStyleModelCreateTime];
+    self.liveFlag = [aDecoder decodeObjectForKey:kTeacherStyleModelLiveFlag];
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+
+    [aCoder encodeObject:_browse forKey:kTeacherStyleModelBrowse];
+    [aCoder encodeObject:_userId forKey:kTeacherStyleModelUserId];
+    [aCoder encodeObject:_avatar forKey:kTeacherStyleModelAvatar];
+    [aCoder encodeObject:_internalBaseClassIdentifier forKey:kTeacherStyleModelId];
+    [aCoder encodeObject:_updateTime forKey:kTeacherStyleModelUpdateTime];
+    [aCoder encodeObject:_describe forKey:kTeacherStyleModelDescribe];
+    [aCoder encodeObject:_username forKey:kTeacherStyleModelUsername];
+    [aCoder encodeObject:_videoUrl forKey:kTeacherStyleModelVideoUrl];
+    [aCoder encodeObject:_createTime forKey:kTeacherStyleModelCreateTime];
+    [aCoder encodeObject:_liveFlag forKey:kTeacherStyleModelLiveFlag];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    TeacherStyleModel *copy = [[TeacherStyleModel alloc] init];
+    
+    if (copy) {
+
+        copy.browse = [self.browse copyWithZone:zone];
+        copy.userId = [self.userId copyWithZone:zone];
+        copy.avatar = [self.avatar copyWithZone:zone];
+        copy.internalBaseClassIdentifier = [self.internalBaseClassIdentifier copyWithZone:zone];
+        copy.updateTime = [self.updateTime copyWithZone:zone];
+        copy.describe = [self.describe copyWithZone:zone];
+        copy.username = [self.username copyWithZone:zone];
+        copy.videoUrl = [self.videoUrl copyWithZone:zone];
+        copy.createTime = [self.createTime copyWithZone:zone];
+        copy.liveFlag = [self.liveFlag copyWithZone:zone];
+    }
+    
+    return copy;
+}
+
+
+@end

+ 16 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Controller/NoticeMessageViewController.h

@@ -0,0 +1,16 @@
+//
+//  NoticeMessageViewController.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import "KSBaseViewController.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface NoticeMessageViewController : KSBaseViewController
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 31 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Controller/NoticeMessageViewController.m

@@ -0,0 +1,31 @@
+//
+//  NoticeMessageViewController.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import "NoticeMessageViewController.h"
+
+@interface NoticeMessageViewController ()
+
+@end
+
+@implementation NoticeMessageViewController
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+}
+
+/*
+#pragma mark - Navigation
+
+// In a storyboard-based application, you will often want to do a little preparation before navigation
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
+    // Get the new view controller using [segue destinationViewController].
+    // Pass the selected object to the new view controller.
+}
+*/
+
+@end

+ 28 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Model/HomeMessageModel.h

@@ -0,0 +1,28 @@
+//
+//  HomeMessageModel.h
+//
+//  Created by   on 2019/9/24
+//  Copyright (c) 2019 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+
+
+@interface HomeMessageModel : NSObject <NSCoding, NSCopying>
+
+@property (nonatomic, strong) NSString *status;
+@property (nonatomic, strong) NSString *content;
+@property (nonatomic, assign) double userId;
+@property (nonatomic, strong) NSString *updateTime;
+@property (nonatomic, strong) NSString *title;
+@property (nonatomic, strong) NSString *coverImage;
+@property (nonatomic, assign) double type;
+@property (nonatomic, strong) NSString *createTime;
+@property (nonatomic, strong) NSString *linkUrl;
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+- (NSDictionary *)dictionaryRepresentation;
+
+@end

+ 154 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/NoticeCenter/Model/HomeMessageModel.m

@@ -0,0 +1,154 @@
+//
+//  HomeMessageModel.m
+//
+//  Created by   on 2019/9/24
+//  Copyright (c) 2019 __MyCompanyName__. All rights reserved.
+//
+
+#import "HomeMessageModel.h"
+
+
+NSString *const kHomeMessageModelStatus = @"status";
+NSString *const kHomeMessageModelContent = @"content";
+NSString *const kHomeMessageModelId = @"id";
+NSString *const kHomeMessageModelUpdateTime = @"updateTime";
+NSString *const kHomeMessageModelTitle = @"title";
+NSString *const kHomeMessageModelCoverImage = @"coverImage";
+NSString *const kHomeMessageModelType = @"type";
+NSString *const kHomeMessageModelCreateTime = @"createTime";
+NSString *const kHomeMessageModelLinkUrl = @"linkUrl";
+
+
+
+@interface HomeMessageModel ()
+
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
+
+@end
+
+@implementation HomeMessageModel
+
+@synthesize status = _status;
+@synthesize content = _content;
+@synthesize userId = _userId;
+@synthesize updateTime = _updateTime;
+@synthesize title = _title;
+@synthesize coverImage = _coverImage;
+@synthesize type = _type;
+@synthesize createTime = _createTime;
+@synthesize linkUrl = _linkUrl;
+
++ (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
+{
+    return [[self alloc] initWithDictionary:dict];
+}
+
+- (instancetype)initWithDictionary:(NSDictionary *)dict
+{
+    self = [super init];
+    
+    // This check serves to make sure that a non-NSDictionary object
+    // passed into the model class doesn't break the parsing.
+    if(self && [dict isKindOfClass:[NSDictionary class]]) {
+            self.status = [self objectOrNilForKey:kHomeMessageModelStatus fromDictionary:dict];
+            self.content = [self objectOrNilForKey:kHomeMessageModelContent fromDictionary:dict];
+            self.userId = [[self objectOrNilForKey:kHomeMessageModelId fromDictionary:dict] doubleValue];
+            self.updateTime = [self objectOrNilForKey:kHomeMessageModelUpdateTime fromDictionary:dict];
+            self.title = [self objectOrNilForKey:kHomeMessageModelTitle fromDictionary:dict];
+            self.coverImage = [self objectOrNilForKey:kHomeMessageModelCoverImage fromDictionary:dict];
+            self.type = [[self objectOrNilForKey:kHomeMessageModelType fromDictionary:dict] doubleValue];
+            self.createTime = [self objectOrNilForKey:kHomeMessageModelCreateTime fromDictionary:dict];
+            self.linkUrl = [self objectOrNilForKey:kHomeMessageModelLinkUrl fromDictionary:dict];
+    }
+    
+    return self;
+    
+}
+
+- (NSDictionary *)dictionaryRepresentation
+{
+    NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
+    [mutableDict setValue:self.status forKey:kHomeMessageModelStatus];
+    [mutableDict setValue:self.content forKey:kHomeMessageModelContent];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.userId] forKey:kHomeMessageModelId];
+    [mutableDict setValue:self.updateTime forKey:kHomeMessageModelUpdateTime];
+    [mutableDict setValue:self.title forKey:kHomeMessageModelTitle];
+    [mutableDict setValue:self.coverImage forKey:kHomeMessageModelCoverImage];
+    [mutableDict setValue:[NSNumber numberWithDouble:self.type] forKey:kHomeMessageModelType];
+    [mutableDict setValue:self.createTime forKey:kHomeMessageModelCreateTime];
+    [mutableDict setValue:self.linkUrl forKey:kHomeMessageModelLinkUrl];
+    
+    return [NSDictionary dictionaryWithDictionary:mutableDict];
+}
+
+- (NSString *)description 
+{
+    return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
+}
+
+#pragma mark - Helper Method
+- (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
+{
+    id object = [dict objectForKey:aKey];
+    if ([object isKindOfClass:[NSNumber class]]) {
+        NSNumber *number = object;
+        object = [number stringValue];
+    }
+    return [object isEqual:[NSNull null]] ? nil : object;
+}
+
+
+#pragma mark - NSCoding Methods
+
+- (id)initWithCoder:(NSCoder *)aDecoder
+{
+    self = [super init];
+
+    self.status = [aDecoder decodeObjectForKey:kHomeMessageModelStatus];
+    self.content = [aDecoder decodeObjectForKey:kHomeMessageModelContent];
+    self.userId = [aDecoder decodeDoubleForKey:kHomeMessageModelId];
+    self.updateTime = [aDecoder decodeObjectForKey:kHomeMessageModelUpdateTime];
+    self.title = [aDecoder decodeObjectForKey:kHomeMessageModelTitle];
+    self.coverImage = [aDecoder decodeObjectForKey:kHomeMessageModelCoverImage];
+    self.type = [aDecoder decodeDoubleForKey:kHomeMessageModelType];
+    self.createTime = [aDecoder decodeObjectForKey:kHomeMessageModelCreateTime];
+    self.linkUrl = [aDecoder decodeObjectForKey:kHomeMessageModelLinkUrl];
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)aCoder
+{
+
+    [aCoder encodeObject:_status forKey:kHomeMessageModelStatus];
+    [aCoder encodeObject:_content forKey:kHomeMessageModelContent];
+    [aCoder encodeDouble:_userId forKey:kHomeMessageModelId];
+    [aCoder encodeObject:_updateTime forKey:kHomeMessageModelUpdateTime];
+    [aCoder encodeObject:_title forKey:kHomeMessageModelTitle];
+    [aCoder encodeObject:_coverImage forKey:kHomeMessageModelCoverImage];
+    [aCoder encodeDouble:_type forKey:kHomeMessageModelType];
+    [aCoder encodeObject:_createTime forKey:kHomeMessageModelCreateTime];
+    [aCoder encodeObject:_linkUrl forKey:kHomeMessageModelLinkUrl];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    HomeMessageModel *copy = [[HomeMessageModel alloc] init];
+    
+    if (copy) {
+
+        copy.status = [self.status copyWithZone:zone];
+        copy.content = [self.content copyWithZone:zone];
+        copy.userId = self.userId;
+        copy.updateTime = [self.updateTime copyWithZone:zone];
+        copy.title = [self.title copyWithZone:zone];
+        copy.coverImage = [self.coverImage copyWithZone:zone];
+        copy.type = self.type;
+        copy.createTime = [self.createTime copyWithZone:zone];
+        copy.linkUrl = [self.linkUrl copyWithZone:zone];
+    }
+    
+    return copy;
+}
+
+
+@end

+ 20 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerCell.h

@@ -0,0 +1,20 @@
+//
+//  HomeBannerCell.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import <UIKit/UIKit.h>
+#import "HomeMessageModel.h"
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HomeBannerCell : UICollectionViewCell
+
+- (void)configCellWithModel:(HomeMessageModel *)sourceModel;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 27 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerCell.m

@@ -0,0 +1,27 @@
+//
+//  HomeBannerCell.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import "HomeBannerCell.h"
+
+@interface HomeBannerCell ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *bannerImage;
+
+@end
+
+@implementation HomeBannerCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+}
+
+- (void)configCellWithModel:(HomeMessageModel *)sourceModel {
+    [self.bannerImage sd_setImageWithURL:[NSURL URLWithString:sourceModel.coverImage] placeholderImage:[UIImage imageNamed:@"video_placeholder"]];
+}
+
+@end

+ 44 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerCell.xib

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.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"/>
+        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="HomeBannerCell">
+            <rect key="frame" x="0.0" y="0.0" width="389" height="143"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                <rect key="frame" x="0.0" y="0.0" width="389" height="143"/>
+                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                <subviews>
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="video_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="KRw-yx-PyP">
+                        <rect key="frame" x="0.0" y="0.0" width="389" height="143"/>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="12"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </imageView>
+                </subviews>
+            </view>
+            <viewLayoutGuide key="safeArea" id="SEy-5g-ep8"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="KRw-yx-PyP" secondAttribute="trailing" id="E99-a0-3To"/>
+                <constraint firstItem="KRw-yx-PyP" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="k9u-re-YWc"/>
+                <constraint firstAttribute="bottom" secondItem="KRw-yx-PyP" secondAttribute="bottom" id="nom-3g-a3v"/>
+                <constraint firstItem="KRw-yx-PyP" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="o6d-XR-yAa"/>
+            </constraints>
+            <size key="customSize" width="389" height="143"/>
+            <point key="canvasLocation" x="377.536231884058" y="102.79017857142857"/>
+        </collectionViewCell>
+    </objects>
+    <resources>
+        <image name="video_placeholder" width="103" height="72"/>
+    </resources>
+</document>

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerView.h

@@ -0,0 +1,22 @@
+//
+//  HomeBannerView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HomeBannerView : UIView
+
+@property (weak, nonatomic) IBOutlet UIView *bannerContentView;
+
++ (instancetype)shareInstance;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 29 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerView.m

@@ -0,0 +1,29 @@
+//
+//  HomeBannerView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import "HomeBannerView.h"
+
+@implementation HomeBannerView
+
++ (instancetype)shareInstance {
+    HomeBannerView *view = [[[NSBundle mainBundle] loadNibNamed:@"HomeBannerView" owner:nil options:nil] firstObject];
+    return view;
+}
+
++ (CGFloat)getViewHeight {
+    return (KPortraitWidth - 14 * 2) * 132 / 347 + 20;
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 37 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeBannerView.xib

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20037"/>
+        <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" customClass="HomeBannerView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="185"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TxO-MH-UVa">
+                    <rect key="frame" x="14" y="10" width="386" height="165"/>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="TxO-MH-UVa" secondAttribute="trailing" constant="14" id="0r3-Rk-6nL"/>
+                <constraint firstItem="TxO-MH-UVa" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="BF3-AJ-S65"/>
+                <constraint firstAttribute="bottom" secondItem="TxO-MH-UVa" secondAttribute="bottom" constant="10" id="FoY-Yd-bSd"/>
+                <constraint firstItem="TxO-MH-UVa" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="zwG-j0-akh"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="bannerContentView" destination="TxO-MH-UVa" id="yig-BR-84P"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="-166.40625"/>
+        </view>
+    </objects>
+</document>

+ 30 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeButtonView.h

@@ -0,0 +1,30 @@
+//
+//  HomeButtonView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HomeButtonView : UIView
+
+@property (weak, nonatomic) IBOutlet UIView *buttonContentView;
+
+@property (weak, nonatomic) IBOutlet UIView *buttonPageCtrl;
+
+@property (weak, nonatomic) IBOutlet UIView *pageDot;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *buttonDotLeft;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *buttonDotWidth;
+
++ (instancetype)shareInstance;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 28 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeButtonView.m

@@ -0,0 +1,28 @@
+//
+//  HomeButtonView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import "HomeButtonView.h"
+
+@implementation HomeButtonView
+
++ (instancetype)shareInstance {
+    HomeButtonView *view = [[[NSBundle mainBundle] loadNibNamed:@"HomeButtonView" owner:nil options:nil] firstObject];
+    return view;
+}
+
++ (CGFloat)getViewHeight {
+    return 110.0f;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 77 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeButtonView.xib

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20037"/>
+        <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" customClass="HomeButtonView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="115"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FDF-ZT-TJx">
+                    <rect key="frame" x="0.0" y="10" width="414" height="100"/>
+                    <subviews>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Hu0-Qz-IjA">
+                            <rect key="frame" x="189" y="86" width="36" height="4"/>
+                            <subviews>
+                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9Qq-0N-maI">
+                                    <rect key="frame" x="0.0" y="0.0" width="18" height="4"/>
+                                    <color key="backgroundColor" red="0.0039215686269999999" green="0.75686274509999996" blue="0.70980392160000005" alpha="1" colorSpace="calibratedRGB"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="18" id="HF0-79-ZOQ"/>
+                                    </constraints>
+                                    <userDefinedRuntimeAttributes>
+                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                            <real key="value" value="2"/>
+                                        </userDefinedRuntimeAttribute>
+                                    </userDefinedRuntimeAttributes>
+                                </view>
+                            </subviews>
+                            <color key="backgroundColor" red="0.92156862750000001" green="0.92156862750000001" blue="0.92156862750000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <constraints>
+                                <constraint firstItem="9Qq-0N-maI" firstAttribute="top" secondItem="Hu0-Qz-IjA" secondAttribute="top" id="03a-hK-kLd"/>
+                                <constraint firstAttribute="bottom" secondItem="9Qq-0N-maI" secondAttribute="bottom" id="AOu-5X-e7N"/>
+                                <constraint firstAttribute="width" constant="36" id="Ftu-7O-gVM"/>
+                                <constraint firstItem="9Qq-0N-maI" firstAttribute="leading" secondItem="Hu0-Qz-IjA" secondAttribute="leading" id="Gbt-lz-MWl"/>
+                                <constraint firstAttribute="height" constant="4" id="SEn-Hw-wmX"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="2"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="Hu0-Qz-IjA" firstAttribute="centerX" secondItem="FDF-ZT-TJx" secondAttribute="centerX" id="Hsr-mg-qWh"/>
+                        <constraint firstAttribute="height" constant="100" id="NcO-ha-Gmb"/>
+                        <constraint firstAttribute="bottom" secondItem="Hu0-Qz-IjA" secondAttribute="bottom" constant="10" id="YkV-kK-CMd"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="FDF-ZT-TJx" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="D3O-sT-Grz"/>
+                <constraint firstItem="FDF-ZT-TJx" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="WkT-zx-U1t"/>
+                <constraint firstAttribute="trailing" secondItem="FDF-ZT-TJx" secondAttribute="trailing" id="vJG-sS-Gpn"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="buttonContentView" destination="FDF-ZT-TJx" id="736-Mg-5pC"/>
+                <outlet property="buttonDotLeft" destination="Gbt-lz-MWl" id="jQi-Dc-Y0g"/>
+                <outlet property="buttonDotWidth" destination="HF0-79-ZOQ" id="ogM-Ak-FDg"/>
+                <outlet property="buttonPageCtrl" destination="Hu0-Qz-IjA" id="VVs-D3-azH"/>
+                <outlet property="pageDot" destination="9Qq-0N-maI" id="Fa4-d7-dmt"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="37.834821428571423"/>
+        </view>
+    </objects>
+</document>

+ 31 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeCourseTipsView.h

@@ -0,0 +1,31 @@
+//
+//  HomeCourseTipsView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, COURSETYPE) {
+    COURSETYPE_ACCOMPANY, // 陪练课
+    COURSETYPE_LIVE,      // 直播课
+};
+
+typedef void(^HomeCourseCallback)(COURSETYPE type, NSString * _Nonnull courseId);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HomeCourseTipsView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)configWithCourseMessage:(id)source;
+
+- (void)joinRoomCallback:(HomeCourseCallback)callback;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 58 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeCourseTipsView.m

@@ -0,0 +1,58 @@
+//
+//  HomeCourseTipsView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import "HomeCourseTipsView.h"
+
+@interface HomeCourseTipsView ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *teacherAvatar;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseName;
+
+@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
+
+@property (nonatomic, copy) HomeCourseCallback callback;
+
+@end
+
+@implementation HomeCourseTipsView
+
++ (instancetype)shareInstance {
+    HomeCourseTipsView *view = [[[NSBundle mainBundle] loadNibNamed:@"HomeCourseTipsView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configWithCourseMessage:(id)source {
+    
+}
+
+- (void)joinRoomCallback:(HomeCourseCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)joinRoomAction:(id)sender {
+    if (self.callback) {
+        self.callback(COURSETYPE_LIVE, @"");
+    }
+}
+
+
++ (CGFloat)getViewHeight {
+    return 80.0f;
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 135 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeCourseTipsView.xib

@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <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" customClass="HomeCourseTipsView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="80"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3RJ-oY-GLg">
+                    <rect key="frame" x="14" y="10" width="386" height="60"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="user_default_avatal" translatesAutoresizingMaskIntoConstraints="NO" id="Jld-ti-AY3">
+                            <rect key="frame" x="7" y="6" width="48" height="48"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="48" id="ofG-UR-djl"/>
+                                <constraint firstAttribute="height" constant="48" id="tML-m8-bbP"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="24"/>
+                                </userDefinedRuntimeAttribute>
+                                <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                    <color key="value" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
+                                </userDefinedRuntimeAttribute>
+                                <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                    <real key="value" value="2"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </imageView>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="homeCourse_notice" translatesAutoresizingMaskIntoConstraints="NO" id="XLv-21-YKG">
+                            <rect key="frame" x="43" y="33" width="20" height="21"/>
+                        </imageView>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="竖笛直播课即将开始" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aJw-9X-t4v">
+                            <rect key="frame" x="70" y="11" width="199" height="17"/>
+                            <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>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="今日 16:30-17:05" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="o9U-Ig-hhv">
+                            <rect key="frame" x="70" y="39" width="97" height="15"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                            <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cQM-ma-gAP">
+                            <rect key="frame" x="295" y="14" width="72" height="32"/>
+                            <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="32" id="RBt-J1-XKc"/>
+                                <constraint firstAttribute="width" constant="72" id="dFD-Cd-jeO"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="13"/>
+                            <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="16"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                            <connections>
+                                <action selector="joinRoomAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="hy1-oJ-dCA"/>
+                            </connections>
+                        </button>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="swJ-ep-4EY">
+                            <rect key="frame" x="284" y="15" width="1" height="30"/>
+                            <color key="backgroundColor" red="0.84705882352941175" green="0.84705882352941175" blue="0.84705882352941175" alpha="1" colorSpace="calibratedRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="1" id="QF8-Ds-9Z9"/>
+                                <constraint firstAttribute="height" constant="30" id="bcn-b8-fVq"/>
+                            </constraints>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstItem="o9U-Ig-hhv" firstAttribute="leading" secondItem="aJw-9X-t4v" secondAttribute="leading" id="1AP-QY-Vt0"/>
+                        <constraint firstItem="cQM-ma-gAP" firstAttribute="centerY" secondItem="3RJ-oY-GLg" secondAttribute="centerY" id="Azt-cT-KP4"/>
+                        <constraint firstItem="Jld-ti-AY3" firstAttribute="leading" secondItem="3RJ-oY-GLg" secondAttribute="leading" constant="7" id="Dyw-ap-x7H"/>
+                        <constraint firstAttribute="height" constant="60" id="HEJ-Kq-2Q7"/>
+                        <constraint firstItem="XLv-21-YKG" firstAttribute="centerX" secondItem="Jld-ti-AY3" secondAttribute="trailing" constant="-2" id="HrP-NZ-Nz0"/>
+                        <constraint firstItem="swJ-ep-4EY" firstAttribute="centerY" secondItem="3RJ-oY-GLg" secondAttribute="centerY" id="KKo-mu-tJC"/>
+                        <constraint firstItem="aJw-9X-t4v" firstAttribute="top" secondItem="Jld-ti-AY3" secondAttribute="top" constant="5" id="V5c-pA-xph"/>
+                        <constraint firstItem="aJw-9X-t4v" firstAttribute="leading" secondItem="Jld-ti-AY3" secondAttribute="trailing" constant="15" id="Wrh-eB-lkY"/>
+                        <constraint firstAttribute="trailing" secondItem="cQM-ma-gAP" secondAttribute="trailing" constant="19" id="goH-Zh-W1g"/>
+                        <constraint firstItem="Jld-ti-AY3" firstAttribute="centerY" secondItem="3RJ-oY-GLg" secondAttribute="centerY" id="iP8-jy-Yrd"/>
+                        <constraint firstItem="swJ-ep-4EY" firstAttribute="leading" secondItem="aJw-9X-t4v" secondAttribute="trailing" constant="15" id="iok-82-t4n"/>
+                        <constraint firstItem="XLv-21-YKG" firstAttribute="bottom" secondItem="Jld-ti-AY3" secondAttribute="bottom" id="k4q-Cr-M10"/>
+                        <constraint firstItem="o9U-Ig-hhv" firstAttribute="bottom" secondItem="Jld-ti-AY3" secondAttribute="bottom" id="tXD-64-QsG"/>
+                        <constraint firstItem="cQM-ma-gAP" firstAttribute="leading" secondItem="swJ-ep-4EY" secondAttribute="trailing" constant="10" id="w72-LY-Ahe"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="30"/>
+                        </userDefinedRuntimeAttribute>
+                        <userDefinedRuntimeAttribute type="color" keyPath="shadowUIColor">
+                            <color key="value" red="0.82745098039215681" green="0.82745098039215681" blue="0.82745098039215681" alpha="0.080000000000000002" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                        </userDefinedRuntimeAttribute>
+                        <userDefinedRuntimeAttribute type="size" keyPath="shadowOffset">
+                            <size key="value" width="2" height="1"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="3RJ-oY-GLg" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="gaz-ov-WF0"/>
+                <constraint firstAttribute="trailing" secondItem="3RJ-oY-GLg" secondAttribute="trailing" constant="14" id="kpz-us-IDC"/>
+                <constraint firstItem="3RJ-oY-GLg" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="mJa-3d-BOB"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="courseName" destination="aJw-9X-t4v" id="jpp-pR-7kH"/>
+                <outlet property="teacherAvatar" destination="Jld-ti-AY3" id="8rL-If-Hud"/>
+                <outlet property="timeLabel" destination="o9U-Ig-hhv" id="r2x-4g-7Wt"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="38.839285714285715"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="homeCourse_notice" width="20" height="21"/>
+        <image name="user_default_avatal" width="52" height="52"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 18 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumCell.h

@@ -0,0 +1,18 @@
+//
+//  HomeHotAlbumCell.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HomeHotAlbumCell : UICollectionViewCell
+
+
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 27 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumCell.m

@@ -0,0 +1,27 @@
+//
+//  HomeHotAlbumCell.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import "HomeHotAlbumCell.h"
+
+@interface HomeHotAlbumCell ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *albumImage;
+
+@property (weak, nonatomic) IBOutlet UILabel *albumNameLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *collectLabel;
+
+@end
+
+@implementation HomeHotAlbumCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+}
+
+@end

+ 100 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumCell.xib

@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <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"/>
+        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="HomeHotAlbumCell">
+            <rect key="frame" x="0.0" y="0.0" width="120" height="140"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                <rect key="frame" x="0.0" y="0.0" width="120" height="140"/>
+                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="VLb-Eb-jdx">
+                        <rect key="frame" x="34" y="16" width="82" height="82"/>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="82" id="scg-Qi-Jfr"/>
+                            <constraint firstAttribute="width" constant="82" id="tqB-Hb-Jjd"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="9"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="video_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="mkp-8k-Rld">
+                        <rect key="frame" x="16" y="10" width="94" height="94"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="94" id="OYN-0Q-mPG"/>
+                            <constraint firstAttribute="width" constant="94" id="wU7-tF-QtE"/>
+                        </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="1bh-Zm-ov0">
+                        <rect key="frame" x="16" y="114" width="100" height="20"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="20" id="s4H-Kv-zgp"/>
+                        </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="xPp-Kr-NCd">
+                        <rect key="frame" x="28" y="76" width="70" height="20"/>
+                        <subviews>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="365人收藏" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HyK-tc-JYn">
+                                <rect key="frame" x="7" y="2" width="56" height="16"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="16" id="QTs-RA-B2w"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="medium" pointSize="11"/>
+                                <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" red="0.2627450980392157" green="0.2627450980392157" blue="0.2627450980392157" alpha="0.29999999999999999" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                        <constraints>
+                            <constraint firstAttribute="trailing" secondItem="HyK-tc-JYn" secondAttribute="trailing" constant="7" id="4Qh-GF-qUt"/>
+                            <constraint firstItem="HyK-tc-JYn" firstAttribute="top" secondItem="xPp-Kr-NCd" secondAttribute="top" constant="2" id="KDW-ks-TaU"/>
+                            <constraint firstItem="HyK-tc-JYn" firstAttribute="leading" secondItem="xPp-Kr-NCd" secondAttribute="leading" constant="7" id="oZX-c6-fga"/>
+                            <constraint firstAttribute="bottom" secondItem="HyK-tc-JYn" secondAttribute="bottom" constant="2" id="vLb-NQ-3ma"/>
+                        </constraints>
+                    </view>
+                </subviews>
+            </view>
+            <viewLayoutGuide key="safeArea" id="SEy-5g-ep8"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="mkp-8k-Rld" secondAttribute="trailing" constant="10" id="2hf-72-pRd"/>
+                <constraint firstItem="1bh-Zm-ov0" firstAttribute="top" secondItem="mkp-8k-Rld" secondAttribute="bottom" constant="10" id="8Ah-sJ-mEm"/>
+                <constraint firstAttribute="trailing" secondItem="VLb-Eb-jdx" secondAttribute="trailing" constant="4" id="AYd-Kv-Z9i"/>
+                <constraint firstItem="mkp-8k-Rld" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" constant="10" id="XeE-bJ-DC9"/>
+                <constraint firstItem="xPp-Kr-NCd" firstAttribute="centerX" secondItem="mkp-8k-Rld" secondAttribute="centerX" id="Z55-XZ-bW6"/>
+                <constraint firstItem="1bh-Zm-ov0" firstAttribute="trailing" secondItem="VLb-Eb-jdx" secondAttribute="trailing" id="bb6-JR-ram"/>
+                <constraint firstItem="1bh-Zm-ov0" firstAttribute="leading" secondItem="mkp-8k-Rld" secondAttribute="leading" id="swt-MU-p2E"/>
+                <constraint firstItem="xPp-Kr-NCd" firstAttribute="bottom" secondItem="mkp-8k-Rld" secondAttribute="bottom" constant="-8" id="vEg-aT-hU0"/>
+                <constraint firstItem="VLb-Eb-jdx" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" constant="16" id="xbu-OQ-0bN"/>
+            </constraints>
+            <size key="customSize" width="121" height="142"/>
+            <connections>
+                <outlet property="albumImage" destination="mkp-8k-Rld" id="Hdo-Go-aYB"/>
+                <outlet property="albumNameLabel" destination="1bh-Zm-ov0" id="KrW-Bf-gSu"/>
+                <outlet property="collectLabel" destination="HyK-tc-JYn" id="NNp-Qk-B0u"/>
+            </connections>
+            <point key="canvasLocation" x="306.52173913043481" y="89.0625"/>
+        </collectionViewCell>
+    </objects>
+    <resources>
+        <image name="video_placeholder" width="103" height="72"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 26 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumView.h

@@ -0,0 +1,26 @@
+//
+//  HomeHotAlbumView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef void(^HomeAlbumMoreBlock)(void);
+
+@interface HomeHotAlbumView : UIView
+
+@property (weak, nonatomic) IBOutlet UIView *albumContentView;
+
++ (instancetype)shareInstance;
+
+- (void)homeAlbumMore:(HomeAlbumMoreBlock)callback;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 48 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumView.m

@@ -0,0 +1,48 @@
+//
+//  HomeHotAlbumView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import "HomeHotAlbumView.h"
+
+@interface HomeHotAlbumView ()
+
+@property (nonatomic, copy) HomeAlbumMoreBlock callback;
+
+@end
+
+@implementation HomeHotAlbumView
+
++ (instancetype)shareInstance {
+    HomeHotAlbumView *view = [[[NSBundle mainBundle] loadNibNamed:@"HomeHotAlbumView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)homeAlbumMore:(HomeAlbumMoreBlock)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)moreDetail:(id)sender {
+    if (self.callback) {
+        self.callback();
+    }
+}
+
+
++ (CGFloat)getViewHeight {
+    return 190.0f;
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 82 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotAlbumView.xib

@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <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" customClass="HomeHotAlbumView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="180"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="更多" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zgK-R6-zz8">
+                    <rect key="frame" x="355" y="14" width="25" height="14.5"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                    <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="热门专辑" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="u9G-3b-Wgt">
+                    <rect key="frame" x="14" y="10" width="65.5" height="22"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="22" id="mNH-cs-reJ"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                    <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_more" translatesAutoresizingMaskIntoConstraints="NO" id="OkW-qe-3Kq">
+                    <rect key="frame" x="384" y="16" width="10" height="10"/>
+                </imageView>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bvf-n0-Khb">
+                    <rect key="frame" x="0.0" y="46" width="414" height="130"/>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="130" id="hLT-Oy-zVJ"/>
+                    </constraints>
+                </view>
+                <button opaque="NO" tag="1008" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kIU-g4-ctC">
+                    <rect key="frame" x="355" y="6" width="39" height="30"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="30" id="l3w-24-Jol"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                    <state key="normal">
+                        <color key="titleColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="0.84705882349999995" colorSpace="calibratedRGB"/>
+                    </state>
+                    <connections>
+                        <action selector="moreDetail:" destination="iN0-l3-epB" eventType="touchUpInside" id="Si8-kK-NiF"/>
+                    </connections>
+                </button>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="OkW-qe-3Kq" firstAttribute="centerY" secondItem="u9G-3b-Wgt" secondAttribute="centerY" id="0C2-jz-ybg"/>
+                <constraint firstAttribute="trailing" secondItem="OkW-qe-3Kq" secondAttribute="trailing" constant="20" id="406-yJ-0Qm"/>
+                <constraint firstItem="u9G-3b-Wgt" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="GyF-gJ-3Ba"/>
+                <constraint firstAttribute="trailing" secondItem="bvf-n0-Khb" secondAttribute="trailing" id="Hzs-4d-CyT"/>
+                <constraint firstItem="OkW-qe-3Kq" firstAttribute="trailing" secondItem="kIU-g4-ctC" secondAttribute="trailing" id="Jbh-O6-QXS"/>
+                <constraint firstItem="bvf-n0-Khb" firstAttribute="top" secondItem="u9G-3b-Wgt" secondAttribute="bottom" constant="14" id="M9Y-eb-zMS"/>
+                <constraint firstItem="bvf-n0-Khb" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="a0y-wq-MEu"/>
+                <constraint firstItem="OkW-qe-3Kq" firstAttribute="leading" secondItem="zgK-R6-zz8" secondAttribute="trailing" constant="4" id="aT3-GI-PH3"/>
+                <constraint firstItem="u9G-3b-Wgt" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="eRX-8J-T9f"/>
+                <constraint firstItem="zgK-R6-zz8" firstAttribute="leading" secondItem="kIU-g4-ctC" secondAttribute="leading" id="fOa-SI-oGA"/>
+                <constraint firstItem="zgK-R6-zz8" firstAttribute="centerY" secondItem="u9G-3b-Wgt" secondAttribute="centerY" id="p7u-UZ-CQL"/>
+                <constraint firstItem="kIU-g4-ctC" firstAttribute="centerY" secondItem="u9G-3b-Wgt" secondAttribute="centerY" id="sWH-G6-1lp"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="albumContentView" destination="bvf-n0-Khb" id="o8m-Jb-zPr"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="1.3392857142857142"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="home_more" width="10" height="10"/>
+    </resources>
+</document>

+ 32 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotCourseView.h

@@ -0,0 +1,32 @@
+//
+//  HomeHotCourseView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, COURSE_ACTION) {
+    COURSE_ACTION_LIVE,   // 视频课
+    COURSE_ACTION_VIDEO,  // 直播课
+    COURSE_ACTION_MORE,   // 更多
+};
+
+typedef void(^HotCourseCallback)(COURSE_ACTION action);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HomeHotCourseView : UIView
+
+@property (weak, nonatomic) IBOutlet UIView *courseContainer;
+
++ (instancetype)shareInstance;
+
+- (void)courseActionCallback:(HotCourseCallback)callback;
+
+- (CGFloat)getViewHeightWithCount:(NSInteger)count;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 91 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotCourseView.m

@@ -0,0 +1,91 @@
+//
+//  HomeHotCourseView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import "HomeHotCourseView.h"
+
+@interface HomeHotCourseView ()
+
+@property (nonatomic, copy) HotCourseCallback callback;
+
+@property (weak, nonatomic) IBOutlet UILabel *LiveLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *videoLabel;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leftConstraint;
+
+@end
+
+@implementation HomeHotCourseView
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    self.leftConstraint.constant = 30.5f;
+}
+
++ (instancetype)shareInstance {
+    HomeHotCourseView *view = [[[NSBundle mainBundle] loadNibNamed:@"HomeHotCourseView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)courseActionCallback:(HotCourseCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)livePage:(id)sender {
+    [self chooseLivePage:YES];
+    if (self.callback) {
+        self.callback(COURSE_ACTION_LIVE);
+    }
+}
+
+- (IBAction)videoPage:(id)sender {
+    [self chooseLivePage:NO];
+    if (self.callback) {
+        self.callback(COURSE_ACTION_VIDEO);
+    }
+}
+
+- (IBAction)moreDetail:(id)sender {
+    if (self.callback) {
+        self.callback(COURSE_ACTION_MORE);
+    }
+}
+
+
+- (void)chooseLivePage:(BOOL)chooseLivePage {
+    if (chooseLivePage) {
+        self.leftConstraint.constant = 30.5f;
+        self.LiveLabel.textColor = HexRGB(0x333333);
+        self.LiveLabel.font = [UIFont systemFontOfSize:16.0f weight:UIFontWeightMedium];
+        
+        self.videoLabel.textColor = HexRGB(0x999999);
+        self.videoLabel.font = [UIFont systemFontOfSize:16.0f];
+    }
+    else {
+        self.leftConstraint.constant = 116.5f;
+        self.LiveLabel.textColor = HexRGB(0x999999);
+        self.LiveLabel.font = [UIFont systemFontOfSize:16.0f];
+        
+        self.videoLabel.textColor = HexRGB(0x333333);
+        self.videoLabel.font = [UIFont systemFontOfSize:16.0f weight:UIFontWeightMedium];
+    }
+}
+
+- (CGFloat)getViewHeightWithCount:(NSInteger)count {
+    return 57 + count * 126;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 145 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeHotCourseView.xib

@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <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" customClass="HomeHotCourseView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="414"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="直播课" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dVJ-dx-TCI">
+                    <rect key="frame" x="16" y="10" width="49" height="22"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="22" id="zKb-rt-71C"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                    <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3ne-eb-P75">
+                    <rect key="frame" x="16" y="6" width="49" height="30"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="30" id="j7v-Vi-sw9"/>
+                    </constraints>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <connections>
+                        <action selector="livePage:" destination="iN0-l3-epB" eventType="touchUpInside" id="SEN-xe-Um5"/>
+                    </connections>
+                </button>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JJx-GE-N6X">
+                    <rect key="frame" x="83" y="14" width="1" height="14"/>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="14" id="99i-Ec-9Np"/>
+                        <constraint firstAttribute="width" constant="1" id="CiS-a6-7Se"/>
+                    </constraints>
+                </view>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="视频课" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Mbb-UI-0Ro">
+                    <rect key="frame" x="102" y="10" width="49" height="22"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="22" id="Eit-kP-aPk"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                    <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="f1s-C8-bDr">
+                    <rect key="frame" x="102" y="6" width="49" height="30"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="30" id="YiF-CE-eOR"/>
+                    </constraints>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <connections>
+                        <action selector="videoPage:" destination="iN0-l3-epB" eventType="touchUpInside" id="1IS-e6-Dgf"/>
+                    </connections>
+                </button>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="更多" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HNM-Px-jlP">
+                    <rect key="frame" x="355" y="14" width="25" height="14.5"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                    <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_more" translatesAutoresizingMaskIntoConstraints="NO" id="yA6-xr-ZOC">
+                    <rect key="frame" x="384" y="16" width="10" height="10"/>
+                </imageView>
+                <button opaque="NO" tag="1008" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6X9-nr-VSO">
+                    <rect key="frame" x="355" y="6" width="39" height="30"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="30" id="FLG-iJ-uP5"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                    <state key="normal">
+                        <color key="titleColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="0.84705882349999995" colorSpace="calibratedRGB"/>
+                    </state>
+                    <connections>
+                        <action selector="moreDetail:" destination="iN0-l3-epB" eventType="touchUpInside" id="WKd-JK-3gy"/>
+                    </connections>
+                </button>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_radainLine" translatesAutoresizingMaskIntoConstraints="NO" id="kgP-i0-eRV">
+                    <rect key="frame" x="30.5" y="37" width="20" height="7"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="7" id="9PH-Hu-7AX"/>
+                        <constraint firstAttribute="width" constant="20" id="stC-Gr-WjV"/>
+                    </constraints>
+                </imageView>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IRE-c2-PJV">
+                    <rect key="frame" x="0.0" y="57" width="414" height="347"/>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="yA6-xr-ZOC" firstAttribute="trailing" secondItem="6X9-nr-VSO" secondAttribute="trailing" id="2XB-me-3JH"/>
+                <constraint firstAttribute="bottom" secondItem="IRE-c2-PJV" secondAttribute="bottom" constant="10" id="2d3-xX-ssq"/>
+                <constraint firstItem="kgP-i0-eRV" firstAttribute="top" secondItem="dVJ-dx-TCI" secondAttribute="bottom" constant="5" id="7kF-T8-hxz"/>
+                <constraint firstAttribute="trailing" secondItem="yA6-xr-ZOC" secondAttribute="trailing" constant="20" id="B2y-Js-cvn"/>
+                <constraint firstItem="JJx-GE-N6X" firstAttribute="centerY" secondItem="dVJ-dx-TCI" secondAttribute="centerY" id="Bl1-EM-IUN"/>
+                <constraint firstItem="f1s-C8-bDr" firstAttribute="centerY" secondItem="Mbb-UI-0Ro" secondAttribute="centerY" id="Ejn-eA-P5h"/>
+                <constraint firstItem="HNM-Px-jlP" firstAttribute="leading" secondItem="6X9-nr-VSO" secondAttribute="leading" id="GAz-wd-ujO"/>
+                <constraint firstItem="yA6-xr-ZOC" firstAttribute="centerY" secondItem="HNM-Px-jlP" secondAttribute="centerY" id="H1W-gz-iHE"/>
+                <constraint firstItem="dVJ-dx-TCI" firstAttribute="centerY" secondItem="3ne-eb-P75" secondAttribute="centerY" id="Hmy-Aa-FTR"/>
+                <constraint firstItem="JJx-GE-N6X" firstAttribute="leading" secondItem="dVJ-dx-TCI" secondAttribute="trailing" constant="18" id="M1Y-JX-mJJ"/>
+                <constraint firstItem="IRE-c2-PJV" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="Nqj-o9-SCF"/>
+                <constraint firstItem="dVJ-dx-TCI" firstAttribute="trailing" secondItem="3ne-eb-P75" secondAttribute="trailing" id="XwP-KM-a4U"/>
+                <constraint firstItem="yA6-xr-ZOC" firstAttribute="trailing" secondItem="6X9-nr-VSO" secondAttribute="trailing" id="Zd9-le-516"/>
+                <constraint firstItem="f1s-C8-bDr" firstAttribute="trailing" secondItem="Mbb-UI-0Ro" secondAttribute="trailing" id="chu-sU-tbJ"/>
+                <constraint firstItem="dVJ-dx-TCI" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="16" id="h3o-Gh-ltX"/>
+                <constraint firstAttribute="trailing" secondItem="IRE-c2-PJV" secondAttribute="trailing" id="hag-xt-sm9"/>
+                <constraint firstItem="6X9-nr-VSO" firstAttribute="centerY" secondItem="HNM-Px-jlP" secondAttribute="centerY" id="hs2-Kr-7Ek"/>
+                <constraint firstItem="dVJ-dx-TCI" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="j7e-W2-5wt"/>
+                <constraint firstItem="IRE-c2-PJV" firstAttribute="top" secondItem="kgP-i0-eRV" secondAttribute="bottom" constant="13" id="jLf-0p-FnW"/>
+                <constraint firstItem="kgP-i0-eRV" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="30.5" id="jSq-EF-PAZ"/>
+                <constraint firstItem="HNM-Px-jlP" firstAttribute="centerY" secondItem="Mbb-UI-0Ro" secondAttribute="centerY" id="jpt-QA-1ke"/>
+                <constraint firstItem="yA6-xr-ZOC" firstAttribute="leading" secondItem="HNM-Px-jlP" secondAttribute="trailing" constant="4" id="kla-3S-7XE"/>
+                <constraint firstItem="f1s-C8-bDr" firstAttribute="leading" secondItem="Mbb-UI-0Ro" secondAttribute="leading" id="ric-NF-UHw"/>
+                <constraint firstItem="Mbb-UI-0Ro" firstAttribute="leading" secondItem="JJx-GE-N6X" secondAttribute="trailing" constant="18" id="wCJ-9p-G4M"/>
+                <constraint firstItem="dVJ-dx-TCI" firstAttribute="leading" secondItem="3ne-eb-P75" secondAttribute="leading" id="yx0-fs-dUu"/>
+                <constraint firstItem="Mbb-UI-0Ro" firstAttribute="centerY" secondItem="JJx-GE-N6X" secondAttribute="centerY" id="za4-nx-FeC"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="LiveLabel" destination="dVJ-dx-TCI" id="hdV-Kr-Eav"/>
+                <outlet property="courseContainer" destination="IRE-c2-PJV" id="gzy-OD-Ri5"/>
+                <outlet property="leftConstraint" destination="jSq-EF-PAZ" id="q9g-ad-9So"/>
+                <outlet property="videoLabel" destination="Mbb-UI-0Ro" id="2gC-Du-ah2"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="-89.732142857142847"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="home_more" width="10" height="10"/>
+        <image name="home_radainLine" width="20" height="7"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 26 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeInformationCell.h

@@ -0,0 +1,26 @@
+//
+//  HomeInformationCell.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import <UIKit/UIKit.h>
+#import "HomeMessageModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_ENUM(NSInteger, ROWINDEX) {
+    ROWINDEX_TOP,
+    ROWINDEX_MIDDLE,
+    ROWINDEX_BOTTOM,
+};
+
+@interface HomeInformationCell : UITableViewCell
+
+- (void)configCellWithSource:(HomeMessageModel *)model rowIndex:(ROWINDEX)rowIndex;
+
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 63 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeInformationCell.m

@@ -0,0 +1,63 @@
+//
+//  HomeInformationCell.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import "HomeInformationCell.h"
+
+@interface HomeInformationCell ()
+
+@property (weak, nonatomic) IBOutlet UILabel *messageTitle;
+
+@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
+
+@property (weak, nonatomic) IBOutlet UIImageView *messageImage;
+
+@property (weak, nonatomic) IBOutlet UIView *backView;
+
+@end
+
+@implementation HomeInformationCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    self.selectionStyle = UITableViewCellSelectionStyleNone;
+}
+
+- (void)configCellWithSource:(HomeMessageModel *)model rowIndex:(ROWINDEX)rowIndex {
+    self.messageTitle.text = [NSString returnNoNullStringWithString:model.title];
+    self.timeLabel.text = [model.updateTime dateFormatString];
+    [self.messageImage sd_setImageWithURL:[NSURL URLWithString:model.coverImage] placeholderImage:[UIImage imageNamed:@"video_placeholder"]];
+    if (rowIndex == ROWINDEX_TOP) {
+        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, kScreenWidth - 28, 108) byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight cornerRadii:CGSizeMake(8, 8)];
+        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
+        maskLayer.frame = self.backView.bounds;
+        maskLayer.path = maskPath.CGPath;
+        self.backView.layer.mask = maskLayer;
+    }
+    else if (rowIndex == ROWINDEX_BOTTOM) {
+        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, kScreenWidth - 28, 108) byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight cornerRadii:CGSizeMake(8, 8)];
+        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
+        maskLayer.frame = self.backView.bounds;
+        maskLayer.path = maskPath.CGPath;
+        self.backView.layer.mask = maskLayer;
+    }
+    else {
+        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, kScreenWidth - 28, 108) byRoundingCorners:UIRectCornerBottomLeft|UIRectCornerBottomRight cornerRadii:CGSizeMake(0, 0)];
+        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
+        maskLayer.frame = self.backView.bounds;
+        maskLayer.path = maskPath.CGPath;
+        self.backView.layer.mask = maskLayer;
+    }
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end

+ 86 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeInformationCell.xib

@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <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"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="KGk-i7-Jjw" customClass="HomeInformationCell">
+            <rect key="frame" x="0.0" y="0.0" width="442" height="108"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="442" height="108"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="mV5-EQ-8aL">
+                        <rect key="frame" x="14" y="0.0" width="414" height="108"/>
+                        <subviews>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="video_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="Z8V-5d-ftb">
+                                <rect key="frame" x="8" y="18" width="104" height="72"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="72" id="Ixx-fI-7pn"/>
+                                    <constraint firstAttribute="width" constant="104" id="h7s-KS-fQD"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="5"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </imageView>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2月28日 19:30" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7QX-lI-BO2">
+                                <rect key="frame" x="123" y="75" width="76" height="14"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                                <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" text="音乐中考究竟是什么?多地真题盘点一起看!" textAlignment="natural" lineBreakMode="wordWrap" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vYy-zu-7s3">
+                                <rect key="frame" x="123" y="19" width="277" height="33.5"/>
+                                <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>
+                        </subviews>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        <constraints>
+                            <constraint firstItem="Z8V-5d-ftb" firstAttribute="centerY" secondItem="mV5-EQ-8aL" secondAttribute="centerY" id="65T-Vc-Xyh"/>
+                            <constraint firstAttribute="trailing" secondItem="vYy-zu-7s3" secondAttribute="trailing" constant="14" id="7U3-xg-AYH"/>
+                            <constraint firstItem="Z8V-5d-ftb" firstAttribute="leading" secondItem="mV5-EQ-8aL" secondAttribute="leading" constant="8" id="AkI-85-N17"/>
+                            <constraint firstItem="vYy-zu-7s3" firstAttribute="leading" secondItem="Z8V-5d-ftb" secondAttribute="trailing" constant="11" id="R3E-jc-iaM"/>
+                            <constraint firstItem="vYy-zu-7s3" firstAttribute="top" secondItem="Z8V-5d-ftb" secondAttribute="top" constant="1" id="kdL-xJ-5iv"/>
+                            <constraint firstItem="7QX-lI-BO2" firstAttribute="bottom" secondItem="Z8V-5d-ftb" secondAttribute="bottom" constant="-1" id="nvO-fK-ikj"/>
+                            <constraint firstItem="7QX-lI-BO2" firstAttribute="leading" secondItem="Z8V-5d-ftb" secondAttribute="trailing" constant="11" id="rfR-4y-TIo"/>
+                        </constraints>
+                    </view>
+                </subviews>
+                <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                <constraints>
+                    <constraint firstAttribute="trailing" secondItem="mV5-EQ-8aL" secondAttribute="trailing" constant="14" id="0ad-Tb-j03"/>
+                    <constraint firstAttribute="bottom" secondItem="mV5-EQ-8aL" secondAttribute="bottom" id="XUv-gM-Sqv"/>
+                    <constraint firstItem="mV5-EQ-8aL" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="aB3-cN-RvZ"/>
+                    <constraint firstItem="mV5-EQ-8aL" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="cLe-Wg-fKX"/>
+                </constraints>
+            </tableViewCellContentView>
+            <viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <connections>
+                <outlet property="backView" destination="mV5-EQ-8aL" id="ew1-Ax-ZPM"/>
+                <outlet property="messageImage" destination="Z8V-5d-ftb" id="jJy-y1-rPF"/>
+                <outlet property="messageTitle" destination="vYy-zu-7s3" id="A78-0z-65X"/>
+                <outlet property="timeLabel" destination="7QX-lI-BO2" id="L9Q-3J-Uzq"/>
+            </connections>
+            <point key="canvasLocation" x="220.28985507246378" y="95.089285714285708"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="video_placeholder" width="103" height="72"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 26 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeIntroduceView.h

@@ -0,0 +1,26 @@
+//
+//  HomeIntroduceView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^HomeIntroduceMoreBlock)(void);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HomeIntroduceView : UIView
+
+@property (weak, nonatomic) IBOutlet UIView *teacherContainer;
+
++ (instancetype)shareInstance;
+
+- (void)introduceMore:(HomeIntroduceMoreBlock)callback;
+
+- (CGFloat)getViewHeightWithSourceCount:(NSInteger)count;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 50 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeIntroduceView.m

@@ -0,0 +1,50 @@
+//
+//  HomeIntroduceView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import "HomeIntroduceView.h"
+
+@interface HomeIntroduceView ()
+
+@property (nonatomic, copy) HomeIntroduceMoreBlock callback;
+
+@end
+
+@implementation HomeIntroduceView
+
++ (instancetype)shareInstance {
+    HomeIntroduceView *view = [[[NSBundle mainBundle] loadNibNamed:@"HomeIntroduceView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)introduceMore:(HomeIntroduceMoreBlock)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (CGFloat)getViewHeightWithSourceCount:(NSInteger)count {
+    
+    NSInteger row = count / 2 + count % 2;
+    
+    return 56 + row * 164 + (row - 1) * 12;
+    
+}
+- (IBAction)moreAction:(id)sender {
+    if (self.callback) {
+        self.callback();
+    }
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 80 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeIntroduceView.xib

@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <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" customClass="HomeIntroduceView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="166"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="老师风采" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="R1l-Xp-3tk">
+                    <rect key="frame" x="14" y="10" width="65.5" height="22"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="22" id="4eO-n3-qj3"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                    <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="1GA-dU-S4o">
+                    <rect key="frame" x="0.0" y="46" width="414" height="110"/>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                </view>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_more" translatesAutoresizingMaskIntoConstraints="NO" id="nWD-gC-NuU">
+                    <rect key="frame" x="384" y="16" width="10" height="10"/>
+                </imageView>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="更多" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RwY-C1-Hxk">
+                    <rect key="frame" x="355" y="14" width="25" height="14.5"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                    <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <button opaque="NO" tag="1008" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="spZ-ec-oEg">
+                    <rect key="frame" x="355" y="6" width="39" height="30"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="30" id="AsG-mP-8Lu"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                    <state key="normal">
+                        <color key="titleColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="0.84705882349999995" colorSpace="calibratedRGB"/>
+                    </state>
+                    <connections>
+                        <action selector="moreAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="edt-PG-XWg"/>
+                    </connections>
+                </button>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="nWD-gC-NuU" firstAttribute="centerY" secondItem="R1l-Xp-3tk" secondAttribute="centerY" id="Amd-ny-xOF"/>
+                <constraint firstItem="R1l-Xp-3tk" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="14" id="P9c-Qj-z6W"/>
+                <constraint firstItem="1GA-dU-S4o" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="SGl-fa-PFK"/>
+                <constraint firstItem="1GA-dU-S4o" firstAttribute="top" secondItem="R1l-Xp-3tk" secondAttribute="bottom" constant="14" id="ZF8-Pc-kri"/>
+                <constraint firstAttribute="trailing" secondItem="nWD-gC-NuU" secondAttribute="trailing" constant="20" id="Zd4-ek-IA6"/>
+                <constraint firstItem="RwY-C1-Hxk" firstAttribute="leading" secondItem="spZ-ec-oEg" secondAttribute="leading" id="dzW-2G-lz5"/>
+                <constraint firstItem="nWD-gC-NuU" firstAttribute="trailing" secondItem="spZ-ec-oEg" secondAttribute="trailing" id="gMg-zf-v74"/>
+                <constraint firstItem="RwY-C1-Hxk" firstAttribute="centerY" secondItem="R1l-Xp-3tk" secondAttribute="centerY" id="lNZ-xj-Kq8"/>
+                <constraint firstAttribute="trailing" secondItem="1GA-dU-S4o" secondAttribute="trailing" id="nhw-1V-bTA"/>
+                <constraint firstAttribute="bottom" secondItem="1GA-dU-S4o" secondAttribute="bottom" constant="10" id="qRe-UX-fpA"/>
+                <constraint firstItem="nWD-gC-NuU" firstAttribute="leading" secondItem="RwY-C1-Hxk" secondAttribute="trailing" constant="4" id="reH-Ia-H94"/>
+                <constraint firstItem="spZ-ec-oEg" firstAttribute="centerY" secondItem="R1l-Xp-3tk" secondAttribute="centerY" id="ta1-r5-Kds"/>
+                <constraint firstItem="R1l-Xp-3tk" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="z0l-BE-MdE"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="teacherContainer" destination="1GA-dU-S4o" id="eax-ks-ust"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="-122.54464285714285"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="home_more" width="10" height="10"/>
+    </resources>
+</document>

+ 19 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeLiveCouseCell.h

@@ -0,0 +1,19 @@
+//
+//  HomeLiveCouseCell.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import <UIKit/UIKit.h>
+#import "HomeLiveGroupModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HomeLiveCouseCell : UITableViewCell
+
+- (void)configWithSource:(HomeLiveGroupModel *)source;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 62 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeLiveCouseCell.m

@@ -0,0 +1,62 @@
+//
+//  HomeLiveCouseCell.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import "HomeLiveCouseCell.h"
+
+@interface HomeLiveCouseCell ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *coverImage;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseName;
+
+@property (weak, nonatomic) IBOutlet UILabel *teacherName;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseBegin;
+
+@property (weak, nonatomic) IBOutlet UILabel *priceLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseCountLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *descLabel;
+
+@end
+
+@implementation HomeLiveCouseCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    self.selectionStyle = UITableViewCellSelectionStyleNone;
+}
+
+- (void)configWithSource:(HomeLiveGroupModel *)source {
+    [self.coverImage sd_setImageWithURL:[NSURL URLWithString:source.avatar] placeholderImage:[UIImage imageNamed:@"video_placeholder"]];
+    self.courseName.text = [NSString returnNoNullStringWithString:source.courseGroupName];
+    self.teacherName.text = [NSString stringWithFormat:@"老师:%@",[NSString returnNoNullStringWithString:source.teacherName]];
+    self.priceLabel.text = [NSString stringWithFormat:@"¥%.2f",source.courseGroupPrice];
+    self.courseCountLabel.text = [NSString stringWithFormat:@"%.0f课时",source.courseNum];
+//    self.descLabel.text = [NSString stringWithFormat:@"%.0f人已购买",source.courseNum];
+    // 时间
+    if ([NSString isEmptyString:source.courseStartTime]) {
+        self.courseBegin.text = @"";
+    }
+    else {
+        NSDateFormatter *dateFormatter = [NSObject getDateformatter];
+        [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
+        NSDate *beginDate = [dateFormatter dateFromString:source.courseStartTime];
+        [dateFormatter setDateFormat:@"yyyy年MM月dd日 HH:mm"];
+        self.courseBegin.text = [NSString returnNoNullStringWithString:[dateFormatter stringFromDate:beginDate]];
+    }
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end

+ 155 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeLiveCouseCell.xib

@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <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"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="225" id="KGk-i7-Jjw" customClass="HomeLiveCouseCell">
+            <rect key="frame" x="0.0" y="0.0" width="432" height="126"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="432" height="126"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="d3t-M0-UQn">
+                        <rect key="frame" x="14" y="0.0" width="404" height="116"/>
+                        <subviews>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="video_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="mto-Fi-MuN">
+                                <rect key="frame" x="10" y="10" width="130" height="96"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" constant="130" id="Vwf-Ux-jKV"/>
+                                    <constraint firstAttribute="height" constant="96" id="qMT-LJ-SB3"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="8"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </imageView>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="单簧管基础入门单曲练习" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8ja-4v-aTz">
+                                <rect key="frame" x="148" y="14" width="246" height="20"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="20" id="US1-oc-Lb6"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
+                                <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="老师:李云磊" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="H4s-4H-yh0">
+                                <rect key="frame" x="148" y="37" width="74" height="17"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="17" id="xfD-mK-47N"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                <color key="textColor" red="0.41568627450980389" green="0.41568627450980389" blue="0.41568627450980389" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="开课时间:2月28日 19:30" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="T3t-fA-cM4">
+                                <rect key="frame" x="148" y="57" width="132" height="16"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="16" id="l9V-6s-gu9"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                                <color key="textColor" red="0.41568627450000001" green="0.41568627450000001" blue="0.41568627450000001" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="¥299" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rZn-jF-zsG">
+                                <rect key="frame" x="148" y="81" width="37" height="20"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="20" id="keb-BD-W5Z"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
+                                <color key="textColor" red="0.98039215686274506" green="0.39215686274509803" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="C1l-Ki-Xiv">
+                                <rect key="frame" x="196" y="82.5" width="46" height="17"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="12课时" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zJs-83-soC">
+                                        <rect key="frame" x="4" y="0.0" width="38" height="17"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                        <color key="textColor" red="1" green="0.57647058823529407" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="1" green="0.94509803921568625" blue="0.87058823529411766" alpha="1" colorSpace="calibratedRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="17" id="D9G-Pn-9Jv"/>
+                                    <constraint firstAttribute="trailing" secondItem="zJs-83-soC" secondAttribute="trailing" constant="4" id="TVQ-Zk-nLQ"/>
+                                    <constraint firstAttribute="bottom" secondItem="zJs-83-soC" secondAttribute="bottom" id="aZw-b8-QBS"/>
+                                    <constraint firstItem="zJs-83-soC" firstAttribute="leading" secondItem="C1l-Ki-Xiv" secondAttribute="leading" constant="4" id="cC5-tq-agc"/>
+                                    <constraint firstItem="zJs-83-soC" firstAttribute="top" secondItem="C1l-Ki-Xiv" secondAttribute="top" id="kfg-dp-Eks"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="4"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="6人已购买" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iFI-xj-FYd">
+                                <rect key="frame" x="337" y="83.5" width="57" height="15"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                <color key="textColor" red="1" green="0.50196078431372548" blue="0.17254901960784313" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        <constraints>
+                            <constraint firstItem="mto-Fi-MuN" firstAttribute="leading" secondItem="d3t-M0-UQn" secondAttribute="leading" constant="10" id="6BN-tn-yyu"/>
+                            <constraint firstItem="H4s-4H-yh0" firstAttribute="leading" secondItem="8ja-4v-aTz" secondAttribute="leading" id="6xx-BQ-Org"/>
+                            <constraint firstItem="rZn-jF-zsG" firstAttribute="leading" secondItem="T3t-fA-cM4" secondAttribute="leading" id="CBs-2D-gkT"/>
+                            <constraint firstItem="iFI-xj-FYd" firstAttribute="centerY" secondItem="C1l-Ki-Xiv" secondAttribute="centerY" id="Rxy-ge-uag"/>
+                            <constraint firstItem="T3t-fA-cM4" firstAttribute="top" secondItem="H4s-4H-yh0" secondAttribute="bottom" constant="3" id="Smu-6O-eHo"/>
+                            <constraint firstItem="mto-Fi-MuN" firstAttribute="centerY" secondItem="d3t-M0-UQn" secondAttribute="centerY" id="SvE-NP-GIq"/>
+                            <constraint firstItem="C1l-Ki-Xiv" firstAttribute="centerY" secondItem="rZn-jF-zsG" secondAttribute="centerY" id="VXq-RT-vnQ"/>
+                            <constraint firstItem="8ja-4v-aTz" firstAttribute="top" secondItem="mto-Fi-MuN" secondAttribute="top" constant="4" id="X9a-fQ-tvn"/>
+                            <constraint firstItem="C1l-Ki-Xiv" firstAttribute="leading" secondItem="rZn-jF-zsG" secondAttribute="trailing" constant="11" id="b0g-UQ-wBc"/>
+                            <constraint firstItem="rZn-jF-zsG" firstAttribute="top" secondItem="T3t-fA-cM4" secondAttribute="bottom" constant="8" id="fzb-a0-8ma"/>
+                            <constraint firstItem="H4s-4H-yh0" firstAttribute="top" secondItem="8ja-4v-aTz" secondAttribute="bottom" constant="3" id="oJi-wg-cDg"/>
+                            <constraint firstItem="T3t-fA-cM4" firstAttribute="leading" secondItem="H4s-4H-yh0" secondAttribute="leading" id="pMN-ud-rPR"/>
+                            <constraint firstItem="8ja-4v-aTz" firstAttribute="leading" secondItem="mto-Fi-MuN" secondAttribute="trailing" constant="8" id="vFc-T8-uGy"/>
+                            <constraint firstAttribute="trailing" secondItem="iFI-xj-FYd" secondAttribute="trailing" constant="10" id="w1d-7L-E1j"/>
+                            <constraint firstAttribute="trailing" secondItem="8ja-4v-aTz" secondAttribute="trailing" constant="10" id="xjo-bW-BbU"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="8"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+                <constraints>
+                    <constraint firstAttribute="bottom" secondItem="d3t-M0-UQn" secondAttribute="bottom" constant="10" id="0ur-gd-eps"/>
+                    <constraint firstItem="d3t-M0-UQn" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="K1R-Sr-aqx"/>
+                    <constraint firstItem="d3t-M0-UQn" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="jua-cG-zWX"/>
+                    <constraint firstAttribute="trailing" secondItem="d3t-M0-UQn" secondAttribute="trailing" constant="14" id="s12-P4-bYf"/>
+                </constraints>
+            </tableViewCellContentView>
+            <viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <connections>
+                <outlet property="courseBegin" destination="T3t-fA-cM4" id="sgg-uA-dqO"/>
+                <outlet property="courseCountLabel" destination="zJs-83-soC" id="lSq-60-MaR"/>
+                <outlet property="courseName" destination="8ja-4v-aTz" id="ZJM-Q0-LiV"/>
+                <outlet property="coverImage" destination="mto-Fi-MuN" id="bnA-Le-57d"/>
+                <outlet property="descLabel" destination="iFI-xj-FYd" id="17h-Ba-iO1"/>
+                <outlet property="priceLabel" destination="rZn-jF-zsG" id="H15-rk-wqH"/>
+                <outlet property="teacherName" destination="H4s-4H-yh0" id="sMX-He-jR0"/>
+            </connections>
+            <point key="canvasLocation" x="213.04347826086959" y="155.35714285714286"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="video_placeholder" width="103" height="72"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 31 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.h

@@ -0,0 +1,31 @@
+//
+//  HomeNavView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef NS_ENUM(NSInteger, NAVACTION) {
+    NAVACTION_SUBJECT,  // 声部
+    NAVACTION_MESSAGE,  // 消息
+};
+
+typedef void(^HomeNavCallback)(NAVACTION action);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HomeNavView : UIView
+
+@property (weak, nonatomic) IBOutlet UILabel *subjectName;
+
+@property (weak, nonatomic) IBOutlet UIView *dotView;
+
++ (instancetype)shareInstance;
+
+- (void)homeNavAction:(HomeNavCallback)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 47 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.m

@@ -0,0 +1,47 @@
+//
+//  HomeNavView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import "HomeNavView.h"
+
+@interface HomeNavView ()
+
+@property (nonatomic, copy) HomeNavCallback calback;
+@end
+
+@implementation HomeNavView
+
++ (instancetype)shareInstance {
+    HomeNavView *view = [[[NSBundle mainBundle] loadNibNamed:@"HomeNavView" owner:nil options:nil] firstObject];
+    return view;
+}
+- (void)homeNavAction:(HomeNavCallback)callback {
+    if (callback) {
+        self.calback = callback;
+    }
+}
+
+- (IBAction)chooseSubject:(id)sender {
+    if (self.calback) {
+        self.calback(NAVACTION_SUBJECT);
+    }
+}
+
+- (IBAction)toMessaegCenter:(id)sender {
+    if (self.calback) {
+        self.calback(NAVACTION_MESSAGE);
+    }
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 93 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeNavView.xib

@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <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" customClass="HomeNavView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="91"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="请选择乐器" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6OQ-et-S7G">
+                    <rect key="frame" x="20" y="55" width="92" height="22"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="18"/>
+                    <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="nav_down" translatesAutoresizingMaskIntoConstraints="NO" id="jHi-90-Am6">
+                    <rect key="frame" x="120" y="57" width="18" height="18"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="18" id="TfK-vc-8WW"/>
+                        <constraint firstAttribute="height" constant="18" id="oJU-b1-uqe"/>
+                    </constraints>
+                </imageView>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="BQD-3C-xLl">
+                    <rect key="frame" x="20" y="46" width="118" height="40"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="40" id="5gc-tx-f8a"/>
+                    </constraints>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <connections>
+                        <action selector="chooseSubject:" destination="iN0-l3-epB" eventType="touchUpInside" id="GYF-9A-Bkw"/>
+                    </connections>
+                </button>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xYy-Ue-YZl">
+                    <rect key="frame" x="359" y="46" width="40" height="40"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="40" id="PLA-jk-MlL"/>
+                        <constraint firstAttribute="height" constant="40" id="xdo-m9-D5d"/>
+                    </constraints>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" image="home_message"/>
+                    <connections>
+                        <action selector="toMessaegCenter:" destination="iN0-l3-epB" eventType="touchUpInside" id="mav-ya-fe5"/>
+                    </connections>
+                </button>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="omR-9c-WQ1">
+                    <rect key="frame" x="385" y="54" width="8" height="8"/>
+                    <color key="backgroundColor" red="0.97254901960784312" green="0.31372549019607843" blue="0.2627450980392157" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="8" id="q21-oT-Hxm"/>
+                        <constraint firstAttribute="width" constant="8" id="wKI-LW-qki"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="4"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="omR-9c-WQ1" firstAttribute="top" secondItem="xYy-Ue-YZl" secondAttribute="top" constant="8" id="3LP-Cf-UOB"/>
+                <constraint firstItem="jHi-90-Am6" firstAttribute="centerY" secondItem="6OQ-et-S7G" secondAttribute="centerY" id="5Rs-Nj-XCi"/>
+                <constraint firstItem="jHi-90-Am6" firstAttribute="leading" secondItem="6OQ-et-S7G" secondAttribute="trailing" constant="8" id="7F7-M8-l6Y"/>
+                <constraint firstItem="6OQ-et-S7G" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" id="8mf-9R-Dxu"/>
+                <constraint firstAttribute="trailing" secondItem="omR-9c-WQ1" secondAttribute="trailing" constant="21" id="MxY-he-eWw"/>
+                <constraint firstAttribute="trailing" secondItem="xYy-Ue-YZl" secondAttribute="trailing" constant="15" id="NQ0-wf-rrB"/>
+                <constraint firstItem="jHi-90-Am6" firstAttribute="centerY" secondItem="BQD-3C-xLl" secondAttribute="centerY" id="Nv1-Xw-lJU"/>
+                <constraint firstAttribute="bottom" secondItem="BQD-3C-xLl" secondAttribute="bottom" constant="5" id="PN5-C1-St4"/>
+                <constraint firstItem="xYy-Ue-YZl" firstAttribute="centerY" secondItem="BQD-3C-xLl" secondAttribute="centerY" id="PdM-w4-plu"/>
+                <constraint firstItem="jHi-90-Am6" firstAttribute="trailing" secondItem="BQD-3C-xLl" secondAttribute="trailing" id="mU8-kT-Ys3"/>
+                <constraint firstItem="6OQ-et-S7G" firstAttribute="leading" secondItem="BQD-3C-xLl" secondAttribute="leading" id="y5S-9B-lFW"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="dotView" destination="omR-9c-WQ1" id="2qw-zC-ZLk"/>
+                <outlet property="subjectName" destination="6OQ-et-S7G" id="hLa-xl-AQa"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="-110.15625"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="home_message" width="23" height="23"/>
+        <image name="nav_down" width="18" height="18"/>
+    </resources>
+</document>

+ 19 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeVideoCourseCell.h

@@ -0,0 +1,19 @@
+//
+//  HomeVideoCourseCell.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import <UIKit/UIKit.h>
+#import "HomeVideoGroupModel.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HomeVideoCourseCell : UITableViewCell
+
+- (void)configWithSource:(HomeVideoGroupModel *)source;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 49 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeVideoCourseCell.m

@@ -0,0 +1,49 @@
+//
+//  HomeVideoCourseCell.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import "HomeVideoCourseCell.h"
+
+@interface HomeVideoCourseCell ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *coverImage;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseName;
+
+@property (weak, nonatomic) IBOutlet UILabel *teacherName;
+
+@property (weak, nonatomic) IBOutlet UILabel *coursePrice;
+
+@property (weak, nonatomic) IBOutlet UILabel *courseCount;
+
+@property (weak, nonatomic) IBOutlet UILabel *descLabel;
+
+@end
+
+@implementation HomeVideoCourseCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    self.selectionStyle = UITableViewCellSelectionStyleNone;
+}
+
+- (void)configWithSource:(HomeVideoGroupModel *)source {
+    [self.coverImage sd_setImageWithURL:[NSURL URLWithString:source.lessonCoverUrl] placeholderImage:[UIImage imageNamed:@"video_placeholder"]];
+    self.courseName.text = [NSString returnNoNullStringWithString:source.videoGroupName];
+    self.teacherName.text = [NSString stringWithFormat:@"老师:%@",[NSString returnNoNullStringWithString:source.teacherName]];
+    self.coursePrice.text = [NSString stringWithFormat:@"¥%.2f",source.lessonPrice];
+    self.courseCount.text = [NSString stringWithFormat:@"%.0f课时",source.lessonCount];
+    
+}
+
+- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
+    [super setSelected:selected animated:animated];
+
+    // Configure the view for the selected state
+}
+
+@end

+ 144 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HomeVideoCourseCell.xib

@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <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"/>
+        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="151" id="KGk-i7-Jjw" customClass="HomeVideoCourseCell">
+            <rect key="frame" x="0.0" y="0.0" width="391" height="151"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
+                <rect key="frame" x="0.0" y="0.0" width="391" height="151"/>
+                <autoresizingMask key="autoresizingMask"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Hwe-zX-Dr8">
+                        <rect key="frame" x="14" y="0.0" width="363" height="141"/>
+                        <subviews>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="video_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="knq-4v-R8V">
+                                <rect key="frame" x="10" y="22.5" width="130" height="96"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" constant="130" id="HYT-fy-cHB"/>
+                                    <constraint firstAttribute="height" constant="96" id="NoQ-gx-obg"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="8"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </imageView>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="单簧管基础入门单曲练习" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p1L-Tc-1eC">
+                                <rect key="frame" x="148" y="26.5" width="205" height="20"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="20" id="cVG-cS-SxM"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
+                                <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="老师:李云磊" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KYe-PG-V9i">
+                                <rect key="frame" x="148" y="49.5" width="74" height="17"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="17" id="EyE-QQ-cmD"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                <color key="textColor" red="0.41568627450000001" green="0.41568627450000001" blue="0.41568627450000001" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="¥299" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JR5-GO-mSN">
+                                <rect key="frame" x="148" y="93.5" width="37" height="20"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="20" id="wdy-nF-fYp"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
+                                <color key="textColor" red="0.98039215690000003" green="0.3921568627" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vlX-ud-WSY">
+                                <rect key="frame" x="196" y="95" width="46" height="17"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="12课时" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ta9-PS-Fd5">
+                                        <rect key="frame" x="4" y="0.0" width="38" height="17"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                        <color key="textColor" red="1" green="0.57647058819999997" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="1" green="0.94509803920000002" blue="0.87058823529999996" alpha="1" colorSpace="calibratedRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="trailing" secondItem="ta9-PS-Fd5" secondAttribute="trailing" constant="4" id="Mpq-Gv-HzR"/>
+                                    <constraint firstAttribute="bottom" secondItem="ta9-PS-Fd5" secondAttribute="bottom" id="aqw-Lz-YJU"/>
+                                    <constraint firstItem="ta9-PS-Fd5" firstAttribute="leading" secondItem="vlX-ud-WSY" secondAttribute="leading" constant="4" id="gCa-8g-j6m"/>
+                                    <constraint firstItem="ta9-PS-Fd5" firstAttribute="top" secondItem="vlX-ud-WSY" secondAttribute="top" id="ogv-bW-YJd"/>
+                                    <constraint firstAttribute="height" constant="17" id="qyJ-ex-wqR"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="4"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="6人已购买" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wLP-Ow-uiD">
+                                <rect key="frame" x="296" y="96" width="57" height="15"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                <color key="textColor" red="1" green="0.50196078430000002" blue="0.17254901959999999" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                        </subviews>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        <constraints>
+                            <constraint firstItem="knq-4v-R8V" firstAttribute="leading" secondItem="Hwe-zX-Dr8" secondAttribute="leading" constant="10" id="7Cd-Mj-Tb2"/>
+                            <constraint firstItem="wLP-Ow-uiD" firstAttribute="centerY" secondItem="vlX-ud-WSY" secondAttribute="centerY" id="9b0-Ps-dhd"/>
+                            <constraint firstItem="p1L-Tc-1eC" firstAttribute="leading" secondItem="knq-4v-R8V" secondAttribute="trailing" constant="8" id="Am2-UT-dVy"/>
+                            <constraint firstAttribute="trailing" secondItem="wLP-Ow-uiD" secondAttribute="trailing" constant="10" id="BJd-b3-GDy"/>
+                            <constraint firstItem="vlX-ud-WSY" firstAttribute="leading" secondItem="JR5-GO-mSN" secondAttribute="trailing" constant="11" id="Baq-P2-MLw"/>
+                            <constraint firstItem="KYe-PG-V9i" firstAttribute="top" secondItem="p1L-Tc-1eC" secondAttribute="bottom" constant="3" id="Hh3-6E-Cmp"/>
+                            <constraint firstItem="knq-4v-R8V" firstAttribute="centerY" secondItem="Hwe-zX-Dr8" secondAttribute="centerY" id="LHd-wh-QXf"/>
+                            <constraint firstItem="JR5-GO-mSN" firstAttribute="bottom" secondItem="knq-4v-R8V" secondAttribute="bottom" constant="-5" id="Of4-Nt-ICM"/>
+                            <constraint firstItem="p1L-Tc-1eC" firstAttribute="top" secondItem="knq-4v-R8V" secondAttribute="top" constant="4" id="gMW-CX-juj"/>
+                            <constraint firstAttribute="trailing" secondItem="p1L-Tc-1eC" secondAttribute="trailing" constant="10" id="i4s-hj-WAH"/>
+                            <constraint firstItem="KYe-PG-V9i" firstAttribute="leading" secondItem="p1L-Tc-1eC" secondAttribute="leading" id="idA-YD-3dU"/>
+                            <constraint firstItem="vlX-ud-WSY" firstAttribute="centerY" secondItem="JR5-GO-mSN" secondAttribute="centerY" id="tDh-91-MoS"/>
+                            <constraint firstItem="JR5-GO-mSN" firstAttribute="leading" secondItem="KYe-PG-V9i" secondAttribute="leading" id="ytX-Pm-yGb"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="8"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+                <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                <constraints>
+                    <constraint firstAttribute="bottom" secondItem="Hwe-zX-Dr8" secondAttribute="bottom" constant="10" id="H0I-Xn-jBA"/>
+                    <constraint firstAttribute="trailing" secondItem="Hwe-zX-Dr8" secondAttribute="trailing" constant="14" id="bkT-2F-fUF"/>
+                    <constraint firstItem="Hwe-zX-Dr8" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leading" constant="14" id="dEy-O7-rdr"/>
+                    <constraint firstItem="Hwe-zX-Dr8" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="kjt-o6-vuI"/>
+                </constraints>
+            </tableViewCellContentView>
+            <viewLayoutGuide key="safeArea" id="aW0-zy-SZf"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <connections>
+                <outlet property="courseCount" destination="ta9-PS-Fd5" id="1Mh-LM-Dc3"/>
+                <outlet property="courseName" destination="p1L-Tc-1eC" id="Wc7-mx-kf0"/>
+                <outlet property="coursePrice" destination="JR5-GO-mSN" id="Qti-X4-3xG"/>
+                <outlet property="coverImage" destination="knq-4v-R8V" id="dpy-Wz-IEu"/>
+                <outlet property="descLabel" destination="wLP-Ow-uiD" id="lkg-g1-9me"/>
+                <outlet property="teacherName" destination="KYe-PG-V9i" id="ylg-Uv-HyL"/>
+            </connections>
+            <point key="canvasLocation" x="150" y="131.58482142857142"/>
+        </tableViewCell>
+    </objects>
+    <resources>
+        <image name="video_placeholder" width="103" height="72"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HotInformationHeadView.h

@@ -0,0 +1,22 @@
+//
+//  HotInformationHeadView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^HotInformationCallback)(void);
+NS_ASSUME_NONNULL_BEGIN
+
+@interface HotInformationHeadView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)moreInformationCallback:(HotInformationCallback)callback;
+
++ (CGFloat)getViewHeight;
+@end
+
+NS_ASSUME_NONNULL_END

+ 47 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HotInformationHeadView.m

@@ -0,0 +1,47 @@
+//
+//  HotInformationHeadView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/21.
+//
+
+#import "HotInformationHeadView.h"
+
+@interface HotInformationHeadView ()
+
+@property (nonatomic, copy) HotInformationCallback callback;
+
+@end
+
+@implementation HotInformationHeadView
+
++ (instancetype)shareInstance {
+    HotInformationHeadView *view = [[[NSBundle mainBundle] loadNibNamed:@"HotInformationHeadView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)moreInformationCallback:(HotInformationCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)moreInformation:(id)sender {
+    if (self.callback) {
+        self.callback();
+    }
+}
+
++ (CGFloat)getViewHeight {
+    return 50.0f;
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 69 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HotInformationHeadView.xib

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <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" customClass="HotInformationHeadView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="50"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="精彩资讯" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="76G-7c-nEc">
+                    <rect key="frame" x="16" y="10" width="65.5" height="22"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="22" id="325-gq-Ep0"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                    <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <button opaque="NO" tag="1008" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="GKx-rJ-vq5">
+                    <rect key="frame" x="355" y="6" width="39" height="30"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="30" id="F8f-2f-Iih"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="14"/>
+                    <state key="normal">
+                        <color key="titleColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="0.84705882349999995" colorSpace="calibratedRGB"/>
+                    </state>
+                    <connections>
+                        <action selector="moreInformation:" destination="iN0-l3-epB" eventType="touchUpInside" id="6kY-d9-9iy"/>
+                    </connections>
+                </button>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="更多" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uoh-6D-nay">
+                    <rect key="frame" x="355" y="14" width="25" height="14.5"/>
+                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                    <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_more" translatesAutoresizingMaskIntoConstraints="NO" id="xaQ-Rd-bel">
+                    <rect key="frame" x="384" y="16" width="10" height="10"/>
+                </imageView>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="xaQ-Rd-bel" firstAttribute="centerY" secondItem="76G-7c-nEc" secondAttribute="centerY" id="3Sc-FQ-jQZ"/>
+                <constraint firstItem="GKx-rJ-vq5" firstAttribute="centerY" secondItem="76G-7c-nEc" secondAttribute="centerY" id="O2s-vi-aJA"/>
+                <constraint firstItem="xaQ-Rd-bel" firstAttribute="leading" secondItem="uoh-6D-nay" secondAttribute="trailing" constant="4" id="kku-ko-uWg"/>
+                <constraint firstItem="76G-7c-nEc" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="10" id="mWY-Mu-pgz"/>
+                <constraint firstItem="uoh-6D-nay" firstAttribute="centerY" secondItem="76G-7c-nEc" secondAttribute="centerY" id="oXh-yg-Fba"/>
+                <constraint firstItem="xaQ-Rd-bel" firstAttribute="trailing" secondItem="GKx-rJ-vq5" secondAttribute="trailing" id="va8-tl-1zF"/>
+                <constraint firstAttribute="trailing" secondItem="xaQ-Rd-bel" secondAttribute="trailing" constant="20" id="wHB-pd-svc"/>
+                <constraint firstItem="76G-7c-nEc" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="16" id="yZf-ND-wQj"/>
+                <constraint firstItem="uoh-6D-nay" firstAttribute="leading" secondItem="GKx-rJ-vq5" secondAttribute="leading" id="zYz-3c-1r5"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <point key="canvasLocation" x="131.8840579710145" y="-27.790178571428569"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="home_more" width="10" height="10"/>
+    </resources>
+</document>

+ 25 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/KSHomeButton.h

@@ -0,0 +1,25 @@
+//
+//  KSHomeButton.h
+//  StudentDaya
+//
+//  Created by Kyle on 2020/9/25.
+//  Copyright © 2020 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSHomeButton : UIView
+
+@property (weak, nonatomic) IBOutlet UIImageView *buttonImage;
+@property (weak, nonatomic) IBOutlet UILabel *buttonTitle;
+@property (weak, nonatomic) IBOutlet UIButton *actionButton;
+
+
++ (instancetype)shareInstance;
+
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 26 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/KSHomeButton.m

@@ -0,0 +1,26 @@
+//
+//  KSHomeButton.m
+//  StudentDaya
+//
+//  Created by Kyle on 2020/9/25.
+//  Copyright © 2020 DayaMusic. All rights reserved.
+//
+
+#import "KSHomeButton.h"
+
+@implementation KSHomeButton
+
++ (instancetype)shareInstance {
+    KSHomeButton *view = [[[NSBundle mainBundle] loadNibNamed:@"KSHomeButton" owner:nil options:nil] firstObject];
+    return view;
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 63 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/KSHomeButton.xib

@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <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" customClass="KSHomeButton">
+            <rect key="frame" x="0.0" y="0.0" width="80" height="90"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="专项训练" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1ld-By-usD">
+                    <rect key="frame" x="11" y="73" width="58" height="17"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="17" id="HmM-NJ-9X6"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                    <color key="textColor" red="0.26666666666666666" green="0.26666666666666666" blue="0.26666666666666666" alpha="1" colorSpace="calibratedRGB"/>
+                    <nil key="highlightedColor"/>
+                </label>
+                <button opaque="NO" tag="1003" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Z8s-SG-JhM">
+                    <rect key="frame" x="8.5" y="0.0" width="63.5" height="90"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="63.5" id="JSo-aS-lFI"/>
+                    </constraints>
+                </button>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_train" translatesAutoresizingMaskIntoConstraints="NO" id="fGp-yj-UZk">
+                    <rect key="frame" x="7" y="0.0" width="66" height="67"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="66" id="a4B-wg-004"/>
+                        <constraint firstAttribute="height" constant="67" id="xmk-HE-99v"/>
+                    </constraints>
+                </imageView>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="Z8s-SG-JhM" secondAttribute="bottom" id="3uz-SX-3Fy"/>
+                <constraint firstItem="fGp-yj-UZk" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="6hu-0z-K7k"/>
+                <constraint firstItem="Z8s-SG-JhM" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="QJA-gE-y6C"/>
+                <constraint firstItem="1ld-By-usD" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Zfj-98-cxn"/>
+                <constraint firstItem="Z8s-SG-JhM" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="gyu-3P-I55"/>
+                <constraint firstItem="fGp-yj-UZk" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="t2k-gD-lM1"/>
+                <constraint firstAttribute="bottom" secondItem="1ld-By-usD" secondAttribute="bottom" id="ygh-pf-cwF"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="actionButton" destination="Z8s-SG-JhM" id="nuo-Py-54k"/>
+                <outlet property="buttonImage" destination="fGp-yj-UZk" id="HYi-AM-zku"/>
+                <outlet property="buttonTitle" destination="1ld-By-usD" id="XXN-y8-sA2"/>
+            </connections>
+            <point key="canvasLocation" x="46.376811594202906" y="4.3526785714285712"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="home_train" width="52" height="42"/>
+    </resources>
+</document>

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/TeacherShowCell.h

@@ -0,0 +1,22 @@
+//
+//  TeacherShowCell.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import <UIKit/UIKit.h>
+#import "TeacherStyleModel.h"
+
+
+typedef void(^TeacherStylePlay)(NSString * _Nullable videoUrl);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface TeacherShowCell : UICollectionViewCell
+
+- (void)configWithStyleModel:(TeacherStyleModel *)sourceModel callback:(TeacherStylePlay)callback;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 75 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/TeacherShowCell.m

@@ -0,0 +1,75 @@
+//
+//  TeacherShowCell.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/4/22.
+//
+
+#import "TeacherShowCell.h"
+#import "KSVideoHelper.h"
+#import "UIButton+EnlargeEdge.h"
+
+@interface TeacherShowCell ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *videoCover;
+
+@property (weak, nonatomic) IBOutlet UILabel *descLabel;
+
+@property (weak, nonatomic) IBOutlet UIImageView *teacherAvatar;
+
+@property (weak, nonatomic) IBOutlet UILabel *teacherNameLabel;
+
+@property (weak, nonatomic) IBOutlet UILabel *watchCount;
+
+@property (weak, nonatomic) IBOutlet UILabel *durationLabel;
+
+@property (weak, nonatomic) IBOutlet UIButton *playButton;
+
+@property (nonatomic, copy) TeacherStylePlay callback;
+
+@property (nonatomic, strong) TeacherStyleModel *model;
+
+@end
+
+@implementation TeacherShowCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+    [self.playButton setEnlargeEdgeWithTop:10 right:5 bottom:10 left:10];
+}
+
+- (void)configWithStyleModel:(TeacherStyleModel *)sourceModel callback:(TeacherStylePlay)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+    self.model = sourceModel;
+    [KSVideoHelper getVideoPreviewImageUrl:sourceModel.videoUrl forImageView:self.videoCover placeholder:[UIImage imageNamed:@"video_placeholder"]];
+    self.descLabel.text = [NSString returnNoNullStringWithString:sourceModel.describe];
+    [self.teacherAvatar sd_setImageWithURL:[NSURL URLWithString:sourceModel.avatar] placeholderImage:[UIImage imageNamed:USERDEFAULT_LOGO]];
+    self.teacherNameLabel.text = [NSString returnNoNullStringWithString:sourceModel.username];
+    if (![NSString isEmptyString:sourceModel.browse] && ![sourceModel.browse isEqualToString:@"0"]) {
+        self.watchCount.text = [NSString stringWithFormat:@"%@已观看",sourceModel.browse];
+    }
+    else {
+        self.watchCount.text = @"";
+    }
+    NSInteger duration = [KSVideoHelper getVideoDuration:sourceModel.videoUrl];
+    NSString *durationString = @"00:00";
+    if (duration / 60 > 0) {
+        durationString = [NSString stringWithFormat:@"%2ld:%2ld", duration / 60, duration % 60];
+    }
+    else {
+        durationString = [NSString stringWithFormat:@"00:%2ld", duration];
+    }
+    self.durationLabel.text = durationString;
+}
+
+
+
+- (IBAction)playButtonAction:(id)sender {
+    if (self.callback) {
+        self.callback(self.model.videoUrl);
+    }
+}
+@end

+ 161 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/TeacherShowCell.xib

@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_1" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <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"/>
+        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="TeacherShowCell">
+            <rect key="frame" x="0.0" y="0.0" width="188" height="164"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                <rect key="frame" x="0.0" y="0.0" width="188" height="164"/>
+                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                <subviews>
+                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="01s-Q8-6El">
+                        <rect key="frame" x="0.0" y="0.0" width="188" height="164"/>
+                        <subviews>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="video_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="EFx-Mc-ddD">
+                                <rect key="frame" x="0.0" y="0.0" width="188" height="100"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="100" id="BLz-7G-Kb2"/>
+                                </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="Bj0-bS-0xB">
+                                <rect key="frame" x="7" y="106" width="174" height="17"/>
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="17" id="17Q-qx-6GC"/>
+                                </constraints>
+                                <fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
+                                <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="user_default_avatal" translatesAutoresizingMaskIntoConstraints="NO" id="9jq-kZ-bi9">
+                                <rect key="frame" x="8" y="136" width="18" height="18"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" constant="18" id="hDV-Sn-4Qi"/>
+                                    <constraint firstAttribute="height" constant="18" id="hoC-I2-02c"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="9"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </imageView>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="张老师" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mwL-ai-act">
+                                <rect key="frame" x="32" y="137.5" width="37" height="15"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                                <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="120观看" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="h60-Mb-b5v">
+                                <rect key="frame" x="138.5" y="138.5" width="41.5" height="13.5"/>
+                                <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                                <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="calibratedRGB"/>
+                                <nil key="highlightedColor"/>
+                            </label>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hhc-kx-51J">
+                                <rect key="frame" x="121" y="80" width="59" height="20"/>
+                                <subviews>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="12:30" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ueX-N8-LMM">
+                                        <rect key="frame" x="19" y="0.0" width="30" height="20"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="11"/>
+                                        <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="introduce_play" translatesAutoresizingMaskIntoConstraints="NO" id="lOD-KN-Tuv">
+                                        <rect key="frame" x="6" y="5" width="10" height="10"/>
+                                        <constraints>
+                                            <constraint firstAttribute="width" constant="10" id="3bK-Bx-3cD"/>
+                                            <constraint firstAttribute="height" constant="10" id="TvQ-Bp-Psp"/>
+                                        </constraints>
+                                    </imageView>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KQK-OM-u6P">
+                                        <rect key="frame" x="0.0" y="0.0" width="59" height="20"/>
+                                        <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                        <connections>
+                                            <action selector="playButtonAction:" destination="gTV-IL-0wX" eventType="touchUpInside" id="FQ3-UU-y89"/>
+                                        </connections>
+                                    </button>
+                                </subviews>
+                                <color key="backgroundColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="0.5" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="trailing" secondItem="KQK-OM-u6P" secondAttribute="trailing" id="3dX-2t-Q9E"/>
+                                    <constraint firstItem="lOD-KN-Tuv" firstAttribute="leading" secondItem="hhc-kx-51J" secondAttribute="leading" constant="6" id="5M5-Pv-SHr"/>
+                                    <constraint firstItem="ueX-N8-LMM" firstAttribute="leading" secondItem="lOD-KN-Tuv" secondAttribute="trailing" constant="3" id="LXd-BJ-Gry"/>
+                                    <constraint firstItem="KQK-OM-u6P" firstAttribute="top" secondItem="hhc-kx-51J" secondAttribute="top" id="O8S-TS-wqU"/>
+                                    <constraint firstItem="ueX-N8-LMM" firstAttribute="top" secondItem="hhc-kx-51J" secondAttribute="top" id="fX2-aT-iga"/>
+                                    <constraint firstItem="KQK-OM-u6P" firstAttribute="leading" secondItem="hhc-kx-51J" secondAttribute="leading" id="gfT-2x-Rnc"/>
+                                    <constraint firstAttribute="bottom" secondItem="ueX-N8-LMM" secondAttribute="bottom" id="ie8-gz-R7K"/>
+                                    <constraint firstAttribute="height" constant="20" id="k85-BD-Ypt"/>
+                                    <constraint firstAttribute="trailing" secondItem="ueX-N8-LMM" secondAttribute="trailing" constant="10" id="oGe-Mz-jzV"/>
+                                    <constraint firstItem="lOD-KN-Tuv" firstAttribute="centerY" secondItem="hhc-kx-51J" secondAttribute="centerY" id="r1K-Lf-Xj5"/>
+                                    <constraint firstAttribute="bottom" secondItem="KQK-OM-u6P" secondAttribute="bottom" id="ssl-Hi-aUt"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="5"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                        <constraints>
+                            <constraint firstItem="mwL-ai-act" firstAttribute="centerY" secondItem="9jq-kZ-bi9" secondAttribute="centerY" id="1d2-j3-oWy"/>
+                            <constraint firstAttribute="trailing" secondItem="EFx-Mc-ddD" secondAttribute="trailing" id="2yD-0O-HEb"/>
+                            <constraint firstItem="EFx-Mc-ddD" firstAttribute="leading" secondItem="01s-Q8-6El" secondAttribute="leading" id="8VS-tt-JHf"/>
+                            <constraint firstItem="h60-Mb-b5v" firstAttribute="centerY" secondItem="mwL-ai-act" secondAttribute="centerY" id="E20-QH-cws"/>
+                            <constraint firstAttribute="trailing" secondItem="Bj0-bS-0xB" secondAttribute="trailing" constant="7" id="GH1-JD-q7M"/>
+                            <constraint firstAttribute="trailing" secondItem="h60-Mb-b5v" secondAttribute="trailing" constant="8" id="Jci-3j-Y9v"/>
+                            <constraint firstItem="EFx-Mc-ddD" firstAttribute="top" secondItem="01s-Q8-6El" secondAttribute="top" id="S2S-s2-vlQ"/>
+                            <constraint firstItem="Bj0-bS-0xB" firstAttribute="leading" secondItem="01s-Q8-6El" secondAttribute="leading" constant="7" id="SXK-uA-nnt"/>
+                            <constraint firstItem="hhc-kx-51J" firstAttribute="bottom" secondItem="EFx-Mc-ddD" secondAttribute="bottom" id="U1m-w4-ZLX"/>
+                            <constraint firstItem="mwL-ai-act" firstAttribute="leading" secondItem="9jq-kZ-bi9" secondAttribute="trailing" constant="6" id="YXk-GC-bpl"/>
+                            <constraint firstAttribute="trailing" secondItem="hhc-kx-51J" secondAttribute="trailing" constant="8" id="bOx-RM-i79"/>
+                            <constraint firstItem="9jq-kZ-bi9" firstAttribute="top" secondItem="Bj0-bS-0xB" secondAttribute="bottom" constant="13" id="m3U-Eh-PJY"/>
+                            <constraint firstItem="9jq-kZ-bi9" firstAttribute="leading" secondItem="01s-Q8-6El" secondAttribute="leading" constant="8" id="n8n-vj-zpF"/>
+                            <constraint firstItem="Bj0-bS-0xB" firstAttribute="top" secondItem="EFx-Mc-ddD" secondAttribute="bottom" constant="6" id="p1g-pR-hfF"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="8"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                </subviews>
+            </view>
+            <viewLayoutGuide key="safeArea" id="SEy-5g-ep8"/>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="01s-Q8-6El" secondAttribute="bottom" id="3sK-v7-xHm"/>
+                <constraint firstAttribute="trailing" secondItem="01s-Q8-6El" secondAttribute="trailing" id="Njd-lu-MRY"/>
+                <constraint firstItem="01s-Q8-6El" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="X8j-01-xHr"/>
+                <constraint firstItem="01s-Q8-6El" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="hCm-BD-nUI"/>
+            </constraints>
+            <size key="customSize" width="188" height="191"/>
+            <connections>
+                <outlet property="descLabel" destination="Bj0-bS-0xB" id="owR-vx-mXa"/>
+                <outlet property="durationLabel" destination="ueX-N8-LMM" id="Xuo-oM-2BR"/>
+                <outlet property="playButton" destination="KQK-OM-u6P" id="243-5b-pYg"/>
+                <outlet property="teacherAvatar" destination="9jq-kZ-bi9" id="LVa-r3-Ogc"/>
+                <outlet property="teacherNameLabel" destination="mwL-ai-act" id="rAZ-Im-GKP"/>
+                <outlet property="videoCover" destination="EFx-Mc-ddD" id="Efo-f4-wif"/>
+                <outlet property="watchCount" destination="h60-Mb-b5v" id="VU2-S6-rzx"/>
+            </connections>
+            <point key="canvasLocation" x="231.8840579710145" y="141.29464285714286"/>
+        </collectionViewCell>
+    </objects>
+    <resources>
+        <image name="introduce_play" width="10" height="10"/>
+        <image name="user_default_avatal" width="52" height="52"/>
+        <image name="video_placeholder" width="103" height="72"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 4 - 0
KulexiuForStudent/KulexiuForStudent/Module/Login/Controller/SubjectChooseViewController.h

@@ -7,11 +7,15 @@
 
 #import "KSBaseViewController.h"
 
+
+typedef void(^SubjectChooseCallback)(void);
 NS_ASSUME_NONNULL_BEGIN
 
 /// 声部选择
 @interface SubjectChooseViewController : KSBaseViewController
 
+- (void)chooseSubjectCallback:(SubjectChooseCallback)callback;
+
 @end
 
 NS_ASSUME_NONNULL_END

+ 11 - 0
KulexiuForStudent/KulexiuForStudent/Module/Login/Controller/SubjectChooseViewController.m

@@ -34,10 +34,18 @@
 
 @property (nonatomic, strong) InstrumentMessageModel *chooseInstrument;
 
+@property (nonatomic, copy) SubjectChooseCallback callback;
+
 @end
 
 @implementation SubjectChooseViewController
 
+- (void)chooseSubjectCallback:(SubjectChooseCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
 - (void)viewDidLoad {
     [super viewDidLoad];
     // Do any additional setup after loading the view.
@@ -249,6 +257,9 @@
         if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
             MJWeakSelf;
             [self KSShowMsg:@"设置成功" promptCompletion:^{
+                if (weakSelf.callback) {
+                    weakSelf.callback();
+                }
                 [weakSelf backAction];
             }];
         }

+ 1 - 0
KulexiuForStudent/KulexiuForStudent/Module/Mine/Model/StudentInfoModel.h

@@ -29,6 +29,7 @@
 @property (nonatomic, assign) double exerciseHours;
 @property (nonatomic, assign) double memberRankSettingId;
 @property (nonatomic, strong) NSString *updateTime;
+@property (nonatomic, strong) NSString *subjectName;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
 - (instancetype)initWithDictionary:(NSDictionary *)dict;

+ 8 - 3
KulexiuForStudent/KulexiuForStudent/Module/Mine/Model/StudentInfoModel.m

@@ -26,7 +26,7 @@ NSString *const kStudentInfoModelUsername = @"username";
 NSString *const kStudentInfoModelExerciseHours = @"exerciseHours";
 NSString *const kStudentInfoModelMemberRankSettingId = @"memberRankSettingId";
 NSString *const kStudentInfoModelUpdateTime = @"updateTime";
-
+NSString *const kStudentInfoModelSubjectName = @"subjectName";
 
 @interface StudentInfoModel ()
 
@@ -54,7 +54,7 @@ NSString *const kStudentInfoModelUpdateTime = @"updateTime";
 @synthesize exerciseHours = _exerciseHours;
 @synthesize memberRankSettingId = _memberRankSettingId;
 @synthesize updateTime = _updateTime;
-
+@synthesize subjectName = _subjectName;
 
 + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
 {
@@ -86,6 +86,8 @@ NSString *const kStudentInfoModelUpdateTime = @"updateTime";
             self.exerciseHours = [[self objectOrNilForKey:kStudentInfoModelExerciseHours fromDictionary:dict] doubleValue];
             self.memberRankSettingId = [[self objectOrNilForKey:kStudentInfoModelMemberRankSettingId fromDictionary:dict] doubleValue];
             self.updateTime = [self objectOrNilForKey:kStudentInfoModelUpdateTime fromDictionary:dict];
+            self.subjectName = [self objectOrNilForKey:kStudentInfoModelSubjectName fromDictionary:dict];
+        
 
     }
     
@@ -114,7 +116,7 @@ NSString *const kStudentInfoModelUpdateTime = @"updateTime";
     [mutableDict setValue:[NSNumber numberWithDouble:self.exerciseHours] forKey:kStudentInfoModelExerciseHours];
     [mutableDict setValue:[NSNumber numberWithDouble:self.memberRankSettingId] forKey:kStudentInfoModelMemberRankSettingId];
     [mutableDict setValue:self.updateTime forKey:kStudentInfoModelUpdateTime];
-
+    [mutableDict setValue:self.subjectName forKey:kStudentInfoModelSubjectName];
     return [NSDictionary dictionaryWithDictionary:mutableDict];
 }
 
@@ -159,6 +161,7 @@ NSString *const kStudentInfoModelUpdateTime = @"updateTime";
     self.exerciseHours = [aDecoder decodeDoubleForKey:kStudentInfoModelExerciseHours];
     self.memberRankSettingId = [aDecoder decodeDoubleForKey:kStudentInfoModelMemberRankSettingId];
     self.updateTime = [aDecoder decodeObjectForKey:kStudentInfoModelUpdateTime];
+    self.subjectName = [aDecoder decodeObjectForKey:kStudentInfoModelSubjectName];
     return self;
 }
 
@@ -183,6 +186,7 @@ NSString *const kStudentInfoModelUpdateTime = @"updateTime";
     [aCoder encodeDouble:_exerciseHours forKey:kStudentInfoModelExerciseHours];
     [aCoder encodeDouble:_memberRankSettingId forKey:kStudentInfoModelMemberRankSettingId];
     [aCoder encodeObject:_updateTime forKey:kStudentInfoModelUpdateTime];
+    [aCoder encodeObject:_subjectName forKey:kStudentInfoModelSubjectName];
 }
 
 - (id)copyWithZone:(NSZone *)zone
@@ -209,6 +213,7 @@ NSString *const kStudentInfoModelUpdateTime = @"updateTime";
         copy.exerciseHours = self.exerciseHours;
         copy.memberRankSettingId = self.memberRankSettingId;
         copy.updateTime = [self.updateTime copyWithZone:zone];
+        copy.subjectName = [self.subjectName copyWithZone:zone];
     }
     
     return copy;

+ 2 - 2
KulexiuForStudent/KulexiuForStudent/Module/Mine/View/MineBodyView.xib

@@ -12,7 +12,7 @@
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
         <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MineBodyView">
             <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
-            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+            <autoresizingMask key="autoresizingMask"/>
             <subviews>
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="yLa-RZ-nEh">
                     <rect key="frame" x="12" y="258" width="390" height="93"/>
@@ -637,7 +637,7 @@
                     </userDefinedRuntimeAttributes>
                 </view>
             </subviews>
-            <color key="backgroundColor" red="0.96470588235294119" green="0.97254901960784312" blue="0.97647058823529409" alpha="1" colorSpace="calibratedRGB"/>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
             <constraints>
                 <constraint firstItem="yLa-RZ-nEh" firstAttribute="top" secondItem="CM0-x0-QTu" secondAttribute="bottom" constant="12" id="210-NZ-EXg"/>
                 <constraint firstAttribute="trailing" secondItem="Qk7-Dc-xiJ" secondAttribute="trailing" constant="12" id="A0I-Vb-BmB"/>

BIN
KulexiuForStudent/build/Debug-iphonesimulator/KulexiuForStudent.app/Assets.car


BIN
KulexiuForStudent/build/Debug-iphonesimulator/KulexiuForStudent.app/Info.plist


BIN
KulexiuForStudent/build/Debug-iphonesimulator/KulexiuForStudent.app/KulexiuForStudent


Some files were not shown because too many files changed in this diff