Pārlūkot izejas kodu

修复偶像崩溃问题

Steven 2 gadi atpakaļ
vecāks
revīzija
892ed24b45
18 mainītis faili ar 1045 papildinājumiem un 195 dzēšanām
  1. 36 0
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. BIN
      KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/UserInterfaceState.xcuserstate
  3. 28 172
      KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  4. 22 0
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/mic_connting.imageset/Contents.json
  5. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/mic_connting.imageset/mic_connting@2x.png
  6. BIN
      KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/mic_connting.imageset/mic_connting@3x.png
  7. 101 23
      KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m
  8. 22 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/KSLiveAlertView.h
  9. 39 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/KSLiveAlertView.m
  10. 115 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/KSLiveAlertView.xib
  11. 28 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyView.h
  12. 95 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyView.m
  13. 90 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyView.xib
  14. 31 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyingView.h
  15. 90 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyingView.m
  16. 125 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyingView.xib
  17. 25 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveRoomAlertView.h
  18. 198 0
      KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveRoomAlertView.m

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

@@ -566,6 +566,13 @@
 		BC7663162827E49900C91A1D /* NotiferHeadView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC7663102827E49800C91A1D /* NotiferHeadView.xib */; };
 		BC7663172827E49900C91A1D /* NotiferMessageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BC7663122827E49800C91A1D /* NotiferMessageCell.m */; };
 		BC7663182827E49900C91A1D /* NotiferMessageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC7663132827E49900C91A1D /* NotiferMessageCell.xib */; };
+		BC802D8528B872AB0079E350 /* KSLiveAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC802D8428B872AB0079E350 /* KSLiveAlertView.m */; };
+		BC802D8728B872B40079E350 /* KSLiveAlertView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC802D8628B872B40079E350 /* KSLiveAlertView.xib */; };
+		BC802D8A28B876720079E350 /* LiveRoomAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC802D8928B876720079E350 /* LiveRoomAlertView.m */; };
+		BC802D8D28B896460079E350 /* LiveApplyView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC802D8C28B896460079E350 /* LiveApplyView.m */; };
+		BC802D8F28B8964C0079E350 /* LiveApplyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC802D8E28B8964C0079E350 /* LiveApplyView.xib */; };
+		BC802D9228B897610079E350 /* LiveApplyingView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC802D9128B897610079E350 /* LiveApplyingView.m */; };
+		BC802D9428B897670079E350 /* LiveApplyingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC802D9328B897670079E350 /* LiveApplyingView.xib */; };
 		BC8A4593283DC33400094BBB /* KSCloudViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A4548283DC33400094BBB /* KSCloudViewController.m */; };
 		BC8A4594283DC33400094BBB /* MidiPlayerEngine.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A454A283DC33400094BBB /* MidiPlayerEngine.m */; };
 		BC8A4595283DC33400094BBB /* GCDTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = BC8A454B283DC33400094BBB /* GCDTimer.m */; };
@@ -1838,6 +1845,17 @@
 		BC7663122827E49800C91A1D /* NotiferMessageCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotiferMessageCell.m; sourceTree = "<group>"; };
 		BC7663132827E49900C91A1D /* NotiferMessageCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NotiferMessageCell.xib; sourceTree = "<group>"; };
 		BC7663142827E49900C91A1D /* NotiferHeadView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotiferHeadView.h; sourceTree = "<group>"; };
+		BC802D8328B872AB0079E350 /* KSLiveAlertView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveAlertView.h; sourceTree = "<group>"; };
+		BC802D8428B872AB0079E350 /* KSLiveAlertView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveAlertView.m; sourceTree = "<group>"; };
+		BC802D8628B872B40079E350 /* KSLiveAlertView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KSLiveAlertView.xib; sourceTree = "<group>"; };
+		BC802D8828B876720079E350 /* LiveRoomAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiveRoomAlertView.h; sourceTree = "<group>"; };
+		BC802D8928B876720079E350 /* LiveRoomAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LiveRoomAlertView.m; sourceTree = "<group>"; };
+		BC802D8B28B896460079E350 /* LiveApplyView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveApplyView.h; sourceTree = "<group>"; };
+		BC802D8C28B896460079E350 /* LiveApplyView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiveApplyView.m; sourceTree = "<group>"; };
+		BC802D8E28B8964C0079E350 /* LiveApplyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LiveApplyView.xib; sourceTree = "<group>"; };
+		BC802D9028B897610079E350 /* LiveApplyingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiveApplyingView.h; sourceTree = "<group>"; };
+		BC802D9128B897610079E350 /* LiveApplyingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiveApplyingView.m; sourceTree = "<group>"; };
+		BC802D9328B897670079E350 /* LiveApplyingView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LiveApplyingView.xib; sourceTree = "<group>"; };
 		BC8A4547283DC33400094BBB /* KSCloudViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSCloudViewController.h; sourceTree = "<group>"; };
 		BC8A4548283DC33400094BBB /* KSCloudViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSCloudViewController.m; sourceTree = "<group>"; };
 		BC8A454A283DC33400094BBB /* MidiPlayerEngine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MidiPlayerEngine.m; sourceTree = "<group>"; };
@@ -4936,6 +4954,17 @@
 				BCB9091528530E9C00F5FF69 /* KSShopCardView.h */,
 				BCB9091628530E9C00F5FF69 /* KSShopCardView.m */,
 				BCB9091828530EA500F5FF69 /* KSShopCardView.xib */,
+				BC802D8328B872AB0079E350 /* KSLiveAlertView.h */,
+				BC802D8428B872AB0079E350 /* KSLiveAlertView.m */,
+				BC802D8628B872B40079E350 /* KSLiveAlertView.xib */,
+				BC802D8828B876720079E350 /* LiveRoomAlertView.h */,
+				BC802D8928B876720079E350 /* LiveRoomAlertView.m */,
+				BC802D8B28B896460079E350 /* LiveApplyView.h */,
+				BC802D8C28B896460079E350 /* LiveApplyView.m */,
+				BC802D8E28B8964C0079E350 /* LiveApplyView.xib */,
+				BC802D9028B897610079E350 /* LiveApplyingView.h */,
+				BC802D9128B897610079E350 /* LiveApplyingView.m */,
+				BC802D9328B897670079E350 /* LiveApplyingView.xib */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -5681,6 +5710,7 @@
 				BC71D24F288804CD0010F14B /* img_7.png in Resources */,
 				2723B5BA27F157B100E0B90B /* ChatAddressHeaderView.xib in Resources */,
 				BCC583C228A9EC6400BAB4CF /* cloud_animation_28.png in Resources */,
+				BC802D8728B872B40079E350 /* KSLiveAlertView.xib in Resources */,
 				BC8C2C7F28265D8E00FBA5D5 /* KSNewsAlert.xib in Resources */,
 				BC494A7D286958EC00CCD343 /* MusicRoomCourseInfoCell.xib in Resources */,
 				BC119235280ED97C00A716F7 /* CourseForLiveCell.xib in Resources */,
@@ -5841,6 +5871,7 @@
 				BC27A070280FF56C00F91E27 /* AccompanyStudentEvaCell.xib in Resources */,
 				2723B63927F157D500E0B90B /* GroupMemberListCell.xib in Resources */,
 				BC8A45A0283DC33400094BBB /* JudgePageView.xib in Resources */,
+				BC802D9428B897670079E350 /* LiveApplyingView.xib in Resources */,
 				BC71D244288804CD0010F14B /* img_10.png in Resources */,
 				BC0212F827FC4A080040569F /* SubjectImageCell.xib in Resources */,
 				BCC583B728A9EC6400BAB4CF /* cloud_animation_21.png in Resources */,
@@ -5864,6 +5895,7 @@
 				BCC583CA28A9EC6400BAB4CF /* cloud_animation_6.png in Resources */,
 				2723B5C527F157B100E0B90B /* ContractListCell.xib in Resources */,
 				BCBFDF48281159A40052AFE5 /* HomeHotAlbumView.xib in Resources */,
+				BC802D8F28B8964C0079E350 /* LiveApplyView.xib in Resources */,
 				BC71D24E288804CD0010F14B /* img_16.png in Resources */,
 				27F9033727E87C8B00C08A19 /* MineNavView.xib in Resources */,
 				BC8A45AB283DC33400094BBB /* TrackChooseView.xib in Resources */,
@@ -6083,6 +6115,7 @@
 				2779353427E324A60010E277 /* UIImageView+CornerRadius.m in Sources */,
 				2779357827E324A70010E277 /* NSString+phone.m in Sources */,
 				BC5367C7283F6D6B008428E8 /* HomeVideoCourseView.m in Sources */,
+				BC802D8528B872AB0079E350 /* KSLiveAlertView.m in Sources */,
 				2779357D27E324A80010E277 /* KSMessageInputView.m in Sources */,
 				277935BE27E324A90010E277 /* FSCalendarCalculator.m in Sources */,
 				BCB6347727F6D29600ACFDCF /* LiveRoomLikeLayer.m in Sources */,
@@ -6318,6 +6351,7 @@
 				BCB6353327F6D2A300ACFDCF /* CREmojiCollectionCell.m in Sources */,
 				BCB6356B27F6D2A300ACFDCF /* NodePlayMessage.m in Sources */,
 				2779352327E324A60010E277 /* UILabel+Extension.m in Sources */,
+				BC802D8D28B896460079E350 /* LiveApplyView.m in Sources */,
 				BCB635A327F6D3FE00ACFDCF /* KSNormalAlertView.m in Sources */,
 				2723B63027F157D500E0B90B /* GroupApplyChooseAllCell.m in Sources */,
 				2723B61F27F157D500E0B90B /* GroupNoticeModel.m in Sources */,
@@ -6475,6 +6509,7 @@
 				BCB6354D27F6D2A300ACFDCF /* EmptyView.m in Sources */,
 				2723B63327F157D500E0B90B /* ChatComplainBodyView.m in Sources */,
 				2779357927E324A70010E277 /* KSImageButton.m in Sources */,
+				BC802D9228B897610079E350 /* LiveApplyingView.m in Sources */,
 				2779351827E324A60010E277 /* NSObject+KSImpChangeTool.m in Sources */,
 				BC8C2C5D2823F57100FBA5D5 /* AddressDetailBodyView.m in Sources */,
 				2779359D27E324A80010E277 /* TZImageManager.m in Sources */,
@@ -6597,6 +6632,7 @@
 				BCB6353D27F6D2A300ACFDCF /* MessageModel.m in Sources */,
 				277935AA27E324A80010E277 /* MSSBrowseNetworkViewController.m in Sources */,
 				2723B63627F157D500E0B90B /* GroupMemberListCell.m in Sources */,
+				BC802D8A28B876720079E350 /* LiveRoomAlertView.m in Sources */,
 				2723B62227F157D500E0B90B /* LFPopupMenu.m in Sources */,
 				BCB6348027F6D29600ACFDCF /* LiveSeatApplyView.m in Sources */,
 				2779357F27E324A80010E277 /* KeyChainTools.m in Sources */,

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


+ 28 - 172
KulexiuForStudent/KulexiuForStudent.xcworkspace/xcuserdata/wangzhi.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -126,9 +126,9 @@
             filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "713"
-            endingLineNumber = "713"
-            landmarkName = "-updateVideoViewContainer"
+            startingLineNumber = "699"
+            endingLineNumber = "699"
+            landmarkName = "-countMemberCount"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
@@ -487,224 +487,80 @@
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "10FF452F-D91B-4DE5-B2CC-20BB109C598B"
+            uuid = "C8D8D819-C69D-4F84-9739-680EB2EE9F1C"
             shouldBeEnabled = "No"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "1346"
-            endingLineNumber = "1346"
-            landmarkName = "-didReceiveMessageNotification:"
-            landmarkType = "7">
-            <Locations>
-               <Location
-                  uuid = "10FF452F-D91B-4DE5-B2CC-20BB109C598B - 37facbaa101c85f1"
-                  shouldBeEnabled = "Yes"
-                  ignoreCount = "0"
-                  continueAfterRunningActions = "No"
-                  symbolName = "-[LiveVideoRoomViewController didReceiveMessageNotification:]"
-                  moduleName = "KulexiuForStudent"
-                  usesParentBreakpointCondition = "Yes"
-                  urlString = "file:///Users/wangzhi/DayaWorkspace/Klx_student/KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-                  startingColumnNumber = "9223372036854775807"
-                  endingColumnNumber = "9223372036854775807"
-                  startingLineNumber = "1425"
-                  endingLineNumber = "1425"
-                  offsetFromSymbolStart = "1184">
-               </Location>
-               <Location
-                  uuid = "10FF452F-D91B-4DE5-B2CC-20BB109C598B - 37facbaa101c85f1"
-                  shouldBeEnabled = "Yes"
-                  ignoreCount = "0"
-                  continueAfterRunningActions = "No"
-                  symbolName = "-[LiveVideoRoomViewController didReceiveMessageNotification:]"
-                  moduleName = "KulexiuForStudent"
-                  usesParentBreakpointCondition = "Yes"
-                  urlString = "file:///Users/wangzhi/DayaWorkspace/Klx_student/KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-                  startingColumnNumber = "9223372036854775807"
-                  endingColumnNumber = "9223372036854775807"
-                  startingLineNumber = "1425"
-                  endingLineNumber = "1425"
-                  offsetFromSymbolStart = "1188">
-               </Location>
-            </Locations>
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "A31AD81B-9011-41C6-B3A4-1805C49B8634"
-            shouldBeEnabled = "Yes"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Live/View/KSChatroomTextCell.m"
+            filePath = "KulexiuForStudent/Module/Mine/MineCourse/View/VideoCourseCell.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "204"
-            endingLineNumber = "204"
-            landmarkName = "-updateUI:"
+            startingLineNumber = "45"
+            endingLineNumber = "45"
+            landmarkName = "-configSourceModel:isInCheck:"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "E9BBCBFD-5DE2-4845-8C26-32B22A2803F9"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "1451"
-            endingLineNumber = "1451"
-            landmarkName = "-didReceiveMessageNotification:"
-            landmarkType = "7">
-            <Locations>
-               <Location
-                  uuid = "E9BBCBFD-5DE2-4845-8C26-32B22A2803F9 - 37facbaa101c8592"
-                  shouldBeEnabled = "Yes"
-                  ignoreCount = "0"
-                  continueAfterRunningActions = "No"
-                  symbolName = "-[LiveVideoRoomViewController didReceiveMessageNotification:]"
-                  moduleName = "KulexiuForStudent"
-                  usesParentBreakpointCondition = "Yes"
-                  urlString = "file:///Users/wangzhi/DayaWorkspace/Klx_student/KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-                  startingColumnNumber = "9223372036854775807"
-                  endingColumnNumber = "9223372036854775807"
-                  startingLineNumber = "1428"
-                  endingLineNumber = "1428"
-                  offsetFromSymbolStart = "1184">
-               </Location>
-               <Location
-                  uuid = "E9BBCBFD-5DE2-4845-8C26-32B22A2803F9 - 37facbaa101c8592"
-                  shouldBeEnabled = "Yes"
-                  ignoreCount = "0"
-                  continueAfterRunningActions = "No"
-                  symbolName = "-[LiveVideoRoomViewController didReceiveMessageNotification:]"
-                  moduleName = "KulexiuForStudent"
-                  usesParentBreakpointCondition = "Yes"
-                  urlString = "file:///Users/wangzhi/DayaWorkspace/Klx_student/KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-                  startingColumnNumber = "9223372036854775807"
-                  endingColumnNumber = "9223372036854775807"
-                  startingLineNumber = "1428"
-                  endingLineNumber = "1428"
-                  offsetFromSymbolStart = "1188">
-               </Location>
-            </Locations>
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "2EBF0C0D-BC6A-44E0-8B45-75E85CFC0D6E"
+            uuid = "84DE9E35-E62D-4C6B-AB45-37F619865FD1"
             shouldBeEnabled = "Yes"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Live/View/KSChatroomTextCell.m"
+            filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "171"
-            endingLineNumber = "171"
-            landmarkName = "-updateUI:"
+            startingLineNumber = "725"
+            endingLineNumber = "725"
+            landmarkName = "-updateVideoViewContainer"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "94A12614-714B-4C8E-91EE-4B41E2838320"
-            shouldBeEnabled = "No"
-            ignoreCount = "0"
-            continueAfterRunningActions = "No"
-            filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-            startingColumnNumber = "9223372036854775807"
-            endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "1443"
-            endingLineNumber = "1443"
-            landmarkName = "-didReceiveMessageNotification:"
-            landmarkType = "7">
-            <Locations>
-               <Location
-                  uuid = "94A12614-714B-4C8E-91EE-4B41E2838320 - 37facbaa101c8592"
-                  shouldBeEnabled = "Yes"
-                  ignoreCount = "0"
-                  continueAfterRunningActions = "No"
-                  symbolName = "-[LiveVideoRoomViewController didReceiveMessageNotification:]"
-                  moduleName = "KulexiuForStudent"
-                  usesParentBreakpointCondition = "Yes"
-                  urlString = "file:///Users/wangzhi/DayaWorkspace/Klx_student/KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-                  startingColumnNumber = "9223372036854775807"
-                  endingColumnNumber = "9223372036854775807"
-                  startingLineNumber = "1428"
-                  endingLineNumber = "1428"
-                  offsetFromSymbolStart = "1184">
-               </Location>
-               <Location
-                  uuid = "94A12614-714B-4C8E-91EE-4B41E2838320 - 37facbaa101c8592"
-                  shouldBeEnabled = "Yes"
-                  ignoreCount = "0"
-                  continueAfterRunningActions = "No"
-                  symbolName = "-[LiveVideoRoomViewController didReceiveMessageNotification:]"
-                  moduleName = "KulexiuForStudent"
-                  usesParentBreakpointCondition = "Yes"
-                  urlString = "file:///Users/wangzhi/DayaWorkspace/Klx_student/KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
-                  startingColumnNumber = "9223372036854775807"
-                  endingColumnNumber = "9223372036854775807"
-                  startingLineNumber = "1428"
-                  endingLineNumber = "1428"
-                  offsetFromSymbolStart = "1188">
-               </Location>
-            </Locations>
-         </BreakpointContent>
-      </BreakpointProxy>
-      <BreakpointProxy
-         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
-         <BreakpointContent
-            uuid = "C6CEC3A8-2EB0-4A76-9DA2-62B4E4B95D74"
-            shouldBeEnabled = "No"
+            uuid = "F6BB8FD9-538B-4DE7-8949-EF8139997B4D"
+            shouldBeEnabled = "Yes"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "1127"
-            endingLineNumber = "1127"
-            landmarkName = "-insertMessage:userInfo:"
+            startingLineNumber = "554"
+            endingLineNumber = "554"
+            landmarkName = "-connectHostWithStatus:"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "00091328-271D-4E22-9152-D56E67E3B43E"
-            shouldBeEnabled = "No"
+            uuid = "A8FC4392-7631-409C-A01A-EB2D3FF3209E"
+            shouldBeEnabled = "Yes"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "1537"
-            endingLineNumber = "1537"
-            landmarkName = "-appendAndDisplayMessage:"
+            startingLineNumber = "813"
+            endingLineNumber = "813"
+            landmarkName = "-subscribeRemoteResource:isTiny:"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>
       <BreakpointProxy
          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
          <BreakpointContent
-            uuid = "35B47182-A220-447C-A8E7-1AF8DAED450A"
-            shouldBeEnabled = "No"
+            uuid = "BC893046-7BBE-47D7-9C82-A0579FCE0066"
+            shouldBeEnabled = "Yes"
             ignoreCount = "0"
             continueAfterRunningActions = "No"
             filePath = "KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m"
             startingColumnNumber = "9223372036854775807"
             endingColumnNumber = "9223372036854775807"
-            startingLineNumber = "1053"
-            endingLineNumber = "1053"
-            landmarkName = "-joinLiveRoom"
+            startingLineNumber = "631"
+            endingLineNumber = "631"
+            landmarkName = "-connectHostWithStatus:"
             landmarkType = "7">
          </BreakpointContent>
       </BreakpointProxy>

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/mic_connting.imageset/Contents.json

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

BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/mic_connting.imageset/mic_connting@2x.png


BIN
KulexiuForStudent/KulexiuForStudent/Assets.xcassets/Live/mic_connting.imageset/mic_connting@3x.png


+ 101 - 23
KulexiuForStudent/KulexiuForStudent/Module/Live/Controller/LiveVideoRoomViewController.m

@@ -31,6 +31,10 @@
 #import "KSLiveEndView.h"
 #import "LiveAnimationView.h"
 
+
+#import "LiveApplyView.h"
+#import "LiveApplyingView.h"
+
 #define AUTOHIDE_TIME (10.0f)
 
 #define PACKAGE_LOST (0.30f)
@@ -141,6 +145,10 @@ typedef NS_ENUM(NSInteger, MICSTATUS) {
 
 @property (nonatomic, assign) BOOL isOtherLogin;  // 是否被顶掉
 
+@property (nonatomic, strong) LiveApplyView *applyView; // 未申请
+ 
+@property (nonatomic, strong) LiveApplyingView *applyingView; // 申请中
+
 @end
 
 //  用于记录点赞消息连续点击的次数
@@ -438,7 +446,8 @@ static int clickPraiseBtnTimes  = 0;
     if (self.hasShowSuspendView) {
         KSLiveStreamVideo *mainVideo = nil;
         if (self.videoView.streamId) {
-            for (KSLiveStreamVideo *streamVideo in self.streamVideos) {
+            NSMutableArray *steamArray = [self.streamVideos mutableCopy];
+            for (KSLiveStreamVideo *streamVideo in steamArray) {
                 if ([streamVideo.streamId isEqualToString:self.videoView.streamId]) {
                     mainVideo = streamVideo;
                     break;
@@ -579,7 +588,7 @@ static int clickPraiseBtnTimes  = 0;
                     [strongSelf subscribeRemoteResource:streamArray];
                 }
                 else {
-                    
+                    [strongSelf updateVideoViewContainer];
                 }
                 
                 strongSelf.micStatus = MICSTATUS_CONNECTING;
@@ -624,8 +633,9 @@ static int clickPraiseBtnTimes  = 0;
                 __strong typeof(weakSelf) strongSelf = weakSelf;
                 strongSelf.liveRoleType = RCRTCLiveRoleTypeAudience;
                 [strongSelf.engine.defaultAudioStream setMicrophoneDisable:YES];
+                
+                NSMutableArray *streamArray = [NSMutableArray array];
                 if (strongSelf.room.remoteUsers.count) {
-                    NSMutableArray *streamArray = [NSMutableArray array];
                     NSArray *remoteUserArray = [strongSelf.room.remoteUsers mutableCopy];
                     for (RCRTCRemoteUser *user in remoteUserArray) {
                         if (user.remoteStreams.count) {
@@ -633,10 +643,12 @@ static int clickPraiseBtnTimes  = 0;
                             [strongSelf subscribeRemoteResource:streamArray];
                         }
                     }
-                }
-                else {
                     
                 }
+                if (streamArray.count == 0) {
+                    [strongSelf updateVideoViewContainer];
+                }
+                
                 strongSelf.micStatus = MICSTATUS_NOMAL;
                 // 刷新麦位状态
                 [strongSelf renderSeatView];
@@ -709,11 +721,11 @@ static int clickPraiseBtnTimes  = 0;
 
 // 更新视图
 - (void)updateVideoViewContainer {
-    
-    if (self.streamVideos.count > 0) {
+    NSMutableArray *steamArray = [self.streamVideos mutableCopy];
+    if (steamArray.count > 0) {
         // 渲染主播的流 优先显示主播的共享流
         KSLiveStreamVideo *mainVideo = nil;
-        for (KSLiveStreamVideo *videoSource in self.streamVideos) {
+        for (KSLiveStreamVideo *videoSource in steamArray) {
             if ([videoSource.userId isEqualToString:self.createrId]) { // 主屏只渲染主讲人
                 if ([videoSource.streamTag isEqualToString:@"screenshare"]) { // 如果是共享流
                     if (![self.videoView.streamId isEqualToString:videoSource.streamId]) { // 主屏渲染不同 则重新渲染
@@ -875,7 +887,8 @@ static int clickPraiseBtnTimes  = 0;
 
 // 根据 streamId 确认唯一的音视频流
 - (KSLiveStreamVideo *)fetchStreamVideoWithStreamId:(NSString *)streamId {
-    for (KSLiveStreamVideo *sVideo in self.streamVideos) {
+    NSMutableArray *streamArray = [self.streamVideos mutableCopy];
+    for (KSLiveStreamVideo *sVideo in streamArray) {
         if ([streamId isEqualToString:sVideo.streamId]) {
             return sVideo;
         }
@@ -970,10 +983,14 @@ static int clickPraiseBtnTimes  = 0;
 
 - (void)resetConnectionStatus {
     if (self.micStatus == MICSTATUS_CONNECTING) {
-        [self connectHostWithStatus:NO];
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+            [self connectHostWithStatus:NO];
+        });
+    }
+    else {
+        [self removeSeatContainer];
     }
     self.micStatus = MICSTATUS_NOMAL;
-    [self removeSeatContainer];
 }
 
 - (void)resetMicWaitToNomal {
@@ -1347,7 +1364,8 @@ static int clickPraiseBtnTimes  = 0;
                     if (seatControlMessage.seatBan) { // 禁止连麦
                         __blockSelf.enableSeat = NO;
                         __blockSelf.micStatus = MICSTATUS_NOMAL;
-                        
+                        [__blockSelf hideApplyView];
+                        [__blockSelf hideApplyingView];
                     }
                     else { // 开启连麦
                         __blockSelf.enableSeat = YES;
@@ -1366,8 +1384,8 @@ static int clickPraiseBtnTimes  = 0;
                         NSString *titles = [NSString stringWithFormat:@"%@邀请您连麦",[NSString returnNoNullStringWithString:seatApplyMessage.teacherName]];
                         [__blockSelf showInviteAlertMessage:titles];
                     }
-                    else if (seatApplyMessage.type == SEATHANDLE_DISINVITE) { // 主讲人撤回
-                        [__blockSelf MBPShow:@"主讲人撤回了连麦请"];
+                    else if (seatApplyMessage.type == SEATHANDLE_DISINVITE) { // 主讲人撤回
+                        [__blockSelf MBPShow:@"主讲人撤回了连麦请"];
                         if (__blockSelf.alertView && __blockSelf.alertView.isShow) {
                             [__blockSelf.alertView dismissAlertView];
                         }
@@ -1375,6 +1393,7 @@ static int clickPraiseBtnTimes  = 0;
                     else if (seatApplyMessage.type == SEATHANDLE_KICKSEAT) { // 主讲人将麦上观众抱下麦
                         [__blockSelf kickSeatWithMessage:@"您已被抱下麦"];
                     }
+                    [__blockSelf hideApplyingView];
                     [__blockSelf insertMessage:rcMessage userInfo:notification.userInfo];
                 }
                 // 连麦回复消息(暂不处理)
@@ -1390,6 +1409,7 @@ static int clickPraiseBtnTimes  = 0;
                         [__blockSelf MBPShow:@"主讲人拒绝了您的连麦申请"];
                         __blockSelf.micStatus = MICSTATUS_NOMAL;
                     }
+                    [__blockSelf hideApplyingView];
                     [__blockSelf insertMessage:rcMessage userInfo:notification.userInfo];
                 }
                 else if ([rcMessage.content isMemberOfClass:[KSLiveChatroomDownSeat class]]) { // 成员下麦消息
@@ -1405,6 +1425,7 @@ static int clickPraiseBtnTimes  = 0;
                         // 显示直播间关闭状态
                         [__blockSelf closeAlertView];
                         [__blockSelf displayCloseView];
+                        [__blockSelf hideApplyingView];
                     });
                     return;
                 }
@@ -1413,9 +1434,11 @@ static int clickPraiseBtnTimes  = 0;
                 }
                 else if ([rcMessage.content isMemberOfClass:[KSRCPauseLiveMessage class]]) { // 主讲人暂停直播
                     [__blockSelf MBPShow:@"主讲人已暂停直播"];
-                    [__blockSelf resetNetTips];
                     [__blockSelf resetConnectionStatus];
+                    [__blockSelf resetNetTips];
                     [__blockSelf closeAlertView];
+                    [__blockSelf hideApplyingView];
+                    return;
                 }
                 else if ([rcMessage.content isMemberOfClass:[KSRCShopRushMessage class]]) { //
                     
@@ -1449,6 +1472,7 @@ static int clickPraiseBtnTimes  = 0;
                         // 处理连麦状态
                         __blockSelf.micStatus = MICSTATUS_NOMAL;
                         [__blockSelf insertMessage:rcMessage userInfo:notification.userInfo];
+                        [__blockSelf hideApplyingView];
                     }
                 }
                 
@@ -1458,6 +1482,17 @@ static int clickPraiseBtnTimes  = 0;
     }
 }
 
+- (void)hideApplyView {
+    if (self.applyView.isShow) {
+        [self.applyView hideView];
+    }
+}
+
+- (void)hideApplyingView {
+    if (self.applyingView.isShow) {
+        [self.applyingView hideView];
+    }
+}
 
 // 发送人数同步消息
 - (void)sendMemberCountMessage {
@@ -1911,12 +1946,7 @@ static int clickPraiseBtnTimes  = 0;
             }
             else if (self.micStatus == MICSTATUS_WAITING) { // 连麦申请中
                 // 弹窗取消申请
-                MJWeakSelf;
-                self.alertView = [KSNormalAlertView ks_showAlertWithTitle:@"连麦申请中,确认取消连麦申请吗?" leftTitle:@"取消" rightTitle:@"确定" inView:self.view cancel:^{
-                    
-                } confirm:^{
-                    [weakSelf sendSeatMessageApply:NO];
-                }];
+                [self displayApplyingView];
             }
             else {
                  if (self.blacklistFlag == YES) {
@@ -1929,8 +1959,8 @@ static int clickPraiseBtnTimes  = 0;
                 }
                 
                 if (self.enableSeat) {
-                    [self MBPShow:@"已发起连麦申请"];
-                    [self sendSeatMessageApply:YES];
+                    // 显示弹窗
+                    [self displaySeatApplyView];
                 }
                 else {
                     [self MBPShow:@"管理员关闭连麦申请"];
@@ -1958,6 +1988,14 @@ static int clickPraiseBtnTimes  = 0;
     }
 }
 
+- (void)displaySeatApplyView {
+    [self.applyView showInView:self.view];
+}
+
+- (void)displayApplyingView {
+    [self.applyingView showInView:self.view];
+}
+
 - (void)showCartAlert {
     [self.cardView showViewInView:self.view];
 }
@@ -2276,4 +2314,44 @@ static int clickPraiseBtnTimes  = 0;
     [[NSNotificationCenter defaultCenter] removeObserver:self];
 }
 
+- (LiveApplyView *)applyView {
+    if (!_applyView) {
+        _applyView = [LiveApplyView shareInstance];
+        MJWeakSelf;
+        [_applyView applySeatCallback:^{
+            [weakSelf applySeatAction];
+        }];
+    }
+    return _applyView;
+}
+
+- (void)applySeatAction {
+    [self MBPShow:@"已发起连麦申请"];
+    [self sendSeatMessageApply:YES];
+}
+
+- (LiveApplyingView *)applyingView {
+    if (!_applyingView) {
+        _applyingView = [LiveApplyingView shareInstance];
+        NSString *avatar = UserDefaultObjectForKey(AvatarUrlKey);
+        [_applyingView.myAvatal sd_setImageWithURL:[NSURL URLWithString:[avatar getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:USERDEFAULT_LOGO]];
+        [_applyingView.teacherAvatal sd_setImageWithURL:[NSURL URLWithString:[self.createrAvatal getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:USERDEFAULT_LOGO]];
+        MJWeakSelf;
+        [_applyingView cancleApplyCallback:^{
+            [weakSelf cancleApplyAction];
+        }];
+    }
+    return _applyingView;
+}
+
+- (void)cancleApplyAction {
+    MJWeakSelf;
+    self.alertView = [KSNormalAlertView ks_showAlertWithTitle:@"连麦申请中,确认取消连麦申请吗?" leftTitle:@"取消" rightTitle:@"确定" inView:self.view cancel:^{
+        
+    } confirm:^{
+        [weakSelf.applyingView hideView];
+        [weakSelf sendSeatMessageApply:NO];
+    }];
+}
+
 @end

+ 22 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/View/KSLiveAlertView.h

@@ -0,0 +1,22 @@
+//
+//  KSLiveAlertView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/8/26.
+//
+
+#import "BaseAlertView.h"
+
+typedef void(^LiveAlertCallback)(void);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSLiveAlertView : BaseAlertView
+
++ (instancetype)shareInstance;
+
+- (void)configDescMessage:(NSString *)descMessage leftButtonTitle:(NSString *)leftTitle rightButtonTitle:(NSString *)rightTitle cancel:(LiveAlertCallback)cancel confirm:(LiveAlertCallback)confirm;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 39 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/View/KSLiveAlertView.m

@@ -0,0 +1,39 @@
+//
+//  KSLiveAlertView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/8/26.
+//
+
+#import "KSLiveAlertView.h"
+
+@interface KSLiveAlertView ()
+
+@property (weak, nonatomic) IBOutlet UILabel *headTitleLabel;
+
+@property (weak, nonatomic) IBOutlet UIButton *leftButton;
+
+@property (weak, nonatomic) IBOutlet UIButton *rightButton;
+
+@end
+
+@implementation KSLiveAlertView
+
++ (instancetype)shareInstance {
+    KSLiveAlertView *view = [[[NSBundle mainBundle] loadNibNamed:@"KSLiveAlertView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configDescMessage:(NSString *)descMessage leftButtonTitle:(NSString *)leftTitle rightButtonTitle:(NSString *)rightTitle cancel:(LiveAlertCallback)cancel confirm:(LiveAlertCallback)confirm {
+    
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 115 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/View/KSLiveAlertView.xib

@@ -0,0 +1,115 @@
+<?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="KSLiveAlertView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bKc-op-sSr">
+                    <rect key="frame" x="68.5" y="378" width="277" height="140"/>
+                    <subviews>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MOL-hD-PTq">
+                            <rect key="frame" x="0.0" y="93" width="138" height="47"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="47" id="UdC-ov-MhK"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="16"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" title="取消">
+                                <color key="titleColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            </state>
+                        </button>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="m3C-sG-XpO">
+                            <rect key="frame" x="139" y="93" width="138" height="47"/>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="16"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" title="确定">
+                                <color key="titleColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            </state>
+                        </button>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2au-Wa-jmG">
+                            <rect key="frame" x="138" y="93" width="1" height="47"/>
+                            <color key="backgroundColor" red="0.87058823529411766" green="0.87058823529411766" blue="0.87058823529411766" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="1" id="P3b-v7-TZz"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="yCR-7e-I9F">
+                            <rect key="frame" x="0.0" y="92" width="277" height="1"/>
+                            <color key="backgroundColor" red="0.87058823529999996" green="0.87058823529999996" blue="0.87058823529999996" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="1" id="3nn-Um-B3W"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wvY-Wh-Rz2">
+                            <rect key="frame" x="0.0" y="0.0" width="277" height="92"/>
+                            <subviews>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="确认将正在申请连麦的学员清空?" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="i0a-YB-rCP">
+                                    <rect key="frame" x="35" y="29.5" width="207" height="33.5"/>
+                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                    <color key="textColor" red="0.40000000000000002" green="0.40000000000000002" blue="0.40000000000000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                            </subviews>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstItem="i0a-YB-rCP" firstAttribute="leading" secondItem="wvY-Wh-Rz2" secondAttribute="leading" constant="35" id="fgM-sM-L9E"/>
+                                <constraint firstAttribute="trailing" secondItem="i0a-YB-rCP" secondAttribute="trailing" constant="35" id="nPe-VK-jJb"/>
+                                <constraint firstItem="i0a-YB-rCP" firstAttribute="centerY" secondItem="wvY-Wh-Rz2" secondAttribute="centerY" id="sO9-qn-fRt"/>
+                            </constraints>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="trailing" secondItem="wvY-Wh-Rz2" secondAttribute="trailing" id="1pS-TW-2XY"/>
+                        <constraint firstItem="MOL-hD-PTq" firstAttribute="top" secondItem="yCR-7e-I9F" secondAttribute="bottom" id="CuR-eZ-pcn"/>
+                        <constraint firstItem="2au-Wa-jmG" firstAttribute="height" secondItem="MOL-hD-PTq" secondAttribute="height" id="DDy-Uw-Qvm"/>
+                        <constraint firstItem="m3C-sG-XpO" firstAttribute="leading" secondItem="2au-Wa-jmG" secondAttribute="trailing" id="DNS-xI-SyY"/>
+                        <constraint firstItem="MOL-hD-PTq" firstAttribute="leading" secondItem="bKc-op-sSr" secondAttribute="leading" id="FGu-jt-urW"/>
+                        <constraint firstAttribute="width" constant="277" id="KHc-9s-6eN"/>
+                        <constraint firstItem="2au-Wa-jmG" firstAttribute="leading" secondItem="MOL-hD-PTq" secondAttribute="trailing" id="KtE-Ji-Oov"/>
+                        <constraint firstAttribute="bottom" secondItem="2au-Wa-jmG" secondAttribute="bottom" id="PRQ-Ty-qc5"/>
+                        <constraint firstItem="wvY-Wh-Rz2" firstAttribute="top" secondItem="bKc-op-sSr" secondAttribute="top" id="PT4-wM-Mae"/>
+                        <constraint firstItem="yCR-7e-I9F" firstAttribute="leading" secondItem="bKc-op-sSr" secondAttribute="leading" id="QDN-3y-VFW"/>
+                        <constraint firstItem="m3C-sG-XpO" firstAttribute="width" secondItem="MOL-hD-PTq" secondAttribute="width" id="QHC-xm-9Nd"/>
+                        <constraint firstAttribute="bottom" secondItem="m3C-sG-XpO" secondAttribute="bottom" id="TMX-WO-Xfa"/>
+                        <constraint firstAttribute="height" constant="140" id="ecH-VT-8cK"/>
+                        <constraint firstAttribute="bottom" secondItem="MOL-hD-PTq" secondAttribute="bottom" id="iUo-XU-vrV"/>
+                        <constraint firstItem="yCR-7e-I9F" firstAttribute="top" secondItem="wvY-Wh-Rz2" secondAttribute="bottom" id="kbU-M9-c8W"/>
+                        <constraint firstAttribute="trailing" secondItem="yCR-7e-I9F" secondAttribute="trailing" id="km6-Hm-npQ"/>
+                        <constraint firstAttribute="trailing" secondItem="m3C-sG-XpO" secondAttribute="trailing" id="rYi-wa-fXd"/>
+                        <constraint firstItem="wvY-Wh-Rz2" firstAttribute="leading" secondItem="bKc-op-sSr" secondAttribute="leading" id="s3T-Hs-Q7o"/>
+                        <constraint firstItem="m3C-sG-XpO" firstAttribute="height" secondItem="MOL-hD-PTq" secondAttribute="height" id="y7j-oy-SVC"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="8"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.40000000000000002" colorSpace="custom" customColorSpace="sRGB"/>
+            <constraints>
+                <constraint firstItem="bKc-op-sSr" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="Xrg-jb-hj8"/>
+                <constraint firstItem="bKc-op-sSr" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="xWx-rH-J8M"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="headTitleLabel" destination="i0a-YB-rCP" id="okS-l9-Jf7"/>
+                <outlet property="leftButton" destination="MOL-hD-PTq" id="52b-sR-heE"/>
+                <outlet property="rightButton" destination="m3C-sG-XpO" id="iN3-vN-jmD"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="69.642857142857139"/>
+        </view>
+    </objects>
+</document>

+ 28 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyView.h

@@ -0,0 +1,28 @@
+//
+//  LiveApplyView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/8/26.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^LiveApplyCallback)(void);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveApplyView : UIView
+
+@property (nonatomic, assign) BOOL isShow;
+
++ (instancetype)shareInstance;
+
+- (void)showInView:(UIView *)displayView;
+
+- (void)applySeatCallback:(LiveApplyCallback)callback;
+
+- (void)hideView;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 95 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyView.m

@@ -0,0 +1,95 @@
+//
+//  LiveApplyView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/8/26.
+//
+
+#import "LiveApplyView.h"
+
+@interface LiveApplyView ()<UIGestureRecognizerDelegate>
+
+@property (weak, nonatomic) IBOutlet UIView *containerView;
+
+@property (nonatomic, copy) LiveApplyCallback callback;
+
+@end
+
+@implementation LiveApplyView
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    [self setUpUI];
+    [self addTapGesture];
+}
+
+- (void)setUpUI {
+    if (@available(iOS 11.0, *)) {
+        _containerView.layer.cornerRadius = 14;
+        _containerView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner; // 左上圆角
+    }
+    else {
+        UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:_containerView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(14, 14)];
+        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
+        maskLayer.frame = _containerView.bounds;
+        maskLayer.path = path.CGPath;
+        _containerView.layer.mask = maskLayer;
+    }
+    _containerView.layer.masksToBounds = YES;
+}
+
+- (void)addTapGesture {
+    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideView)];
+    tap.delegate = self;
+    [self addGestureRecognizer:tap];
+}
+
++ (instancetype)shareInstance {
+    LiveApplyView *view = [[[NSBundle mainBundle] loadNibNamed:@"LiveApplyView" owner:nil options:nil] firstObject];
+    view.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight);
+    return view;
+}
+
+- (void)showInView:(UIView *)displayView {
+    self.isShow = YES;
+    [displayView addSubview:self];
+}
+
+- (void)applySeatCallback:(LiveApplyCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (void)hideView {
+    self.isShow = NO;
+    [self removeFromSuperview];
+}
+
+
+- (IBAction)applyAction:(id)sender {
+    if (self.callback) {
+        self.callback();
+    }
+    [self hideView];
+}
+
+- (IBAction)cancleAction:(id)sender {
+    [self hideView];
+}
+
+- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
+    if ([touch.view isDescendantOfView:self.containerView]) {
+        return NO;
+    }
+    return YES;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 90 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyView.xib

@@ -0,0 +1,90 @@
+<?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="LiveApplyView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="aXt-Ef-uLt">
+                    <rect key="frame" x="0.0" y="755" width="414" height="141"/>
+                    <subviews>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Gy4-S5-S7T">
+                            <rect key="frame" x="0.0" y="0.0" width="414" height="60"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="60" id="0PC-ZQ-L87"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" title="申请连麦">
+                                <color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            </state>
+                            <connections>
+                                <action selector="applyAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="gDK-O0-ykv"/>
+                            </connections>
+                        </button>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bSH-gd-YJE">
+                            <rect key="frame" x="0.0" y="60" width="414" height="1"/>
+                            <color key="backgroundColor" red="0.87058823529411766" green="0.87058823529411766" blue="0.87058823529411766" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="1" id="mQx-uS-ZDc"/>
+                            </constraints>
+                        </view>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ddN-vb-duW">
+                            <rect key="frame" x="0.0" y="61" width="414" height="60"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="60" id="b0Y-a8-qgr"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="18"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" title="取消">
+                                <color key="titleColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            </state>
+                            <connections>
+                                <action selector="cancleAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="tsf-5c-wwY"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstItem="ddN-vb-duW" firstAttribute="top" secondItem="bSH-gd-YJE" secondAttribute="bottom" id="2Zz-L7-eOQ"/>
+                        <constraint firstAttribute="height" constant="141" id="5Zh-gD-IsK"/>
+                        <constraint firstAttribute="trailing" secondItem="ddN-vb-duW" secondAttribute="trailing" id="C0k-af-CaY"/>
+                        <constraint firstItem="bSH-gd-YJE" firstAttribute="leading" secondItem="aXt-Ef-uLt" secondAttribute="leading" id="HQs-3G-5rE"/>
+                        <constraint firstAttribute="trailing" secondItem="Gy4-S5-S7T" secondAttribute="trailing" id="Idb-3M-XgU"/>
+                        <constraint firstItem="Gy4-S5-S7T" firstAttribute="top" secondItem="aXt-Ef-uLt" secondAttribute="top" id="Qnh-v6-4KM"/>
+                        <constraint firstItem="bSH-gd-YJE" firstAttribute="top" secondItem="Gy4-S5-S7T" secondAttribute="bottom" id="RRj-Gh-arv"/>
+                        <constraint firstItem="ddN-vb-duW" firstAttribute="leading" secondItem="aXt-Ef-uLt" secondAttribute="leading" id="RdP-hY-amA"/>
+                        <constraint firstAttribute="trailing" secondItem="bSH-gd-YJE" secondAttribute="trailing" id="pNA-67-dE1"/>
+                        <constraint firstItem="Gy4-S5-S7T" firstAttribute="leading" secondItem="aXt-Ef-uLt" secondAttribute="leading" id="yxy-Oq-cl7"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="aXt-Ef-uLt" secondAttribute="bottom" id="05x-K4-5ro"/>
+                <constraint firstAttribute="trailing" secondItem="aXt-Ef-uLt" secondAttribute="trailing" id="7wm-GA-5vt"/>
+                <constraint firstItem="aXt-Ef-uLt" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="sOS-84-44k"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="containerView" destination="aXt-Ef-uLt" id="bdK-dB-nKi"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="95.758928571428569"/>
+        </view>
+    </objects>
+    <resources>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 31 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyingView.h

@@ -0,0 +1,31 @@
+//
+//  LiveApplyingView.h
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/8/26.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^LiveCancleApplyBlcok)(void);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveApplyingView : UIView
+
+@property (nonatomic, assign) BOOL isShow;
+
+@property (weak, nonatomic) IBOutlet UIImageView *myAvatal;
+
+@property (weak, nonatomic) IBOutlet UIImageView *teacherAvatal;
+
++ (instancetype)shareInstance;
+
+- (void)showInView:(UIView *)displayView;
+
+- (void)cancleApplyCallback:(LiveCancleApplyBlcok)callback;
+
+- (void)hideView;
+@end
+
+NS_ASSUME_NONNULL_END

+ 90 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyingView.m

@@ -0,0 +1,90 @@
+//
+//  LiveApplyingView.m
+//  KulexiuForStudent
+//
+//  Created by 王智 on 2022/8/26.
+//
+
+#import "LiveApplyingView.h"
+
+@interface LiveApplyingView ()<UIGestureRecognizerDelegate>
+
+@property (weak, nonatomic) IBOutlet UIView *containerView;
+
+@property (nonatomic, copy) LiveCancleApplyBlcok callback;
+
+@end
+
+@implementation LiveApplyingView
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    [self setUpUI];
+    [self addTapGesture];
+}
+
+- (void)setUpUI {
+    if (@available(iOS 11.0, *)) {
+        _containerView.layer.cornerRadius = 14;
+        _containerView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner; // 左上圆角
+    }
+    else {
+        UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:_containerView.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(14, 14)];
+        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
+        maskLayer.frame = _containerView.bounds;
+        maskLayer.path = path.CGPath;
+        _containerView.layer.mask = maskLayer;
+    }
+    _containerView.layer.masksToBounds = YES;
+}
+
+- (void)addTapGesture {
+    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideView)];
+    tap.delegate = self;
+    [self addGestureRecognizer:tap];
+}
+
+- (void)hideView {
+    self.isShow = NO;
+    [self removeFromSuperview];
+}
+
++ (instancetype)shareInstance {
+    LiveApplyingView *view = [[[NSBundle mainBundle] loadNibNamed:@"LiveApplyingView" owner:nil options:nil] firstObject];
+    view.frame = CGRectMake(0, 0, KPortraitWidth, KPortraitHeight);
+    return view;
+}
+
+- (void)showInView:(UIView *)displayView {
+    self.isShow = YES;
+    [displayView addSubview:self];
+}
+
+- (void)cancleApplyCallback:(LiveCancleApplyBlcok)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+
+- (IBAction)cancleApplyAction:(id)sender {
+    if (self.callback) {
+        self.callback();
+    }
+}
+
+- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
+    if ([touch.view isDescendantOfView:self.containerView]) {
+        return NO;
+    }
+    return YES;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 125 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveApplyingView.xib

@@ -0,0 +1,125 @@
+<?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="LiveApplyingView">
+            <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Jll-Qz-Jz1">
+                    <rect key="frame" x="0.0" y="608" width="414" height="288"/>
+                    <subviews>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="取消申请" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0p0-3M-G5w">
+                            <rect key="frame" x="338" y="20" width="58" height="17"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jex-7n-2XW">
+                            <rect key="frame" x="338" y="8.5" width="58" height="40"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="40" id="v4D-iy-sVi"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="cancleApplyAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="x0L-0h-o81"/>
+                            </connections>
+                        </button>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="user_default_avatal" translatesAutoresizingMaskIntoConstraints="NO" id="wTz-Qn-nGw">
+                            <rect key="frame" x="126.5" y="64" width="48" height="48"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="48" id="jmZ-n2-cyB"/>
+                                <constraint firstAttribute="width" constant="48" id="yUY-zO-oXE"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="24"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </imageView>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="user_default_avatal" translatesAutoresizingMaskIntoConstraints="NO" id="0Ka-dD-OT2">
+                            <rect key="frame" x="239.5" y="64" width="48" height="48"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="48" id="2Oe-cF-PfY"/>
+                                <constraint firstAttribute="width" constant="48" id="uBr-dV-vKq"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="24"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </imageView>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mic_connting" translatesAutoresizingMaskIntoConstraints="NO" id="TNz-Yw-Dop">
+                            <rect key="frame" x="188.5" y="74" width="37" height="28"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="37" id="Cu5-1m-zFB"/>
+                                <constraint firstAttribute="height" constant="28" id="Z3x-hP-Erf"/>
+                            </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="fcW-ky-NK2">
+                            <rect key="frame" x="161" y="150" width="92" height="22"/>
+                            <fontDescription key="fontDescription" type="system" weight="medium" pointSize="18"/>
+                            <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <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="Rcd-yy-NiK">
+                            <rect key="frame" x="164" y="180" width="86" height="17"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <color key="textColor" red="0.59999999999999998" green="0.59999999999999998" blue="0.59999999999999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                    </subviews>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstItem="fcW-ky-NK2" firstAttribute="top" secondItem="wTz-Qn-nGw" secondAttribute="bottom" constant="38" id="CbU-Sz-A3h"/>
+                        <constraint firstItem="fcW-ky-NK2" firstAttribute="centerX" secondItem="Jll-Qz-Jz1" secondAttribute="centerX" id="Ckp-FP-dN3"/>
+                        <constraint firstItem="TNz-Yw-Dop" firstAttribute="top" secondItem="Jll-Qz-Jz1" secondAttribute="top" constant="74" id="DkR-b7-TtC"/>
+                        <constraint firstItem="Rcd-yy-NiK" firstAttribute="top" secondItem="fcW-ky-NK2" secondAttribute="bottom" constant="8" id="SYi-0N-rfn"/>
+                        <constraint firstItem="0Ka-dD-OT2" firstAttribute="centerY" secondItem="wTz-Qn-nGw" secondAttribute="centerY" id="VRS-Vo-bRb"/>
+                        <constraint firstItem="jex-7n-2XW" firstAttribute="centerY" secondItem="0p0-3M-G5w" secondAttribute="centerY" id="Yhb-gM-L5e"/>
+                        <constraint firstItem="0p0-3M-G5w" firstAttribute="top" secondItem="Jll-Qz-Jz1" secondAttribute="top" constant="20" id="Znf-ZO-KzW"/>
+                        <constraint firstItem="0Ka-dD-OT2" firstAttribute="leading" secondItem="TNz-Yw-Dop" secondAttribute="trailing" constant="14" id="bDK-oi-CqH"/>
+                        <constraint firstItem="jex-7n-2XW" firstAttribute="centerX" secondItem="0p0-3M-G5w" secondAttribute="centerX" id="btw-Sx-3O6"/>
+                        <constraint firstItem="TNz-Yw-Dop" firstAttribute="leading" secondItem="wTz-Qn-nGw" secondAttribute="trailing" constant="14" id="eCv-Hm-1b2"/>
+                        <constraint firstAttribute="height" constant="288" id="fVG-bS-LpJ"/>
+                        <constraint firstItem="jex-7n-2XW" firstAttribute="leading" secondItem="0p0-3M-G5w" secondAttribute="leading" id="l6c-GI-tkv"/>
+                        <constraint firstItem="Rcd-yy-NiK" firstAttribute="centerX" secondItem="fcW-ky-NK2" secondAttribute="centerX" id="oRq-PV-fjk"/>
+                        <constraint firstAttribute="trailing" secondItem="0p0-3M-G5w" secondAttribute="trailing" constant="18" id="ogL-J4-vM1"/>
+                        <constraint firstItem="TNz-Yw-Dop" firstAttribute="centerX" secondItem="Jll-Qz-Jz1" secondAttribute="centerX" id="q5p-R2-dcW"/>
+                        <constraint firstItem="TNz-Yw-Dop" firstAttribute="centerY" secondItem="wTz-Qn-nGw" secondAttribute="centerY" id="tWo-p8-BdQ"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="Jll-Qz-Jz1" secondAttribute="trailing" id="Gl5-8d-raH"/>
+                <constraint firstItem="Jll-Qz-Jz1" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="k0o-oO-Tc9"/>
+                <constraint firstAttribute="bottom" secondItem="Jll-Qz-Jz1" secondAttribute="bottom" id="lkx-EC-0ss"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="containerView" destination="Jll-Qz-Jz1" id="PP1-o4-Va2"/>
+                <outlet property="myAvatal" destination="wTz-Qn-nGw" id="7Ij-1V-ACK"/>
+                <outlet property="teacherAvatal" destination="0Ka-dD-OT2" id="aLu-st-eO0"/>
+            </connections>
+            <point key="canvasLocation" x="131.8840579710145" y="95.758928571428569"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="mic_connting" width="37" height="28"/>
+        <image name="user_default_avatal" width="52" height="52"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 25 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveRoomAlertView.h

@@ -0,0 +1,25 @@
+//
+//  LiveRoomAlertView.h
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/6/16.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^LiveAlertCallback)(void);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface LiveRoomAlertView : UIView
+
+@property (nonatomic, assign) BOOL isShow;
+
++ (LiveRoomAlertView *)liveroomAlertWithTitle:(NSString *)title leftButtonTitle:(NSString *)leftTitle rightTitle:(NSString *)rightTitle inView:(UIView *)displayView cancel:(LiveAlertCallback)cancel confirm:(LiveAlertCallback)confirm;
+
+- (void)dismissAlertView;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 198 - 0
KulexiuForStudent/KulexiuForStudent/Module/Live/View/LiveRoomAlertView.m

@@ -0,0 +1,198 @@
+//
+//  LiveRoomAlertView.m
+//  TeacherDaya
+//
+//  Created by 王智 on 2022/6/16.
+//  Copyright © 2022 DayaMusic. All rights reserved.
+//
+
+#import "LiveRoomAlertView.h"
+#import "UIView+Animation.h"
+
+typedef enum : NSUInteger {
+    LiveRoomAlertViewCancel,
+    LiveRoomAlertViewConfirm,
+} LiveRoomAlertViewActionTag;
+
+#define ContainerWidth 320
+#define ContainerHeight 180
+
+@interface LiveRoomAlertView ()
+
+@property (nonatomic, strong) UILabel *tipsLabel;
+
+@property (nonatomic, strong) UILabel *titleLable;
+
+@property (nonatomic, strong) UIButton *cancelButton;
+
+@property (nonatomic, strong) UIButton *sureButton;
+
+@property (nonatomic, strong) NSString *title;
+
+@property (nonatomic, strong) NSString *leftTitle;
+
+@property (nonatomic, strong) NSString *rightTitle;
+
+@property (nonatomic, copy) LiveAlertCallback cancel;
+
+@property (nonatomic, copy) LiveAlertCallback confirm;
+
+@end
+
+@implementation LiveRoomAlertView
+
+
+
++ (LiveRoomAlertView *)liveroomAlertWithTitle:(NSString *)title leftButtonTitle:(NSString *)leftTitle rightTitle:(NSString *)rightTitle inView:(UIView *)displayView cancel:(LiveAlertCallback)cancel confirm:(LiveAlertCallback)confirm {
+    LiveRoomAlertView *alertView = [[LiveRoomAlertView alloc] initWithFrame:CGRectMake(0, 0, KPortraitWidth, KPortraitHeight)];
+    alertView.backgroundColor = HexRGBAlpha(0x000000, 0.5f);
+    alertView.title = title;
+    alertView.leftTitle = leftTitle;
+    alertView.rightTitle = rightTitle;
+    alertView.cancel = cancel;
+    alertView.confirm = confirm;
+    [alertView addSubviews];
+    [alertView showAlertInView:displayView];
+    return alertView;
+}
+
+
+- (void)addSubviews {
+    UIView *contentView = [[UIView alloc] initWithFrame:CGRectMake((kScreenWidth - ContainerWidth) / 2, (CGRectGetHeight(self.bounds) - ContainerHeight) / 2, ContainerWidth, ContainerHeight)];
+    contentView.backgroundColor = [UIColor whiteColor];
+    contentView.layer.cornerRadius = 8.0f;
+    contentView.layer.masksToBounds = YES;
+    [self addSubview:contentView];
+    
+    [contentView addSubview:self.titleLable];
+    [contentView addSubview:self.cancelButton];
+    [contentView addSubview:self.sureButton];
+    
+    CGFloat width = (ContainerWidth - 1) / 2.0f;
+    
+    [self.cancelButton mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(contentView.mas_left);
+        make.bottom.equalTo(contentView.mas_bottom);
+        make.height.mas_equalTo(47);
+        make.width.mas_equalTo(width);
+    }];
+    
+    [self.sureButton mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(self.cancelButton.mas_right);
+        make.bottom.mas_equalTo(contentView.mas_bottom);
+        make.height.mas_equalTo(47);
+        make.width.mas_equalTo(width);
+    }];
+    
+    UIView *buttonSpaceLineView = [[UIView alloc] initWithFrame:CGRectZero];
+    buttonSpaceLineView.backgroundColor = HexRGB(0xDEDEDE);
+    [contentView addSubview:buttonSpaceLineView];
+    
+    [buttonSpaceLineView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(self.cancelButton.mas_right);
+        make.top.bottom.mas_equalTo(self.cancelButton);
+        make.width.mas_equalTo(1);
+    }];
+    
+    UIView *headLine = [[UIView alloc] initWithFrame:CGRectZero];
+    headLine.backgroundColor = HexRGB(0xDEDEDE);
+    [contentView addSubview:headLine];
+    [headLine mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.mas_equalTo(contentView);
+        make.height.mas_equalTo(1);
+        make.bottom.mas_equalTo(self.cancelButton.mas_top);
+    }];
+    
+    [self.titleLable mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(contentView.mas_top).offset(30);
+        make.left.equalTo(contentView.mas_left).offset(36);
+        make.right.equalTo(contentView.mas_right).offset(-36);
+        make.bottom.mas_greaterThanOrEqualTo(self.sureButton.mas_top).offset(-15);
+    }];
+    
+}
+
+
+
+- (void)showAlertInView:(UIView *)displayView {
+    _isShow = YES;
+    [displayView addSubview:self];
+    [displayView bringSubviewToFront:self];
+    [self setPopAnimation];
+}
+
+
+- (void)dismissAlertView {
+    _isShow = NO;
+    [self removeFromSuperview];
+}
+
+
+- (void)buttonAction:(UIButton *)button {
+    if (button.tag == LiveRoomAlertViewCancel) {
+        if (self.cancel) {
+            self.cancel();
+        }
+    }else {
+        if (self.confirm) {
+            self.confirm();
+        }
+    }
+    [self dismissAlertView];
+}
+
+
+
+
+- (UILabel *)titleLable {
+    if (!_titleLable) {
+        _titleLable = [[UILabel alloc] init];
+        _titleLable.font = [UIFont systemFontOfSize:14.0f];
+        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
+        [paragraphStyle setLineSpacing:4];//调整行间距
+        [paragraphStyle setAlignment:NSTextAlignmentCenter];
+        NSMutableAttributedString *attrs = [[NSMutableAttributedString alloc] initWithString:self.title attributes:@{NSParagraphStyleAttributeName:paragraphStyle,NSFontAttributeName:[UIFont systemFontOfSize:14.0f],NSForegroundColorAttributeName:HexRGB(0x666666)}];
+        _titleLable.attributedText = attrs;
+        _titleLable.numberOfLines = 0;
+        _titleLable.lineBreakMode = NSLineBreakByTruncatingMiddle;
+    }
+    return _titleLable;
+}
+
+- (UIButton *)cancelButton {
+    if(!_cancelButton) {
+        _cancelButton = [[UIButton alloc] init];
+        _cancelButton.backgroundColor =  [UIColor clearColor];
+        [_cancelButton.titleLabel setFont:[UIFont systemFontOfSize:16.0f]];
+        [_cancelButton setTitleColor:HexRGB(0x666666) forState:UIControlStateNormal];
+        [_cancelButton setTitle:self.leftTitle forState:UIControlStateNormal];
+        _cancelButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
+        _cancelButton.tag = LiveRoomAlertViewCancel;
+        [_cancelButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
+    }
+    return _cancelButton;
+}
+
+- (UIButton *)sureButton {
+    if (!_sureButton) {
+        _sureButton = [[UIButton alloc] init];
+        _sureButton.backgroundColor =  [UIColor clearColor];
+        [_sureButton.titleLabel setFont:[UIFont systemFontOfSize:16.0f weight:UIFontWeightMedium]];
+        [_sureButton setTitleColor:HexRGB(0x333333) forState:UIControlStateNormal];
+        [_sureButton setTitle:self.rightTitle forState:UIControlStateNormal];
+        _sureButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
+        _sureButton.tag = LiveRoomAlertViewConfirm;
+        [_sureButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
+    }
+    return _sureButton;
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end