Browse Source

feat: combo 优化

陈文艺 5 months ago
parent
commit
ce88f4ee15
61 changed files with 2472 additions and 1643 deletions
  1. 62 8
      MiMoLive/MiMoLive.xcodeproj/project.pbxproj
  2. 2 2
      MiMoLive/MiMoLive.xcodeproj/xcshareddata/xcschemes/MiMoLive_Preview.xcscheme
  3. 6 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/Contents.json
  4. 21 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv1.imageset/Contents.json
  5. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv1.imageset/icon_combo_lv1.png
  6. 21 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv2.imageset/Contents.json
  7. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv2.imageset/icon_combo_lv2.png
  8. 21 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv3.imageset/Contents.json
  9. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv3.imageset/icon_combo_lv3.png
  10. 21 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv4.imageset/Contents.json
  11. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv4.imageset/icon_combo_lv4.png
  12. 6 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/Contents.json
  13. 21 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_1.imageset/Contents.json
  14. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_1.imageset/进度0@2x.png
  15. 21 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_2.imageset/Contents.json
  16. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_2.imageset/ic_gift_show_combo_level_3@2x.png
  17. 21 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_3.imageset/Contents.json
  18. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_3.imageset/ic_gift_show_combo_level_4@2x.png
  19. 21 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_4.imageset/Contents.json
  20. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_4.imageset/ic_gift_show_combo_level_5@2x.png
  21. 21 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_5.imageset/Contents.json
  22. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_5.imageset/ic_gift_show_combo_level_6@2x.png
  23. 21 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_bg.imageset/Contents.json
  24. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_bg.imageset/ic_gift_show_combo_level_bg@2x.png
  25. 21 0
      MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_1.imageset/Contents.json
  26. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_1.imageset/icon_base_gift_custom_view_bg@2x.png
  27. 1 1
      MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_2.imageset/Contents.json
  28. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_2.imageset/icon_base_gift_custom_view_bg_2@2x.png
  29. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_2.imageset/横幅1@2x.png
  30. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_3.imageset/icon_base_gift_custom_view_bg_3@2x.png
  31. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_4.imageset/icon_base_gift_custom_view_bg_4@2x.png
  32. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_5.imageset/icon_base_gift_custom_view_bg_5@2x.png
  33. BIN
      MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_6.imageset/icon_base_gift_custom_view_bg_6@2x.png
  34. 24 1
      MiMoLive/MiMoLive/Classes/Live/MOShowLiveVC.m
  35. 90 21
      MiMoLive/MiMoLive/Classes/Live/View/LiveGiftShowView/LiveGiftShowView.m
  36. 435 0
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftBottomMenuView.swift
  37. 3 9
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftCollectionView.h
  38. 24 77
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftCollectionView.m
  39. 0 15
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftItemCell.h
  40. 61 260
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftItemCell.m
  41. 0 62
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListBagView/MOBagCollectionView.m
  42. 5 8
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListBagView/MOGiftListBagView.h
  43. 8 311
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListBagView/MOGiftListBagView.m
  44. 7 33
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListBagView/Props/MOPropsItemCell.m
  45. 1 4
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListView.h
  46. 261 612
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListView.m
  47. 0 211
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListView.xib
  48. 324 0
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftPanelsView.swift
  49. 313 0
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOSendGiftView.swift
  50. 2 2
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOStripeView/MOStripeView.h
  51. 2 0
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/MOShowRoomLiveView.h
  52. 5 5
      MiMoLive/MiMoLive/Classes/Live/View/LiveingView/MOShowRoomLiveView.xib
  53. 187 0
      MiMoLive/MiMoLive/Classes/Live/View/MOComboSendGiftView/MOComboCountDownView.swift
  54. 407 0
      MiMoLive/MiMoLive/Classes/Live/View/MOComboSendGiftView/MOGiftComboView.swift
  55. BIN
      MiMoLive/MiMoLive/File/Gift/icon_gift_combo_lv_1.webp
  56. BIN
      MiMoLive/MiMoLive/File/Gift/icon_gift_combo_lv_2.webp
  57. BIN
      MiMoLive/MiMoLive/File/Gift/icon_gift_combo_lv_3.webp
  58. BIN
      MiMoLive/MiMoLive/File/Gift/icon_gift_combo_lv_4.webp
  59. BIN
      MiMoLive/MiMoLive/File/Gift/icon_gift_selected_bg.webp
  60. 1 1
      MiMoLive/MiMoLive/Global/MOGlobal.h
  61. 4 0
      MiMoLive/MiMoLive/MiMoLive-Bridging-Header.h

+ 62 - 8
MiMoLive/MiMoLive.xcodeproj/project.pbxproj

@@ -436,7 +436,6 @@
 		A62729B02B0EF79E006464EB /* MOLiveMemberData.m in Sources */ = {isa = PBXBuildFile; fileRef = A62729AE2B0EF79E006464EB /* MOLiveMemberData.m */; };
 		A62729BA2B0F3951006464EB /* UIImageView+MOSvga.m in Sources */ = {isa = PBXBuildFile; fileRef = A62729B92B0F3951006464EB /* UIImageView+MOSvga.m */; };
 		A6272BF52B0F6DD9006464EB /* MOGiftListView.m in Sources */ = {isa = PBXBuildFile; fileRef = A6272BF42B0F6DD9006464EB /* MOGiftListView.m */; };
-		A6272BF72B0F6DF0006464EB /* MOGiftListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = A6272BF62B0F6DF0006464EB /* MOGiftListView.xib */; };
 		A6272BFA2B0F78BB006464EB /* MOGiftCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = A6272BF92B0F78BB006464EB /* MOGiftCollectionView.m */; };
 		A6293E7C2B6B60640000EEA3 /* MOLiveBroadCastEndView.m in Sources */ = {isa = PBXBuildFile; fileRef = A6293E7B2B6B60640000EEA3 /* MOLiveBroadCastEndView.m */; };
 		A6293E7E2B6B606D0000EEA3 /* MOLiveBroadCastEndView.xib in Resources */ = {isa = PBXBuildFile; fileRef = A6293E7D2B6B606D0000EEA3 /* MOLiveBroadCastEndView.xib */; };
@@ -2640,7 +2639,6 @@
 		FB06A1012E82B3FB00A3CD51 /* MOSignInCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A6999C8C2C9063CE009AE37C /* MOSignInCollectionViewCell.xib */; };
 		FB06A1022E82B3FB00A3CD51 /* MOFirstRechargeTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A6999C7E2C90235B009AE37C /* MOFirstRechargeTableViewCell.xib */; };
 		FB06A1032E82B3FB00A3CD51 /* MOModifyAvatarVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = A61944002AE52E8700D2878F /* MOModifyAvatarVC.xib */; };
-		FB06A1072E82B3FB00A3CD51 /* MOGiftListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = A6272BF62B0F6DF0006464EB /* MOGiftListView.xib */; };
 		FB06A1092E82B3FB00A3CD51 /* MOTaskBaseBtnView.xib in Resources */ = {isa = PBXBuildFile; fileRef = A67908EE2C0C6763001B73AE /* MOTaskBaseBtnView.xib */; };
 		FB06A10A2E82B3FB00A3CD51 /* (null) in Resources */ = {isa = PBXBuildFile; };
 		FB06A10C2E82B3FB00A3CD51 /* MODiaWinHistoryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = A6F8CE742C3564DC003475BE /* MODiaWinHistoryView.xib */; };
@@ -2786,6 +2784,26 @@
 		FB4CE1C02E9A45170087C5B8 /* MOLinePkHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB4CE1B92E9A45170087C5B8 /* MOLinePkHistoryView.swift */; };
 		FB56C0A32E87BC81001E86DF /* MOCustomTabBar.m in Sources */ = {isa = PBXBuildFile; fileRef = A699F3542E8551FE00448188 /* MOCustomTabBar.m */; };
 		FB56C0A42E87BC8C001E86DF /* MOBeautyResLicense.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A8A070B2E812EE40081C87A /* MOBeautyResLicense.m */; };
+		FB56CD8D2EA87A2F008F806D /* MOGiftPanelsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB56CD8C2EA87A2F008F806D /* MOGiftPanelsView.swift */; };
+		FB56CD8E2EA87A2F008F806D /* MOGiftPanelsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB56CD8C2EA87A2F008F806D /* MOGiftPanelsView.swift */; };
+		FB56CD902EA87A38008F806D /* MOSendGiftView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB56CD8F2EA87A38008F806D /* MOSendGiftView.swift */; };
+		FB56CD912EA87A38008F806D /* MOSendGiftView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB56CD8F2EA87A38008F806D /* MOSendGiftView.swift */; };
+		FB56CD932EA87A3D008F806D /* MOGiftBottomMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB56CD922EA87A3D008F806D /* MOGiftBottomMenuView.swift */; };
+		FB56CD942EA87A3D008F806D /* MOGiftBottomMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB56CD922EA87A3D008F806D /* MOGiftBottomMenuView.swift */; };
+		FB56CD962EA88326008F806D /* MOGiftComboView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB56CD952EA88326008F806D /* MOGiftComboView.swift */; };
+		FB56CD972EA88326008F806D /* MOGiftComboView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB56CD952EA88326008F806D /* MOGiftComboView.swift */; };
+		FB56CD992EA88333008F806D /* MOComboCountDownView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB56CD982EA88333008F806D /* MOComboCountDownView.swift */; };
+		FB56CD9A2EA88333008F806D /* MOComboCountDownView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB56CD982EA88333008F806D /* MOComboCountDownView.swift */; };
+		FB56CDA22EA8D82F008F806D /* icon_gift_combo_lv_3.webp in Resources */ = {isa = PBXBuildFile; fileRef = FB56CDA02EA8D82F008F806D /* icon_gift_combo_lv_3.webp */; };
+		FB56CDA32EA8D82F008F806D /* icon_gift_selected_bg.webp in Resources */ = {isa = PBXBuildFile; fileRef = FB56CD9E2EA8D82F008F806D /* icon_gift_selected_bg.webp */; };
+		FB56CDA42EA8D82F008F806D /* icon_gift_combo_lv_4.webp in Resources */ = {isa = PBXBuildFile; fileRef = FB56CDA12EA8D82F008F806D /* icon_gift_combo_lv_4.webp */; };
+		FB56CDA52EA8D82F008F806D /* icon_gift_combo_lv_2.webp in Resources */ = {isa = PBXBuildFile; fileRef = FB56CD9F2EA8D82F008F806D /* icon_gift_combo_lv_2.webp */; };
+		FB56CDA62EA8D82F008F806D /* icon_gift_combo_lv_1.webp in Resources */ = {isa = PBXBuildFile; fileRef = FB56CD9D2EA8D82F008F806D /* icon_gift_combo_lv_1.webp */; };
+		FB56CDA72EA8D82F008F806D /* icon_gift_combo_lv_3.webp in Resources */ = {isa = PBXBuildFile; fileRef = FB56CDA02EA8D82F008F806D /* icon_gift_combo_lv_3.webp */; };
+		FB56CDA82EA8D82F008F806D /* icon_gift_selected_bg.webp in Resources */ = {isa = PBXBuildFile; fileRef = FB56CD9E2EA8D82F008F806D /* icon_gift_selected_bg.webp */; };
+		FB56CDA92EA8D82F008F806D /* icon_gift_combo_lv_4.webp in Resources */ = {isa = PBXBuildFile; fileRef = FB56CDA12EA8D82F008F806D /* icon_gift_combo_lv_4.webp */; };
+		FB56CDAA2EA8D82F008F806D /* icon_gift_combo_lv_2.webp in Resources */ = {isa = PBXBuildFile; fileRef = FB56CD9F2EA8D82F008F806D /* icon_gift_combo_lv_2.webp */; };
+		FB56CDAB2EA8D82F008F806D /* icon_gift_combo_lv_1.webp in Resources */ = {isa = PBXBuildFile; fileRef = FB56CD9D2EA8D82F008F806D /* icon_gift_combo_lv_1.webp */; };
 		FB6A3AF72E84D98A003C754B /* MOCommonUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBF574202E8275B1001B14D4 /* MOCommonUI.swift */; };
 		FB6C90882E7C1AB3004DF690 /* MOGiftListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB6C90872E7C1AB3004DF690 /* MOGiftListViewModel.swift */; };
 		FB6C90ED2E7C2F41004DF690 /* Dictionary+Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB6C90EC2E7C2F41004DF690 /* Dictionary+Response.swift */; };
@@ -3700,7 +3718,6 @@
 		A62729B92B0F3951006464EB /* UIImageView+MOSvga.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIImageView+MOSvga.m"; sourceTree = "<group>"; };
 		A6272BF32B0F6DD9006464EB /* MOGiftListView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MOGiftListView.h; sourceTree = "<group>"; };
 		A6272BF42B0F6DD9006464EB /* MOGiftListView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MOGiftListView.m; sourceTree = "<group>"; };
-		A6272BF62B0F6DF0006464EB /* MOGiftListView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MOGiftListView.xib; sourceTree = "<group>"; };
 		A6272BF82B0F78BB006464EB /* MOGiftCollectionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MOGiftCollectionView.h; sourceTree = "<group>"; };
 		A6272BF92B0F78BB006464EB /* MOGiftCollectionView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MOGiftCollectionView.m; sourceTree = "<group>"; };
 		A6293E7A2B6B60640000EEA3 /* MOLiveBroadCastEndView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MOLiveBroadCastEndView.h; sourceTree = "<group>"; };
@@ -5385,6 +5402,16 @@
 		FB4CE1B72E9A45170087C5B8 /* MOLinePkHistoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MOLinePkHistoryCell.swift; sourceTree = "<group>"; };
 		FB4CE1B82E9A45170087C5B8 /* MOLinePkHistoryListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MOLinePkHistoryListView.swift; sourceTree = "<group>"; };
 		FB4CE1B92E9A45170087C5B8 /* MOLinePkHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MOLinePkHistoryView.swift; sourceTree = "<group>"; };
+		FB56CD8C2EA87A2F008F806D /* MOGiftPanelsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MOGiftPanelsView.swift; sourceTree = "<group>"; };
+		FB56CD8F2EA87A38008F806D /* MOSendGiftView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MOSendGiftView.swift; sourceTree = "<group>"; };
+		FB56CD922EA87A3D008F806D /* MOGiftBottomMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MOGiftBottomMenuView.swift; sourceTree = "<group>"; };
+		FB56CD952EA88326008F806D /* MOGiftComboView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MOGiftComboView.swift; sourceTree = "<group>"; };
+		FB56CD982EA88333008F806D /* MOComboCountDownView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MOComboCountDownView.swift; sourceTree = "<group>"; };
+		FB56CD9D2EA8D82F008F806D /* icon_gift_combo_lv_1.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = icon_gift_combo_lv_1.webp; sourceTree = "<group>"; };
+		FB56CD9E2EA8D82F008F806D /* icon_gift_selected_bg.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = icon_gift_selected_bg.webp; sourceTree = "<group>"; };
+		FB56CD9F2EA8D82F008F806D /* icon_gift_combo_lv_2.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = icon_gift_combo_lv_2.webp; sourceTree = "<group>"; };
+		FB56CDA02EA8D82F008F806D /* icon_gift_combo_lv_3.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = icon_gift_combo_lv_3.webp; sourceTree = "<group>"; };
+		FB56CDA12EA8D82F008F806D /* icon_gift_combo_lv_4.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = icon_gift_combo_lv_4.webp; sourceTree = "<group>"; };
 		FB6C90872E7C1AB3004DF690 /* MOGiftListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MOGiftListViewModel.swift; sourceTree = "<group>"; };
 		FB6C90EC2E7C2F41004DF690 /* Dictionary+Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+Response.swift"; sourceTree = "<group>"; };
 		FB6C90EE2E7C35C4004DF690 /* MOBagCollectionView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MOBagCollectionView.h; sourceTree = "<group>"; };
@@ -7427,7 +7454,6 @@
 				A6D05D472C47C8FE0060014C /* Model */,
 				A6272BF32B0F6DD9006464EB /* MOGiftListView.h */,
 				A6272BF42B0F6DD9006464EB /* MOGiftListView.m */,
-				A6272BF62B0F6DF0006464EB /* MOGiftListView.xib */,
 				A6272BF82B0F78BB006464EB /* MOGiftCollectionView.h */,
 				A6272BF92B0F78BB006464EB /* MOGiftCollectionView.m */,
 				A6990F602B10447100C8BDF1 /* MOGiftItemCell.h */,
@@ -7438,6 +7464,9 @@
 				A614852F2C737E5D00DDD3C7 /* MOGiftUserCell.h */,
 				A61485302C737E5D00DDD3C7 /* MOGiftUserCell.m */,
 				A61485312C737E5D00DDD3C7 /* MOGiftUserCell.xib */,
+				FB56CD922EA87A3D008F806D /* MOGiftBottomMenuView.swift */,
+				FB56CD8C2EA87A2F008F806D /* MOGiftPanelsView.swift */,
+				FB56CD8F2EA87A38008F806D /* MOSendGiftView.swift */,
 				FB6C90872E7C1AB3004DF690 /* MOGiftListViewModel.swift */,
 			);
 			path = GiftListView;
@@ -9889,6 +9918,8 @@
 				A61509BE2B95C768004C87B0 /* MOCountDownCirleLayer */,
 				A6AEFCF12B973BF100F81201 /* MOComboSendGiftView.h */,
 				A6AEFCF22B973BF100F81201 /* MOComboSendGiftView.m */,
+				FB56CD952EA88326008F806D /* MOGiftComboView.swift */,
+				FB56CD982EA88333008F806D /* MOComboCountDownView.swift */,
 			);
 			path = MOComboSendGiftView;
 			sourceTree = "<group>";
@@ -10422,6 +10453,11 @@
 		A6CC14252CF84356001117FB /* Gift */ = {
 			isa = PBXGroup;
 			children = (
+				FB56CD9D2EA8D82F008F806D /* icon_gift_combo_lv_1.webp */,
+				FB56CD9E2EA8D82F008F806D /* icon_gift_selected_bg.webp */,
+				FB56CD9F2EA8D82F008F806D /* icon_gift_combo_lv_2.webp */,
+				FB56CDA02EA8D82F008F806D /* icon_gift_combo_lv_3.webp */,
+				FB56CDA12EA8D82F008F806D /* icon_gift_combo_lv_4.webp */,
 				3A9160D52DD9B8A40070C668 /* gif_diamond_drop.gif */,
 				3A9160D72DD9E41A0070C668 /* gif_send_red_packet.gif */,
 				A6A566D62D7166B400BCF3EC /* mo_download.gif */,
@@ -11603,6 +11639,11 @@
 				A608EBD12AE68AEB0092317D /* MOBlackListVC.xib in Resources */,
 				A618DC362AEA916F00976BB8 /* MOMyGuildInfoView.xib in Resources */,
 				A68B40E22B3188800027D881 /* MOPkStatusInfoView.xib in Resources */,
+				FB56CDA72EA8D82F008F806D /* icon_gift_combo_lv_3.webp in Resources */,
+				FB56CDA82EA8D82F008F806D /* icon_gift_selected_bg.webp in Resources */,
+				FB56CDA92EA8D82F008F806D /* icon_gift_combo_lv_4.webp in Resources */,
+				FB56CDAA2EA8D82F008F806D /* icon_gift_combo_lv_2.webp in Resources */,
+				FB56CDAB2EA8D82F008F806D /* icon_gift_combo_lv_1.webp in Resources */,
 				A63664962AF109D6002C0BFC /* MOFamilyMainVC.xib in Resources */,
 				A6C7395B2B4823430090F1F3 /* MOUserInfoMedalView.xib in Resources */,
 				FBA9B4F82E98DA9D00736FD2 /* icon_line_pk_start.webp in Resources */,
@@ -11742,7 +11783,6 @@
 				A6999C8E2C9063CE009AE37C /* MOSignInCollectionViewCell.xib in Resources */,
 				A6999C802C90235B009AE37C /* MOFirstRechargeTableViewCell.xib in Resources */,
 				A61944022AE52E8700D2878F /* MOModifyAvatarVC.xib in Resources */,
-				A6272BF72B0F6DF0006464EB /* MOGiftListView.xib in Resources */,
 				A67908EF2C0C6763001B73AE /* MOTaskBaseBtnView.xib in Resources */,
 				FBF5741F2E8255D5001B14D4 /* icon_line_match.webp in Resources */,
 				A6F8CE752C3564DC003475BE /* MODiaWinHistoryView.xib in Resources */,
@@ -11935,6 +11975,11 @@
 				FB06A0392E82B3FB00A3CD51 /* MOReportTableViewCell.xib in Resources */,
 				FB06A03A2E82B3FB00A3CD51 /* MOBlackListVC.xib in Resources */,
 				FB06A03F2E82B3FB00A3CD51 /* MOMyGuildInfoView.xib in Resources */,
+				FB56CDA22EA8D82F008F806D /* icon_gift_combo_lv_3.webp in Resources */,
+				FB56CDA32EA8D82F008F806D /* icon_gift_selected_bg.webp in Resources */,
+				FB56CDA42EA8D82F008F806D /* icon_gift_combo_lv_4.webp in Resources */,
+				FB56CDA52EA8D82F008F806D /* icon_gift_combo_lv_2.webp in Resources */,
+				FB56CDA62EA8D82F008F806D /* icon_gift_combo_lv_1.webp in Resources */,
 				FB06A0412E82B3FB00A3CD51 /* MOPkStatusInfoView.xib in Resources */,
 				FB06A0452E82B3FB00A3CD51 /* MOFamilyMainVC.xib in Resources */,
 				FB06A0462E82B3FB00A3CD51 /* MOUserInfoMedalView.xib in Resources */,
@@ -12068,7 +12113,6 @@
 				FB06A1012E82B3FB00A3CD51 /* MOSignInCollectionViewCell.xib in Resources */,
 				FB06A1022E82B3FB00A3CD51 /* MOFirstRechargeTableViewCell.xib in Resources */,
 				FB06A1032E82B3FB00A3CD51 /* MOModifyAvatarVC.xib in Resources */,
-				FB06A1072E82B3FB00A3CD51 /* MOGiftListView.xib in Resources */,
 				FB06A1092E82B3FB00A3CD51 /* MOTaskBaseBtnView.xib in Resources */,
 				FB06A10A2E82B3FB00A3CD51 /* (null) in Resources */,
 				FB06A10C2E82B3FB00A3CD51 /* MODiaWinHistoryView.xib in Resources */,
@@ -12701,6 +12745,8 @@
 				A6157AE32E26716200F8CD99 /* ByteBeautyManager.swift in Sources */,
 				A6CA1E2C2BCFAFEB00BFCD69 /* MORoomContriRankTopView.m in Sources */,
 				A608EBD02AE68AEB0092317D /* MOBlackListVC.m in Sources */,
+				FB56CD902EA87A38008F806D /* MOSendGiftView.swift in Sources */,
+				FB56CD992EA88333008F806D /* MOComboCountDownView.swift in Sources */,
 				A6AAFDDB2CEDECA9004C4D59 /* MOMinePlayCell.m in Sources */,
 				A6A3FDE62AFCC2CD0069D768 /* MOLocationHelper.m in Sources */,
 				A60963D72B5E954A009C9D4D /* MOFamilyTaskCell.m in Sources */,
@@ -12835,6 +12881,7 @@
 				A695B2EF2AE167C80072644D /* MODynamicBaseUrlAPI.m in Sources */,
 				A63664A82AF1226D002C0BFC /* MOFamilyStarListCell.m in Sources */,
 				FB9A8B722E8AAE0000488A61 /* MOLineBeanView.swift in Sources */,
+				FB56CD962EA88326008F806D /* MOGiftComboView.swift in Sources */,
 				FB9A8B732E8AAE0000488A61 /* MOLineCountTimeView.swift in Sources */,
 				FB9A8B742E8AAE0000488A61 /* MOLinePeerHostInfoView.swift in Sources */,
 				FB9A8B762E8AAE0000488A61 /* MOLineView.swift in Sources */,
@@ -12855,6 +12902,7 @@
 				3A8A05552E72D0A80081C87A /* MOPkRankSubView.m in Sources */,
 				A61A8CFE2D22881A00D71489 /* QGMP4Box.m in Sources */,
 				A68E81D42B173BC2001A6E79 /* MOMyEarningsTopView.m in Sources */,
+				FB56CD932EA87A3D008F806D /* MOGiftBottomMenuView.swift in Sources */,
 				A6E42D1B2C1C1ABB0010EA20 /* MORedSendConfigs.m in Sources */,
 				A61A8D102D22881A00D71489 /* QGVAPTextureLoader.m in Sources */,
 				A6A52BC72B15B3CD00D24378 /* LiveGiftShowCustom.m in Sources */,
@@ -13193,6 +13241,7 @@
 				A608807D2C3822F600C950E3 /* MOTicketChangeAlertView.m in Sources */,
 				FB012AD72E88D893000770B4 /* MONextVOLivePkLinkInviteVO.swift in Sources */,
 				A6673B322B416161002566A7 /* MORightToLeftBannerView.m in Sources */,
+				FB56CD8E2EA87A2F008F806D /* MOGiftPanelsView.swift in Sources */,
 				A6A52BCC2B15B3CD00D24378 /* LiveGiftListModel.m in Sources */,
 				A68E71E02B3309A700F6C623 /* MOSvgaBaseData.m in Sources */,
 				A63C044C2D27E49B00CCC79A /* MODownloadManager.m in Sources */,
@@ -13813,6 +13862,8 @@
 				FB069CB72E82B3FB00A3CD51 /* ByteBeautyManager.swift in Sources */,
 				FB069CB82E82B3FB00A3CD51 /* MORoomContriRankTopView.m in Sources */,
 				FB069CB92E82B3FB00A3CD51 /* MOBlackListVC.m in Sources */,
+				FB56CD912EA87A38008F806D /* MOSendGiftView.swift in Sources */,
+				FB56CD9A2EA88333008F806D /* MOComboCountDownView.swift in Sources */,
 				FB069CBB2E82B3FB00A3CD51 /* MOMinePlayCell.m in Sources */,
 				FB069CBC2E82B3FB00A3CD51 /* MOLocationHelper.m in Sources */,
 				FB069CBD2E82B3FB00A3CD51 /* MOFamilyTaskCell.m in Sources */,
@@ -13947,6 +13998,7 @@
 				FB069D462E82B3FB00A3CD51 /* MOGiftWishBase.m in Sources */,
 				FB069D472E82B3FB00A3CD51 /* MOFanTasksList.m in Sources */,
 				FB069D482E82B3FB00A3CD51 /* MOMineSetUpCell.m in Sources */,
+				FB56CD972EA88326008F806D /* MOGiftComboView.swift in Sources */,
 				FB069D492E82B3FB00A3CD51 /* MOEffect.m in Sources */,
 				FB069D4A2E82B3FB00A3CD51 /* MODynamicBaseUrlAPI.m in Sources */,
 				FB069D4B2E82B3FB00A3CD51 /* MOFamilyStarListCell.m in Sources */,
@@ -13967,6 +14019,7 @@
 				FB069D5D2E82B3FB00A3CD51 /* MOMyEarningsTopView.m in Sources */,
 				FB069D5E2E82B3FB00A3CD51 /* MORedSendConfigs.m in Sources */,
 				FB069D5F2E82B3FB00A3CD51 /* QGVAPTextureLoader.m in Sources */,
+				FB56CD942EA87A3D008F806D /* MOGiftBottomMenuView.swift in Sources */,
 				FB069D602E82B3FB00A3CD51 /* LiveGiftShowCustom.m in Sources */,
 				FB069D612E82B3FB00A3CD51 /* MORefundHand.swift in Sources */,
 				FB069D622E82B3FB00A3CD51 /* MODialogsData.m in Sources */,
@@ -14305,6 +14358,7 @@
 				FB069EB92E82B3FB00A3CD51 /* MORightToLeftBannerView.m in Sources */,
 				FB9A8B2C2E8A846400488A61 /* Int+Format.swift in Sources */,
 				FB069EBA2E82B3FB00A3CD51 /* LiveGiftListModel.m in Sources */,
+				FB56CD8D2EA87A2F008F806D /* MOGiftPanelsView.swift in Sources */,
 				FB069EBB2E82B3FB00A3CD51 /* MOSvgaBaseData.m in Sources */,
 				FB069EBC2E82B3FB00A3CD51 /* MODownloadManager.m in Sources */,
 				FB069EBD2E82B3FB00A3CD51 /* MORankBasedata.m in Sources */,
@@ -14867,7 +14921,7 @@
 					"-fprofile-instr-generate",
 					"-ld64",
 				);
-				PRODUCT_BUNDLE_IDENTIFIER = com.jiehe.mimo;
+				PRODUCT_BUNDLE_IDENTIFIER = com.jiehe.mimo.debugs;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
@@ -15022,7 +15076,7 @@
 					"-fprofile-instr-generate",
 					"-ld64",
 				);
-				PRODUCT_BUNDLE_IDENTIFIER = com.jiehe.mimo;
+				PRODUCT_BUNDLE_IDENTIFIER = com.jiehe.mimo.debugs;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
 				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";

+ 2 - 2
MiMoLive/MiMoLive.xcodeproj/xcshareddata/xcschemes/MiMoLive_Preview.xcscheme

@@ -52,12 +52,12 @@
       </BuildableProductRunnable>
       <AdditionalOptions>
          <AdditionalOption
-            key = "MallocStackLogging"
+            key = "PrefersMallocStackLoggingLite"
             value = ""
             isEnabled = "YES">
          </AdditionalOption>
          <AdditionalOption
-            key = "PrefersMallocStackLoggingLite"
+            key = "MallocStackLogging"
             value = ""
             isEnabled = "YES">
          </AdditionalOption>

+ 6 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/Contents.json

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

+ 21 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv1.imageset/Contents.json

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

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv1.imageset/icon_combo_lv1.png


+ 21 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv2.imageset/Contents.json

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

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv2.imageset/icon_combo_lv2.png


+ 21 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv3.imageset/Contents.json

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

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv3.imageset/icon_combo_lv3.png


+ 21 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv4.imageset/Contents.json

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

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Combo/icon_combo_lv4.imageset/icon_combo_lv4.png


+ 6 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/Contents.json

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

+ 21 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_1.imageset/Contents.json

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

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_1.imageset/进度0@2x.png


+ 21 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_2.imageset/Contents.json

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

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_2.imageset/ic_gift_show_combo_level_3@2x.png


+ 21 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_3.imageset/Contents.json

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

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_3.imageset/ic_gift_show_combo_level_4@2x.png


+ 21 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_4.imageset/Contents.json

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

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_4.imageset/ic_gift_show_combo_level_5@2x.png


+ 21 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_5.imageset/Contents.json

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

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_5.imageset/ic_gift_show_combo_level_6@2x.png


+ 21 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_bg.imageset/Contents.json

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

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/Gift/Level/ic_gift_show_combo_level_bg.imageset/ic_gift_show_combo_level_bg@2x.png


+ 21 - 0
MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_1.imageset/Contents.json

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

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_1.imageset/icon_base_gift_custom_view_bg@2x.png


+ 1 - 1
MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_2.imageset/Contents.json

@@ -5,7 +5,7 @@
       "scale" : "1x"
     },
     {
-      "filename" : "icon_base_gift_custom_view_bg_2@2x.png",
+      "filename" : "横幅1@2x.png",
       "idiom" : "universal",
       "scale" : "2x"
     },

BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_2.imageset/icon_base_gift_custom_view_bg_2@2x.png


BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_2.imageset/横幅1@2x.png


BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_3.imageset/icon_base_gift_custom_view_bg_3@2x.png


BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_4.imageset/icon_base_gift_custom_view_bg_4@2x.png


BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_5.imageset/icon_base_gift_custom_view_bg_5@2x.png


BIN
MiMoLive/MiMoLive/Assets.xcassets/Live/w_LiveGiftShow/Color/icon_base_gift_custom_view_bg_6.imageset/icon_base_gift_custom_view_bg_6@2x.png


+ 24 - 1
MiMoLive/MiMoLive/Classes/Live/MOShowLiveVC.m

@@ -822,6 +822,7 @@ MOLineViewModelDelegate, MOLinePKViewModelDelegate>
         giftInfo.id = fastGiveModel.giftId;
         giftInfo.giftCode = fastGiveModel.skinCode;
         giftInfo.giftPath = fastGiveModel.giftImage;
+        giftInfo.diamond = fastGiveModel.diamond;
         MOGiftInfo *giftSkin = [[MOSvgaSourceManage shareManager] getGiftInfoWithCode:fastGiveModel.skinCode];
         giftInfo.giftSource = giftSkin.giftSource;
         giftInfo.effectType = giftSkin.effectType;
@@ -834,6 +835,7 @@ MOLineViewModelDelegate, MOLinePKViewModelDelegate>
         giftInfo.id = followGiveModel.giftId;
         giftInfo.giftCode = followGiveModel.skinCode;
         giftInfo.giftPath = followGiveModel.giftImage;
+        giftInfo.diamond = followGiveModel.diamond;
         MOGiftInfo *giftSkin = [[MOSvgaSourceManage shareManager] getGiftInfoWithCode:followGiveModel.skinCode];
         giftInfo.giftSource = giftSkin.giftSource;
         giftInfo.effectType = giftSkin.effectType;
@@ -1901,7 +1903,7 @@ MOLineViewModelDelegate, MOLinePKViewModelDelegate>
 - (void)showGiftListViewAndIsSingleLinkMic:(BOOL)isSingleLinkMic{
     WEAKSELF
     if (!self.giftPanel) {
-        MOGiftListView *view = [MOGiftListView moGiftListView:self.liveViewModel.giftViewModel];
+        MOGiftListView *view = [[MOGiftListView alloc] initWith:self.liveViewModel.giftViewModel];
         
         view.topUpBtnBlock = ^{
             MOTopUpView *view = [MOTopUpView moTopUpView];
@@ -1932,6 +1934,7 @@ MOLineViewModelDelegate, MOLinePKViewModelDelegate>
             
             //显示点赞引导
             [weakSelf toJudgeTheClickActiveGuideView];
+            [weakSelf adjustLiveCanvasByGiftPanelState];
         };
         
         view.showUpBlock = ^{
@@ -1939,6 +1942,7 @@ MOLineViewModelDelegate, MOLinePKViewModelDelegate>
             
             //调整礼物浮窗的位置
             weakSelf.liveView.isNeedTopMove = YES;
+            [weakSelf adjustLiveCanvasByGiftPanelState];
         };
         
         typeof(view) __weak weakSelfView = view;
@@ -3288,6 +3292,12 @@ static int levetTemp = 5;
     self.liveView.roomStatusEntity = roomStatusEntity;
 }
 
+- (void)setViewType:(MOShowLiveViewType)viewType {
+    _viewType = viewType;
+    
+    [self adjustLiveCanvasByGiftPanelState];
+}
+
 #pragma mark - 获取房间信息
 //获取房间的声网token, 以及Rtm的token
 - (void)getRoomInfoWith:(MOLiveList *)roomData{
@@ -6445,6 +6455,19 @@ static int mainRTMJoinNum = 0;
     
 }
 
+- (void)adjustLiveCanvasByGiftPanelState {
+    BOOL giftPanelIsOnShow = self.liveView.showSendGiftView;
+    CGFloat offset = CGRectGetHeight(self.view.bounds) * 0.1;
+    if (!giftPanelIsOnShow || self.viewType != MOShowLiveViewTypeNormal) {
+        offset = 0;
+    }
+    
+    [self.liveView.canvasBottomOffset setConstant:offset];
+    [UIView animateWithDuration:0.2 animations:^{
+        [self.liveView layoutIfNeeded];
+    }];
+}
+
 #pragma mark - 手势事件
 - (void)viewTapGestureRecognizer:(UIGestureRecognizer *)recognize{
     if(self.msgSendView.inputTextView.isFirstResponder){

+ 90 - 21
MiMoLive/MiMoLive/Classes/Live/View/LiveGiftShowView/LiveGiftShowView.m

@@ -46,6 +46,13 @@ static CGFloat const kGiftNumberWidth = 15.0;
 
 @property (nonatomic, strong) UIImageView *xImageView;
 
+@property (nonatomic, strong) UIView *giftLvView;
+@property (nonatomic, strong) NSArray *levels;
+@property (nonatomic, assign) NSInteger curLv;
+@property (nonatomic, strong) UIImageView *lvBgImageView;
+@property (nonatomic, strong) UIView *lvCurContainer;
+@property (nonatomic, strong) UIImageView *lvCurImageView;
+
 @end
 
 @implementation LiveGiftShowView
@@ -55,6 +62,7 @@ static CGFloat const kGiftNumberWidth = 15.0;
 - (instancetype)initWithFrame:(CGRect)frame{
     self = [super initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, kViewWidth, kViewHeight)];
     if (self) {
+        self.levels = @[@(0), @(500), @(2000), @(5000), @(20000), @(50000)];
         self.liveTimerForSecond = 0;
         self.showTipStr = @"";
         [self setupContentContraints];
@@ -62,6 +70,7 @@ static CGFloat const kGiftNumberWidth = 15.0;
         self.kTimeOut = [MOSvgaSourceManage shareManager].giftShowAnimation;
         self.kRemoveAnimationTime = 0.2;
         self.kNumberAnimationTime = 0.1;
+        self.curLv = -1;
     }
     return self;
 }
@@ -277,28 +286,42 @@ static CGFloat const kGiftNumberWidth = 15.0;
     
     if(entity.user.vip.type != 0){
         //显示VIP特殊横幅
+        [self.giftLvView setHidden:YES];
         return;
     }
     else{
         CGFloat theCurrentGiftDiamond = self.model.currentNumber * giftInfo.diamond;
         
-        if(theCurrentGiftDiamond < 499){
-            [self.backIV setImage:[UIImage imageNamed:@"icon_base_gift_custom_view_bg"]];
-        }
-        else if (theCurrentGiftDiamond >= 500 && theCurrentGiftDiamond < 2000){
-            [self.backIV setImage:[UIImage imageNamed:@"icon_base_gift_custom_view_bg_2"]];
-        }
-        else if (theCurrentGiftDiamond >= 2000 && theCurrentGiftDiamond < 5000){
-            [self.backIV setImage:[UIImage imageNamed:@"icon_base_gift_custom_view_bg_3"]];
-        }
-        else if (theCurrentGiftDiamond >= 5000 && theCurrentGiftDiamond < 20000){
-            [self.backIV setImage:[UIImage imageNamed:@"icon_base_gift_custom_view_bg_4"]];
+        NSInteger level = 0;
+        for (NSInteger i = 0; i < self.levels.count; i ++) {
+            NSNumber *number = self.levels[i];
+            if (theCurrentGiftDiamond >= [number intValue]) {
+                level = i;
+            } else {
+                break;
+            }
         }
-        else if (theCurrentGiftDiamond >= 20000 && theCurrentGiftDiamond < 50000){
-            [self.backIV setImage:[UIImage imageNamed:@"icon_base_gift_custom_view_bg_5"]];
+        if (self.curLv != level) {
+            self.curLv = level;
+            [self.backIV setImage:[UIImage imageNamed:[NSString stringWithFormat:@"icon_base_gift_custom_view_bg_%ld", level + 1]]];
+            if (level + 1 < self.levels.count) {
+                [self.giftLvView setHidden:NO];
+                
+                NSString *imageName = [NSString stringWithFormat:@"ic_gift_show_combo_level_%ld", level + 1];
+                [self.lvCurImageView setImage:[UIImage imageNamed:imageName]];
+            } else {
+                [self.giftLvView setHidden:YES];
+            }
         }
-        else{
-            [self.backIV setImage:[UIImage imageNamed:@"icon_base_gift_custom_view_bg_6"]];
+        if (level + 1 < self.levels.count) {
+            NSInteger nextCount = [self.levels[level + 1] intValue];
+            NSInteger curCount = [self.levels[level] intValue];
+            // 24 为图片上下透明空间
+            CGFloat imageHeight = self.lvBgImageView.image.size.height;
+            CGFloat height = (imageHeight - 24) * (theCurrentGiftDiamond - curCount) / (nextCount - curCount);
+            [self.lvCurContainer mas_updateConstraints:^(MASConstraintMaker *make) {
+                make.height.equalTo(@(12 + height));
+            }];
         }
     }
 }
@@ -526,7 +549,7 @@ static CGFloat const kGiftNumberWidth = 15.0;
         iconIvLeft = 16.0;
         iconIvWidthAndHeight = 30.0;
         
-        giftIvRight = - 5 + (bgWidth - kViewWidth) + 10.0;
+        giftIvRight = - 7 + (bgWidth - kViewWidth);
         giftIvWidthAndHeight = 50.0;
     }
     
@@ -614,13 +637,30 @@ static CGFloat const kGiftNumberWidth = 15.0;
     }];
     self.vipBgImgView.hidden = YES;
     
-    CGFloat height = kScaleWidth(36.0);
-    CGFloat width = height * 333.0 / 63.0;
     [self.backIV mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.left.equalTo(self).offset(12.0);
+        make.left.equalTo(self).offset(4);
         make.centerY.equalTo(self);
-        make.height.equalTo(@(height));
-        make.width.equalTo(@(width));
+    }];
+    
+    [self.backIV addSubview:self.giftLvView];
+    [self.giftLvView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.leading.top.equalTo(self.backIV);
+    }];
+    
+    [self.giftLvView addSubview:self.lvBgImageView];
+    [self.lvBgImageView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.edges.equalTo(self.giftLvView);
+    }];
+    
+    [self.giftLvView addSubview:self.lvCurContainer];
+    [self.lvCurContainer mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.leading.bottom.equalTo(self.lvBgImageView);
+        make.height.equalTo(@(0));
+    }];
+    
+    [self.lvCurContainer addSubview:self.lvCurImageView];
+    [self.lvCurImageView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.leading.bottom.trailing.equalTo(self.lvCurContainer);
     }];
     
     [self.iconIV mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -828,6 +868,35 @@ static CGFloat const kGiftNumberWidth = 15.0;
     return _svgaPlayer;
 }
 
+- (UIView *)giftLvView {
+    if (_giftLvView) return _giftLvView;
+    _giftLvView = [UIView new];
+    return _giftLvView;
+}
+
+- (UIImageView *)lvBgImageView {
+    if (_lvBgImageView) return _lvBgImageView;
+    
+    _lvBgImageView = [[UIImageView alloc] init];
+    _lvBgImageView.image = [UIImage imageNamed:@"ic_gift_show_combo_level_bg"];
+    return _lvBgImageView;
+}
+
+- (UIImageView *)lvCurImageView {
+    if (_lvCurImageView) return _lvCurImageView;
+    
+    _lvCurImageView = [[UIImageView alloc] init];
+    return _lvCurImageView;
+}
+
+- (UIView *)lvCurContainer {
+    if (_lvCurContainer) return _lvCurContainer;
+    
+    _lvCurContainer = [[UIView alloc] init];
+    _lvCurContainer.clipsToBounds = true;
+    return _lvCurContainer;
+}
+
 - (void)animationToRemove {
     
     if (self.liveGiftShowViewTimeOut) {

+ 435 - 0
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftBottomMenuView.swift

@@ -0,0 +1,435 @@
+//
+//  MOGiftBottomMenuView.swift
+//  MiMoLive
+//
+//  Created by OneeChan on 2025/9/5.
+//
+
+import Foundation
+import UIKit
+import SnapKit
+
+@objc protocol MOGiftBottomMenuViewDelegate {
+    // Recharge
+    func giftBottomMenuViewClickRecharge(view: MOGiftBottomMenuView)
+    
+    // Gift
+    func giftBottomMenuViewDidSelectNum(view: MOGiftBottomMenuView, num: Int, isCustom: Bool)
+    func giftBottomMenuViewClickSendGift(view: MOGiftBottomMenuView)
+    func giftBottomMenuViewClickCustom(view: MOGiftBottomMenuView)
+    
+    // Bag
+    func giftBottomMenuViewClickSendBag(view: MOGiftBottomMenuView)
+    
+    // Props
+    func giftBottomMenuViewClickUse(view: MOGiftBottomMenuView)
+}
+
+@objcMembers
+class MOGiftBottomMenuView: UIView {
+    weak var delegate: MOGiftBottomMenuViewDelegate?
+    
+    @objc enum GiftBottomMenuType: Int {
+        case none
+        case gift
+        case bag
+        case props
+    }
+    private var curType: GiftBottomMenuType = .gift
+    
+    private var giftView: UIView?
+    private var diamondLabel: UILabel?
+    private var sendGiftView: MOSendGiftView?
+    
+    private var bagView: UIView?
+    
+    private var propView: UIView?
+    private var usePropButon: MOGiftGradientButton?
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        
+        setupViews()
+        updateViewType(curType)
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    func updateSelectItem(_ item: Any?) {
+        guard let item else {
+            updateViewType(.none)
+            return
+        }
+        if let item = item as? MOGiftlist {
+            if item.isBag {
+                updateViewType(.bag)
+            } else {
+                enableGiftSendView(true)
+                updateViewType(.gift)
+            }
+        } else if let item = item as? MOShopList {
+            updateViewType(.props)
+            if item.used {
+                usePropButon?.title = NSLocalizedString("mimo_2_gift_list_prpps_a_use", comment: "")
+            } else {
+                usePropButon?.title = NSLocalizedString("mimo_2_gift_list_prpps_use", comment: "")
+            }
+        } else {
+            updateViewType(.none)
+        }
+    }
+    
+    func updateViewType(_ type: GiftBottomMenuType) {
+        curType = type
+
+        let showView: UIView? = switch type {
+        case .none:
+            nil
+        case .gift:
+            self.giftView
+        case .bag:
+            self.bagView
+        case .props:
+            self.propView
+        }
+        let showings = [self.giftView, self.bagView, self.propView]
+            .filter { $0?.isHidden == false && $0 != showView }
+        showings.forEach { $0?.isHidden = true }
+        
+        // 已经在展示,不需要调整
+        if showView?.isHidden == false { return }
+        showView?.isHidden = false
+    }
+    
+    func updateUserDiamond(_ count: Double) {
+        var zuanNumStr = ""
+        if count < 10_000_000 { // 1千万以下
+            zuanNumStr = String(format: "%.f", count)
+        } else if count < 1_000_000_000 { // 1千万到10亿
+            let firstTwoDigits = Int(count / 10_000)
+            zuanNumStr = String(
+                format: "%ld.%02ldM",
+                firstTwoDigits / 100,
+                firstTwoDigits % 100
+            )
+        } else { // 10亿以上
+            let firstTwoDigits = Int(count / 10_000_000)
+            zuanNumStr = String(
+                format: "%ld.%02ldB",
+                firstTwoDigits / 100,
+                firstTwoDigits % 100
+            )
+        }
+        diamondLabel?.text = "\(zuanNumStr)"
+    }
+    
+    func selectGiftNum(_ num: Int) {
+        sendGiftView?.updateGiftNum(num)
+    }
+    
+    func curGiftNum() -> Int {
+        sendGiftView?.curGiftNum() ?? 1
+    }
+    
+    func enableGiftSendView(_ enable: Bool) {
+        sendGiftView?.isHidden = !enable
+    }
+    
+    func enableGiftNum(_ enable: Bool) {
+        sendGiftView?.enableGiftNum(enable)
+    }
+    
+    func updateCustomNum(_ num: Int) {
+        sendGiftView?.updateCustomNum(num)
+    }
+}
+
+// MARK: Private
+extension MOGiftBottomMenuView {
+}
+
+// MARK: UI 事件
+extension MOGiftBottomMenuView {
+    @objc func handleRechargeButtonClick() {
+        delegate?.giftBottomMenuViewClickRecharge(view: self)
+    }
+    
+    @objc func handleSendBagButtonClick() {
+        delegate?.giftBottomMenuViewClickSendBag(view: self)
+    }
+    
+    @objc func handleUsePropsButtonClick() {
+        delegate?.giftBottomMenuViewClickUse(view: self)
+    }
+}
+
+// MARK: MOSendGiftDelegate
+extension MOGiftBottomMenuView: MOSendGiftViewDelegate {
+    func sendGiftViewDidSelectNum(
+        view: MOSendGiftView,
+        num: Int,
+        isCustom: Bool
+    ) {
+        delegate?
+            .giftBottomMenuViewDidSelectNum(
+                view: self,
+                num: num,
+                isCustom: isCustom
+            )
+    }
+    
+    func sendGiftViewClickSend(view: MOSendGiftView) {
+        delegate?.giftBottomMenuViewClickSendGift(view: self)
+    }
+    
+    func sendGiftViewClickCustom(view: MOSendGiftView) {
+        delegate?.giftBottomMenuViewClickCustom(view: self)
+    }
+}
+
+// MARK: UI 视图构建
+extension MOGiftBottomMenuView {
+    // UI 组装
+    private func setupViews() {
+        let giftView = buildGiftMenuView()
+        giftView.isHidden = true
+        addSubview(giftView)
+        giftView.snp.makeConstraints { make in
+            make.leading.trailing.bottom.equalToSuperview()
+            make.top.bottom.equalToSuperview()
+        }
+        self.giftView = giftView
+        
+        let bagView = buildBagMenuView()
+        bagView.isHidden = true
+        addSubview(bagView)
+        bagView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        self.bagView = bagView
+        
+        let propsView = buildPropsMenuView()
+        propsView.isHidden = true
+        addSubview(propsView)
+        propsView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        self.propView = propsView
+    }
+    
+    // Gift Menu
+    private func buildGiftMenuView() -> UIView {
+        let container = UIView()
+        
+        let diamondView = buildDiamondView()
+        container.addSubview(diamondView)
+        diamondView.snp.makeConstraints { make in
+            make.top.bottom.equalToSuperview()
+            make.leading.equalToSuperview().offset(12)
+        }
+        
+        let sendView = MOSendGiftView()
+        sendView.delegate = self
+        container.addSubview(sendView)
+        sendView.snp.makeConstraints { make in
+            make.top.bottom.equalToSuperview()
+            make.trailing.equalToSuperview().offset(-12)
+            make.leading.equalTo(diamondView.snp.trailing).offset(8)
+        }
+        self.sendGiftView = sendView
+        
+        return container
+    }
+    
+    // 钻石界面
+    private func buildDiamondView() -> UIView {
+        let container = UIView()
+        container.layer.cornerRadius = 10
+        container.backgroundColor = .white.withAlphaComponent(0.15)
+        
+        let diamond = UIImageView()
+        diamond.image = UIImage(named: "icon_gift_zuan")
+        container.addSubview(diamond)
+        diamond.snp.makeConstraints { make in
+            make.top.equalToSuperview().offset(7)
+            make.bottom.equalToSuperview().offset(-7)
+            make.leading.equalToSuperview().offset(10)
+            make.width.height.equalTo(14)
+        }
+        
+        let label = UILabel()
+        label.textColor = .white
+        label.font = MOTextTools.mediumFont(12.0)
+        container.addSubview(label)
+        label.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.leading.equalTo(diamond.snp.trailing).offset(3)
+        }
+        self.diamondLabel = label
+        
+        let arrow = UIImageView()
+        arrow.image = UIImage(named: "icon_arrow_right_gray")
+        container.addSubview(arrow)
+        arrow.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.leading.equalTo(label.snp.trailing).offset(5)
+            make.trailing.equalToSuperview().offset(-10)
+        }
+        
+        let button = UIButton()
+        button
+            .addTarget(
+                self,
+                action: #selector(handleRechargeButtonClick),
+                for: .touchUpInside
+            )
+        container.addSubview(button)
+        button.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+        return container
+    }
+    
+    // Bag View
+    private func buildBagMenuView() -> UIView {
+        let container = UIView()
+        
+        let send = MOGiftGradientButton()
+        send
+            .addTarget(
+                self,
+                action: #selector(handleSendBagButtonClick),
+                for: .touchUpInside
+            )
+        send.title = "Send"
+        container.addSubview(send)
+        send.snp.makeConstraints { make in
+            make.top.bottom.equalToSuperview()
+            make.trailing.equalToSuperview().offset(-12)
+        }
+        
+        return container
+    }
+    
+    // Props View
+    private func buildPropsMenuView() -> UIView {
+        let container = UIView()
+        
+        let use = MOGiftGradientButton()
+        use.addTarget(
+            self,
+            action: #selector(handleUsePropsButtonClick),
+            for: .touchUpInside
+        )
+        use.title = "Use"
+        container.addSubview(use)
+        use.snp.makeConstraints { make in
+            make.top.bottom.equalToSuperview()
+            make.trailing.equalToSuperview().offset(-12)
+        }
+        self.usePropButon = use
+        
+        return container
+    }
+}
+
+private class MOGiftGradientButton: UIButton {
+    var title = "" {
+        didSet {
+            textLabel.text = title
+        }
+    }
+    private let gradientLayer = CAGradientLayer()
+    private let textLabel = UILabel()
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        
+        setupViews()
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    override func layoutSubviews() {
+        super.layoutSubviews()
+        
+        CATransaction.begin()
+        CATransaction.setDisableActions(true)
+        layer.sublayers?.forEach({ layer in
+            if layer is CAGradientLayer {
+                layer.frame = bounds
+            }
+        })
+        CATransaction.commit()
+    }
+    
+    private func setupViews() {
+        let graLayer = CAGradientLayer()
+        graLayer.startPoint = CGPoint(x: 0, y: 0.5)
+        graLayer.endPoint = CGPoint(x: 1, y: 0.5)
+        graLayer.colors = [
+            UIColor(
+                red: 255/255.0,
+                green: 77/255.0,
+                blue: 166/255.0,
+                alpha: 1
+            ).cgColor,
+            UIColor(
+                red: 67/255.0,
+                green: 99/255.0,
+                blue: 255/255.0,
+                alpha: 1
+            ).cgColor
+        ];
+        graLayer.locations = [0, 1.0]
+        layer.insertSublayer(graLayer, at: 0)
+        layer.cornerRadius = 10
+        layer.masksToBounds = true
+        
+        textLabel.text = "Use"
+        textLabel.font = MOTextTools.mediumFont(12.0)
+        textLabel.textColor = .white
+        addSubview(textLabel)
+        textLabel.snp.makeConstraints { make in
+            make.edges
+                .equalToSuperview()
+                .inset(UIEdgeInsets(top: 6, left: 16, bottom: 6, right: 16))
+        }
+    }
+}
+
+//#if DEBUG
+//import SwiftUI
+//
+//struct MOGiftBottomMenuViewPreview: UIViewRepresentable {
+//    func makeUIView(context: Context) -> some UIView {
+//        let container = UIView()
+//        container.backgroundColor = .black
+//
+//        let view = MOGiftBottomMenuView()
+//        container.addSubview(view)
+//        view.snp.makeConstraints { make in
+//            make.centerY.equalToSuperview()
+//            make.leading.trailing.equalToSuperview()
+//        }
+//
+//        return container
+//    }
+//
+//    func updateUIView(_ uiView: UIViewType, context: Context) {
+//
+//    }
+//}
+//
+//#Preview(body: {
+//    VStack {
+//        MOGiftBottomMenuViewPreview()
+//    }
+//})
+//
+//#endif

+ 3 - 9
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftCollectionView.h

@@ -10,22 +10,16 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
+@class MOGiftListViewModel;
+
 @interface MOGiftCollectionView : UIView<JXCategoryListContentViewDelegate>
 
 /** 界面类型  (礼物类型,(1=hot(热门) ,2=SL(幸运),3=fans(粉丝团),4=vip(贵族),5=等级(lv),6=funny(有趣),7=luxury(奢华))*/
 @property (nonatomic, assign) NSInteger type;
 
-@property (nonatomic, copy) void(^selectGiftBlock)(MOGiftlist *selectGiftModel, NSInteger giftType);
-/** comboView 倒计时结束回调*/
-@property (nonatomic, copy) void (^comboCountdownBlock)(void);
-
-@property (nonatomic, strong, readonly) UICollectionView *collectionView;
-@property (nonatomic, copy) void(^reloadCollectionViewBlock)(MOGiftCollectionView *giftView);
-
-@property (nonatomic, assign) NSInteger giftNum;//当前礼物选中的送礼数量
 @property (nonatomic, strong) MOEffect *selectSkin;//当前选中的皮肤
 @property (nonatomic, strong) NSIndexPath *selectIndexPath;//选中的Cell
-@property (nonatomic, copy) void(^selectCellBlock)(MOGiftlist *selectGiftMode);//选中Cell的回调
+@property (nonatomic, copy) void(^selectCellBlock)(MOGiftlist *selectGiftMode, NSInteger giftType);//选中Cell的回调
 
 @property (nonatomic, copy) void(^theFirstGiftBlock)(void);//第一个礼物锁定态
 

+ 24 - 77
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftCollectionView.m

@@ -40,8 +40,6 @@ MOGiftListViewModelDelegate>
 }
 
 - (void)setupUI{
-    self.giftNum = 1;
-    
     [self addSubview:self.collectionView];
     [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
         make.edges.equalTo(self);
@@ -60,6 +58,23 @@ MOGiftListViewModelDelegate>
     }];
 }
 
+- (void)handleCellClick:(NSIndexPath *)indexPath {
+    NSArray *giftList = [self.listViewModel giftListFor:self.type];
+    if (self.selectIndexPath == indexPath) return;
+    if (indexPath.row >= giftList.count) return;
+    
+    MOGiftlist *modle = giftList[indexPath.row];
+    
+    if (modle.lock) return;
+    for (MOGiftlist *giftModel in giftList) {
+        giftModel.isSelect = NO;
+    }
+    modle.isSelect = YES;
+    
+    self.selectIndexPath = indexPath;
+    self.selectCellBlock(modle, self.type);
+}
+
 #pragma mark - JXCategoryListContentViewDelegate
 - (void)listWillAppear {
     self.isOnShow = YES;
@@ -77,17 +92,8 @@ MOGiftListViewModelDelegate>
         }
         
         [self toChangeTheFirstChooseWith:giftList];//默认选中第一个
-        
         [self toSelectTheHitGift:giftList];//跳转Hit礼物
-        
         [self.collectionView reloadData];
-        
-        WEAKSELF
-        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-            if (self.reloadCollectionViewBlock) {
-                self.reloadCollectionViewBlock(self);
-            }
-        });
     }
 }
 
@@ -127,7 +133,7 @@ MOGiftListViewModelDelegate>
     if(!giftModel.lock){
         giftModel.isSelect = YES;
         self.selectIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];//选中第一个
-        self.selectCellBlock ? self.selectCellBlock(giftModel) : nil;
+        self.selectCellBlock(giftModel, self.type);
     }
     else{
         self.theFirstGiftBlock ? self.theFirstGiftBlock() : nil;
@@ -146,7 +152,7 @@ MOGiftListViewModelDelegate>
                 object.isSelect = YES;
                 
                 self.selectIndexPath = [NSIndexPath indexPathForRow:theIndex inSection:0];//选中第一个
-                self.selectCellBlock ? self.selectCellBlock(object) : nil;
+                self.selectCellBlock(object, self.type);
                 [self.collectionView scrollToItemAtIndexPath:self.selectIndexPath atScrollPosition:UICollectionViewScrollPositionTop animated:NO];
                 [MOSvgaSourceManage shareManager].hitGiftModel = nil;
                 
@@ -178,11 +184,6 @@ MOGiftListViewModelDelegate>
     }
     
     [self.collectionView reloadData];
-    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
-        if (self.reloadCollectionViewBlock) {
-            self.reloadCollectionViewBlock(self);
-        }
-    });
     
     self.noMoreDataView.isHaveData = list.count > 0 ? YES : NO;
     
@@ -204,68 +205,15 @@ MOGiftListViewModelDelegate>
     MOGiftlist *modle = giftList[indexPath.row];
     MOGiftItemCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:MOGiftItemCell_ID forIndexPath:indexPath];
     cell.isBag = false;
-    cell.giftNum = self.giftNum;
     cell.listModel = modle;
     cell.selectSkin = self.selectSkin;
-    cell.comboClickBlock = ^(MOGiftlist * _Nonnull cellModel) {
-        NSMutableArray *tempIndexArr = [NSMutableArray array];
-        for (MOGiftlist *giftModel in giftList) {
-            
-            if([cellModel.giftInfo.id isEqualToString:giftModel.giftInfo.id]){
-                giftModel.isSelect = YES;
-            }
-            else{
-                giftModel.isSelect = NO;
-            }
-            
-        }
-        
-        //除了点击的Cell不刷新, 其他视图内可见Cell都刷新
-        for (NSIndexPath *visibleIndexPath in collectionView.indexPathsForVisibleItems) {
-            if (![visibleIndexPath isEqual:indexPath]) {
-                [tempIndexArr addObject:visibleIndexPath];
-            }
-        }
-        
-        //消除刷新阴影
-        if(tempIndexArr.count > 0){
-            [CATransaction setDisableActions:YES];
-            [collectionView reloadItemsAtIndexPaths:tempIndexArr];
-            [CATransaction commit];
-        }
-        
-        weakSelf.selectGiftBlock ? weakSelf.selectGiftBlock(cellModel, weakSelf.type) : nil;
-    };
-    
-    cell.comboCountdownBlock = ^{
-        weakSelf.comboCountdownBlock ? weakSelf.comboCountdownBlock() : nil;
-    };
     
     return cell;
 }
 
 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
-    NSArray *giftList = [self.listViewModel giftListFor:self.type];
     [collectionView deselectItemAtIndexPath:indexPath animated:YES];
-    
-    MOGiftlist *modle = giftList[indexPath.row];
-    
-    if(modle.lock || modle.isSelect){
-        return;
-    }
-    
-    for (MOGiftlist *giftModel in giftList) {
-        giftModel.isSelect = NO;
-    }
-    
-    
-    modle.isSelect = YES;
-    
-    self.selectSkin = nil;
-    self.giftNum = 1;
-    
-    self.selectIndexPath = indexPath;
-    self.selectCellBlock ? self.selectCellBlock(modle) : nil;
+    [self handleCellClick:indexPath];
     
     [self.collectionView reloadData];
 }
@@ -274,7 +222,6 @@ MOGiftListViewModelDelegate>
     if(self.selectIndexPath){
         MOGiftItemCell *cell = (MOGiftItemCell *)[self.collectionView cellForItemAtIndexPath:self.selectIndexPath];
         if(cell){
-            cell.giftNum = self.giftNum;
             cell.selectSkin = self.selectSkin;
             [cell updataCellShowData];
         }
@@ -291,11 +238,11 @@ MOGiftListViewModelDelegate>
     {
         UICollectionViewFlowLayout *flow = [[UICollectionViewFlowLayout alloc] init];
         
-        CGFloat width = (SCREENWIDTH - 3.0 * 3) / 4.0;
-        CGFloat height = width + 10.0;
+        CGFloat width = SCREENWIDTH / 4.0;
+        CGFloat height = 104;
         flow.itemSize = CGSizeMake(width, height);
-        flow.minimumLineSpacing = 1.0;//行间距
-        flow.minimumInteritemSpacing = 3.0;//列间距
+        flow.minimumLineSpacing = 4.0;//行间距
+        flow.minimumInteritemSpacing = 0.0;//列间距
         flow.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
         _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, SCREENWIDTH, 100) collectionViewLayout:flow];
         _collectionView.backgroundColor = [UIColor clearColor];

+ 0 - 15
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftItemCell.h

@@ -9,7 +9,6 @@
 
 #import <UIKit/UIKit.h>
 #import "MOGiftDataModels.h"
-#import "MOComboView.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
@@ -29,24 +28,10 @@ NS_ASSUME_NONNULL_BEGIN
 
 @property (nonatomic, strong) UILabel *numLab;//背包礼物数量
 
-/** 选中时, 钻石位置 */
-@property (nonatomic, strong) BigBtn *selectZuanNumBtn;
-@property (nonatomic, strong) UIImageView *selectImg;
-@property (nonatomic, strong) UIButton *selectBtn;
-
 @property (nonatomic, strong) MOGiftlist *listModel;
 /** 是否背包 */
 @property (nonatomic, assign) BOOL isBag;
 
-@property (nonatomic, strong) UIButton *baseBtn;
-@property (nonatomic, strong) MOComboView *comboView;
-
-@property (nonatomic, copy) void (^comboClickBlock)(MOGiftlist *cellModel);
-
-/** comboView 倒计时结束回调*/
-@property (nonatomic, copy) void (^comboCountdownBlock)(void);
-
-@property (nonatomic, assign) NSInteger giftNum;//当前礼物选中的送礼数量
 @property (nonatomic, strong) MOEffect *selectSkin;//当前选中的皮肤
 
 

+ 61 - 260
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftItemCell.m

@@ -39,47 +39,41 @@
     self.bgView.layer.cornerRadius = 5.0;
     self.bgView.layer.masksToBounds = YES;
     
-    CGFloat width = (SCREENWIDTH - 3.0 * 3) / 4.0;
-    
     [self.bgView addSubview:self.bgImgView];
     [self.bgImgView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.bottom.equalTo(self.bgView);
-        make.left.equalTo(self.bgView).offset(6);
-        make.right.equalTo(self.bgView).offset(-6.0);
-        make.height.equalTo(@(width));
+        make.top.bottom.centerX.equalTo(self.bgView);
+        make.width.equalTo(@(94));
     }];
     self.bgImgView.hidden = YES;
     
-    [self.bgView addSubview:self.zuanNumBtn];
-    [self.zuanNumBtn mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.bottom.equalTo(self.bgView).offset(-10.0);
-        make.left.equalTo(self.bgView).offset(10.0);
-        make.right.equalTo(self.bgView).offset(-10.0);
-        make.height.equalTo(@12.0);
+    [self.bgView addSubview:self.iconImgView];
+    [self.iconImgView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.centerY.equalTo(self.bgView.mas_top).offset(32);
+        make.height.width.equalTo(@56);
+        make.centerX.equalTo(self.bgView);
     }];
     
     [self.bgView addSubview:self.titleLab];
     [self.titleLab mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.bottom.equalTo(self.zuanNumBtn.mas_top).offset(-3.0);
-        make.left.equalTo(self.bgView).offset(10.0);
-        make.right.equalTo(self.bgView).offset(-10.0);
-        make.height.equalTo(@12.0);
+        make.top.equalTo(self.iconImgView.mas_bottom);
+        make.leading.equalTo(self.bgView).offset(10.0);
+        make.trailing.equalTo(self.bgView).offset(-10.0);
     }];
     
     [self.bgView addSubview:self.suoTitleBtn];
     [self.suoTitleBtn mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.left.equalTo(self.bgView).offset(10.0);
-        make.right.equalTo(self.bgView).offset(-10.0);
-        make.height.equalTo(@12.0);
-        make.centerY.equalTo(self.titleLab.mas_centerY);
+        make.top.equalTo(self.iconImgView.mas_bottom);
+        make.leading.equalTo(self.bgView).offset(10.0);
+        make.trailing.equalTo(self.bgView).offset(-10.0);
     }];
     self.suoTitleBtn.hidden = YES;
     
-    [self.bgView addSubview:self.iconImgView];
-    [self.iconImgView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.top.equalTo(self.bgView).offset(12.0);
-        make.height.width.equalTo(@48.0);
-        make.centerX.equalTo(self.bgView.mas_centerX);
+    [self.bgView addSubview:self.zuanNumBtn];
+    [self.zuanNumBtn mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.top.equalTo(self.titleLab.mas_bottom).offset(2);
+        make.top.greaterThanOrEqualTo(self.suoTitleBtn.mas_bottom).offset(2);
+        make.leading.equalTo(self.bgView).offset(10.0);
+        make.trailing.equalTo(self.bgView).offset(-10.0);
     }];
     
     [self.bgView addSubview:self.titleGiftView];
@@ -89,37 +83,14 @@
         make.size.mas_equalTo(CGSizeMake(kScaleWidth(22.0), kScaleWidth(22.0)));
     }];
     
-    [self.bgView addSubview:self.selectZuanNumBtn];
-    [self.selectZuanNumBtn mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.top.equalTo(self.iconImgView.mas_bottom).offset(6.0);
-        make.left.equalTo(self.bgView).offset(10.0);
-        make.right.equalTo(self.bgView).offset(-10.0);
-        make.height.equalTo(@12.0);
-    }];
-    self.selectZuanNumBtn.hidden = YES;
-    
     [self.bgView addSubview:self.luckyImgView];
     [self.luckyImgView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.top.equalTo(self.iconImgView.mas_top).offset(0.0);
-        make.left.equalTo(self.bgView).offset(10.0);
-        make.width.equalTo(@19.5);
-        make.height.equalTo(@18.0);
-    }];
-    
-    [self.bgView addSubview:self.selectImg];
-    [self.selectImg mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.edges.equalTo(self.bgView);
+        make.top.equalTo(self.bgImgView.mas_top).offset(4.0);
+        make.leading.equalTo(self.bgView).offset(4.0);
+        make.height.equalTo(@10.0);
+        make.width.equalTo(@10.0);
     }];
     
-    [self.bgView addSubview:self.selectBtn];
-    [self.selectBtn mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.bottom.equalTo(self.bgView).offset(-3.0);
-        make.left.equalTo(self.bgView).offset(9.0);
-        make.right.equalTo(self.bgView).offset(-9.0);
-        make.height.equalTo(@24.0);
-    }];
-    self.selectBtn.hidden = YES;
-    
     [self.bgView addSubview:self.numLab];
     [self.numLab mas_makeConstraints:^(MASConstraintMaker *make) {
         make.right.equalTo(self.bgView.mas_right).offset(-8);
@@ -128,39 +99,11 @@
         make.width.equalTo(@12.0);
     }];
     self.numLab.hidden = YES;
-    
-    [self.bgView addSubview:self.comboView];
-    [self.comboView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.centerX.equalTo(self.iconImgView);
-        make.centerY.equalTo(self.iconImgView).offset(10);
-        make.width.height.equalTo(@60.0);
-    }];
-    self.comboView.hidden = YES;
-    
-    [self.bgView addSubview:self.baseBtn];
-    [self.baseBtn mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.edges.equalTo(self.bgView);
-    }];
 }
 
 - (void)setListModel:(MOGiftlist *)listModel{
     _listModel = listModel;
     
-    if(listModel.lock){
-        self.selectImg.hidden = YES;
-        self.selectImg.backgroundColor = [MOTools colorWithHexString:@"#333333" alpha:0.6];
-        [self.selectImg setImage:[UIImage imageNamed:@"icon_live_veri_suo"]];
-        self.selectImg.contentMode = UIViewContentModeCenter;
-        self.selectBtn.hidden = YES;
-    }
-    else
-    {
-        self.selectImg.hidden = YES;
-        self.selectImg.backgroundColor = [UIColor clearColor];
-        [self.selectImg setImage:[UIImage imageNamed:@"icon_gift_handsel"]];
-        self.selectImg.contentMode = UIViewContentModeScaleToFill;
-    }
-    
     if(!self.isBag){
         //通常礼物
         CGSize thumbnailSize = CGSizeMake(200, 200);
@@ -179,10 +122,7 @@
         }
         
         [self.zuanNumBtn setTitle:[NSString stringWithFormat:@"%.f",listModel.giftInfo.diamond] forState:UIControlStateNormal];
-        [self.zuanNumBtn setImage:[UIImage imageNamed:@"icon_gift_zuan_20"] forState:UIControlStateNormal];
-        
-        [self.selectZuanNumBtn setImage:[UIImage imageNamed:@"icon_gift_zuan_20"] forState:UIControlStateNormal];
-        [self.selectZuanNumBtn setTitle:[NSString stringWithFormat:@"%.f",listModel.giftInfo.diamond] forState:UIControlStateNormal];
+        [self.zuanNumBtn setImage:[UIImage imageNamed:@"icon_diamond_gift_panel"] forState:UIControlStateNormal];
 
         self.zuanNumBtn.hidden = NO;
         self.numLab.hidden = YES;
@@ -221,34 +161,45 @@
         
         if(self.isBag){
             if(listModel.newGet){
-                [self.luckyImgView setImage:[UIImage imageNamed:@"v_2_prop_new"]];
+                UIImage *image = [UIImage imageNamed:@"v_2_prop_new"];
+                [self.luckyImgView setImage:image];
+                [self.luckyImgView mas_updateConstraints:^(MASConstraintMaker *make) {
+                    make.width.equalTo(@(image.size.width * 10 / image.size.height));
+                }];
             }
             else{
-                [self.luckyImgView sd_setImageWithURL:[NSURL URLWithString:listModel.giftInfo.giftCornerMark.data]];
+                __weak typeof(self) weakSelf = self;
+                [self.luckyImgView sd_setImageWithURL:[NSURL URLWithString:listModel.giftInfo.giftCornerMark.data] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
+                    __strong typeof(self) strongSelf = weakSelf; if (!strongSelf || !image) return;
+                    [strongSelf.luckyImgView mas_updateConstraints:^(MASConstraintMaker *make) {
+                        make.width.equalTo(@(image.size.width * 10 / image.size.height));
+                    }];
+                }];
             }
         }
         else{
-            [self.luckyImgView sd_setImageWithURL:[NSURL URLWithString:listModel.giftInfo.giftCornerMark.data]];
+            __weak typeof(self) weakSelf = self;
+            [self.luckyImgView sd_setImageWithURL:[NSURL URLWithString:listModel.giftInfo.giftCornerMark.data] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
+                __strong typeof(self) strongSelf = weakSelf; if (!strongSelf || !image) return;
+                [strongSelf.luckyImgView mas_updateConstraints:^(MASConstraintMaker *make) {
+                    make.width.equalTo(@(image.size.width * 10 / image.size.height));
+                }];
+            }];
         }
     }
     else{
         self.luckyImgView.hidden = YES;
     }
     
-    if(listModel.isSelect){
-        self.titleLab.hidden = YES;
+    if(self.listModel.isSelect){
         self.suoTitleBtn.hidden = YES;
         
-        self.selectZuanNumBtn.hidden = NO;
-        
         self.bgImgView.hidden = NO;
-        self.selectBtn.hidden = NO;
-        [self updataCellShowData];
-        self.baseBtn.hidden = NO;
+        NSString *path = [[NSBundle mainBundle] pathForResource:@"icon_gift_selected_bg" ofType:@"webp"];
+        [self.bgImgView sd_setImageWithURL:[NSURL fileURLWithPath:path]];
+//        [self updataCellShowData];
         
-        [self.iconImgView mas_updateConstraints:^(MASConstraintMaker *make) {
-            make.top.equalTo(self.bgView).offset(4.0);
-        }];
+        [self showBreathingAnimation:self.iconImgView min:1.0 max:1.14];
     }
     else{
         if(listModel.lock){
@@ -260,46 +211,25 @@
             self.titleLab.hidden = NO;
         }
         
-        self.selectZuanNumBtn.hidden = YES;
         self.bgImgView.hidden = YES;
-        self.selectBtn.hidden = YES;
-        self.baseBtn.hidden = YES;
-        self.comboView.hidden = YES;
-        self.comboView.isFire = NO;
+        self.bgImgView.image = nil;
         
-        [self.iconImgView mas_updateConstraints:^(MASConstraintMaker *make) {
-            make.top.equalTo(self.bgView).offset(12.0);
-        }];
+        [self.iconImgView.layer removeAllAnimations];
     }
-    
+}
+
+- (void)showBreathingAnimation:(UIView *)view min:(CGFloat)min max:(CGFloat)max {
+    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
+    animation.fromValue = @(min);
+    animation.toValue = @(max);
+    animation.duration = 0.5;
+    animation.repeatCount = INFINITY;
+    animation.autoreverses = YES;
+    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
+    [view.layer addAnimation:animation forKey:nil];
 }
 
 - (void)updataCellShowData{
-    if(self.listModel.isSelect){
-        [self.selectBtn setTitle:[NSString stringWithFormat:@"Send %zd",self.giftNum] forState:UIControlStateNormal];
-        
-        if(self.selectSkin){
-            if(self.selectSkin.lock){
-                self.selectBtn.selected = YES;
-                
-                UIImage *grayImg = [[UIImage imageNamed:@"v_2_select_gift_bg"] imageByGrayscale];
-                [self.bgImgView setImage:grayImg];
-                
-                [self.selectBtn setTitle:NSLocalString(@"mimo_2_live_gift_lock") forState:UIControlStateNormal];
-            }
-            else{
-                self.selectBtn.selected = NO;
-                [self.bgImgView setImage:[UIImage imageNamed:@"v_2_select_gift_bg"]];
-            }
-        }
-        else{
-            self.selectBtn.selected = NO;
-            [self.bgImgView setImage:[UIImage imageNamed:@"v_2_select_gift_bg"]];
-        }
-    }
-    else{
-        
-    }
 }
 
 - (void)updataListModelNumWith:(MOGiftlist *)cellModel{
@@ -348,10 +278,6 @@
     }
 }
 
-- (void)handleLongPress:(UILongPressGestureRecognizer *)recognizer {
-    [self.comboView handleLongPress:recognizer];
-}
-
 - (void)oneSecondPassed{
     [self toUpdateTheTimeText];
 }
@@ -363,16 +289,11 @@
     [self.zuanNumBtn setImage:nil forState:UIControlStateNormal];
     [self.zuanNumBtn setTitle:timeText forState:UIControlStateNormal];
     
-    [self.selectZuanNumBtn setImage:nil forState:UIControlStateNormal];
-    [self.selectZuanNumBtn setTitle:timeText forState:UIControlStateNormal];
-    
     if(self.timeRed){
         [self.zuanNumBtn setTitleColor:[MOTools colorWithHexString:@"#FF1F1F"] forState:UIControlStateNormal];
-        [self.selectZuanNumBtn setTitleColor:[MOTools colorWithHexString:@"#FF1F1F"] forState:UIControlStateNormal];
     }
     else{
         [self.zuanNumBtn setTitleColor:[MOTools colorWithHexString:@"#FFFFFF" alpha:0.5] forState:UIControlStateNormal];
-        [self.selectZuanNumBtn setTitleColor:[MOTools colorWithHexString:@"#FFFFFF" alpha:0.5] forState:UIControlStateNormal];
     }
 }
 
@@ -430,7 +351,6 @@
         _bgImgView.clipsToBounds = YES;
         _bgImgView.userInteractionEnabled = NO;
         _bgImgView.contentMode = UIViewContentModeScaleToFill;
-        [_bgImgView setImage:[UIImage imageNamed:@"v_2_select_gift_bg"]];
         _bgImgView.hidden = YES;
     }
     return _bgImgView;
@@ -488,125 +408,6 @@
     return _zuanNumBtn;
 }
 
-- (BigBtn *)selectZuanNumBtn{
-    if (!_selectZuanNumBtn)
-    {
-        _selectZuanNumBtn = [BigBtn buttonWithType:UIButtonTypeCustom];
-        _selectZuanNumBtn.backgroundColor = [UIColor clearColor];
-        [_selectZuanNumBtn setImage:[UIImage imageNamed:@"icon_gift_zuan_20"] forState:UIControlStateNormal];
-        _selectZuanNumBtn.imageView.contentMode = UIViewContentModeScaleAspectFit;
-        _selectZuanNumBtn.userInteractionEnabled = NO;
-        [_selectZuanNumBtn setTitle:@"0" forState:UIControlStateNormal];
-        [_selectZuanNumBtn setTitleColor:[MOTools colorWithHexString:@"#FFFFFF" alpha:0.5] forState:UIControlStateNormal];
-        [_selectZuanNumBtn setFont:[MOTextTools regularFont:10.0]];
-        _selectZuanNumBtn.imageEdgeInsets = UIEdgeInsetsMake(0, -3, 0, 0);
-    }
-    return _selectZuanNumBtn;
-}
-
-- (UIImageView *)selectImg{
-    if (!_selectImg)
-    {
-        _selectImg = [[UIImageView alloc] init];
-        _selectImg.clipsToBounds = YES;
-        _selectImg.userInteractionEnabled = NO;
-        _selectImg.contentMode = UIViewContentModeScaleToFill;
-        [_selectImg setImage:[UIImage imageNamed:@"v_2_select_gift_bg"]];
-    }
-    return _selectImg;
-}
-
-- (UIButton *)selectBtn{
-    if (!_selectBtn)
-    {
-        _selectBtn = [UIButton buttonWithType:UIButtonTypeCustom];
-        
-        NSArray *colorArr = @[kBaseColorLeft,kBaseColorRight];
-        UIImage *image = [MOTools createGradientRectImageWithBounds:CGRectMake(0, 0, 76.0, 24.0) Colors:colorArr GradientType:0];
-        
-        [_selectBtn setBackgroundImage:image forState:UIControlStateNormal];
-        
-        UIImage *grayImg = [MOTools createImageWithColor:[MOTools colorWithHexString:@"#3E3E52"]];
-        [self.selectBtn setBackgroundImage:grayImg forState:UIControlStateSelected];
-        
-        _selectBtn.imageView.contentMode = UIViewContentModeScaleToFill;
-        _selectBtn.userInteractionEnabled = NO;
-        [_selectBtn setTitle:@"Send" forState:UIControlStateNormal];
-        [_selectBtn setTitleColor:[MOTools colorWithHexString:@"#FFFFFF" alpha:1.0] forState:UIControlStateNormal];
-        _selectBtn.titleLabel.font = [MOTextTools poppinsMediumFont:12.0];
-        _selectBtn.layer.cornerRadius = 8.0;
-        _selectBtn.layer.masksToBounds = YES;
-    }
-    return _selectBtn;
-}
-
-- (MOComboView *)comboView{
-    if(!_comboView){
-        WEAKSELF
-        _comboView = [[MOComboView alloc] init];
-        _comboView.isHaveLongPress = YES;
-        _comboView.isFire = NO;
-        _comboView.comboClickBlock = ^{
-            [weakSelf selectBtnClick];
-        };
-        _comboView.timeEndBlock = ^{
-            if(weakSelf.listModel){
-                weakSelf.listModel = weakSelf.listModel;
-            }
-            weakSelf.comboCountdownBlock ? weakSelf.comboCountdownBlock() : nil;
-        };
-    }
-    return _comboView;
-}
-
-- (UIButton *)baseBtn{
-    if(!_baseBtn){
-        _baseBtn = [UIButton buttonWithType:UIButtonTypeCustom];
-        _baseBtn.backgroundColor = [UIColor clearColor];
-        [_baseBtn addTarget:self action:@selector(selectBtnClick) forControlEvents:UIControlEventTouchUpInside];
-        _baseBtn.acceptEventInterval = 0.33;
-        
-        // 添加长按手势
-        UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
-        longPressRecognizer.minimumPressDuration = 0.5; // 长按触发时间
-        [_baseBtn addGestureRecognizer:longPressRecognizer];
-    }
-    return _baseBtn;
-}
-
-- (void)selectBtnClick{
-    
-    if(self.listModel.lock){
-        return;
-    }
-    
-    if(self.selectSkin.id.length > 0){
-        if(self.selectSkin.lock){
-            return;
-        }
-    }
-    
-    self.selectZuanNumBtn.hidden = YES;
-    self.bgImgView.hidden = YES;
-    self.selectBtn.hidden = YES;
-    self.baseBtn.hidden = YES;
-    self.titleLab.hidden = NO;
-    
-    self.listModel.isSelect = YES;
-    
-    self.comboView.hidden = NO;
-    self.comboView.isFire = YES;
-    [self.comboView setGiftImgWith:self.listModel.giftInfo.giftPath];
-    [self.comboView startTimer];
-    
-    self.comboClickBlock ? self.comboClickBlock(self.listModel) : nil;
-}
-
-- (void)prepareForReuse {
-    [super prepareForReuse];
-    [self.comboView resetAnimationIfNeeded]; // 确保动画不会丢失
-}
-
 - (UIButton *)suoTitleBtn{
     if (!_suoTitleBtn){
         _suoTitleBtn = [UIButton buttonWithType:UIButtonTypeCustom];

+ 0 - 62
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListBagView/MOBagCollectionView.m

@@ -46,30 +46,6 @@ MOGiftListViewModelDelegate>
     [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
         make.edges.equalTo(self);
     }];
-    
-//    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
-//    NSArray *colors = @[(id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:1.0].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:0.4].CGColor,
-//                        (id)[UIColor colorWithWhite:0 alpha:0.0].CGColor,
-//    ];
-//    [gradientLayer setColors:colors];
-//    [gradientLayer setStartPoint:CGPointMake(0, 0)];
-//    [gradientLayer setEndPoint:CGPointMake(0, 1)];
-//    gradientLayer.frame = CGRectMake(0.0, 0.0, SCREENWIDTH, 235.0);
-//    [self.layer setMask:gradientLayer];
 }
 
 #pragma mark - JXCategoryListContentViewDelegate
@@ -306,45 +282,8 @@ MOGiftListViewModelDelegate>
     MOGiftlist *modle = self.dataArr[indexPath.row];
     MOGiftItemCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:MOGiftItemCell_ID forIndexPath:indexPath];
     cell.isBag = true;
-    cell.giftNum = self.giftNum;
     cell.listModel = modle;
     cell.selectSkin = self.selectSkin;
-    cell.comboClickBlock = ^(MOGiftlist * _Nonnull cellModel) {
-        
-        NSMutableArray *tempIndexArr = [NSMutableArray array];
-        
-        
-        for (MOGiftlist *giftModel in weakSelf.dataArr) {
-            
-            if([cellModel.giftInfo.id isEqualToString:giftModel.giftInfo.id]){
-                giftModel.isSelect = YES;
-            }
-            else{
-                giftModel.isSelect = NO;
-            }
-            
-        }
-        
-        //除了点击的Cell不刷新, 其他视图内可见Cell都刷新
-        for (NSIndexPath *visibleIndexPath in collectionView.indexPathsForVisibleItems) {
-            if (![visibleIndexPath isEqual:indexPath]) {
-                [tempIndexArr addObject:visibleIndexPath];
-            }
-        }
-        
-        //消除刷新阴影
-        if(tempIndexArr.count > 0){
-            [CATransaction setDisableActions:YES];
-            [collectionView reloadItemsAtIndexPaths:tempIndexArr];
-            [CATransaction commit];
-        }
-        
-        weakSelf.selectGiftBlock ? weakSelf.selectGiftBlock(cellModel, weakSelf.type) : nil;
-    };
-    
-    cell.comboCountdownBlock = ^{
-        weakSelf.comboCountdownBlock ? weakSelf.comboCountdownBlock() : nil;
-    };
     
     return cell;
 }
@@ -379,7 +318,6 @@ MOGiftListViewModelDelegate>
     if(self.selectIndexPath){
         MOGiftItemCell *cell = (MOGiftItemCell *)[self.collectionView cellForItemAtIndexPath:self.selectIndexPath];
         if(cell){
-            cell.giftNum = self.giftNum;
             cell.selectSkin = self.selectSkin;
             [cell updataCellShowData];
         }

+ 5 - 8
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListBagView/MOGiftListBagView.h

@@ -9,22 +9,18 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
+
+@class MOShopList;
+
 @interface MOGiftListBagView : UIView
 
 /** 目标用户Id */
 @property (nonatomic, copy) NSString *targetUserId;
 
 @property (nonatomic, copy) void(^selectGiftBlock)(MOGiftlist *selectGiftModel, NSInteger giftType);
-
-@property (nonatomic, copy) void(^selectCellBlock)(MOGiftlist *selectGiftMode);//选中Cell的回调
+@property (nonatomic, copy) void(^selectCellBlock)(MOShopList *selectGiftMode);//选中Cell的回调
 
 @property (nonatomic, copy) void(^theFirstGiftBlock)(void);//第一个礼物锁定态
-/** comboView 倒计时结束回调*/
-@property (nonatomic, copy) void (^comboCountdownBlock)(void);
-/** 选中的背包礼物数量 */
-@property (nonatomic, copy) void (^sendNumChange)(NSInteger giftNum);
-/** 自定义数量弹窗 */
-@property (nonatomic, copy) void (^customNumBlock)(void);
 /** 消失回调 */
 @property (nonatomic, copy) void (^dismissBlock)(void);
 
@@ -62,6 +58,7 @@ NS_ASSUME_NONNULL_BEGIN
 /// 1秒触发一次
 - (void)oneSecondPassed;
 
+- (void)updatePropCollectionBy:(MOShopList *)item;
 
 @end
 

+ 8 - 311
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListBagView/MOGiftListBagView.m

@@ -30,10 +30,6 @@
 
 @property (nonatomic, strong) JXCategoryListContainerView *listContainerView;
 
-@property (nonatomic, copy) MOChooseNumView *chooseNumView;
-
-@property (nonatomic, strong) BigBtn *theUseBtn;//道具使用按钮
-
 @property (nonatomic, strong) MOBagCollectionView *bagCollectionView;//背包
 
 @property (nonatomic, strong) MOPropsCollectionView *propsCollectionView;//道具
@@ -144,31 +140,12 @@
         make.height.equalTo(@90.0);
     }];
     
-//    [self.bgView addSubview:self.chooseNumView];
-//    [self.chooseNumView mas_makeConstraints:^(MASConstraintMaker *make) {
-//        make.height.equalTo(@(kChooseNumBaseViewHeight));
-//        make.width.equalTo(@(kChooseNumBaseViewWidth));
-//        make.bottom.equalTo(self.listContainerView.mas_bottom).offset(-15.0);
-//        make.right.mas_equalTo(@(-12.0));
-//    }];
-//    self.chooseNumView.hidden = YES;
-    
-    [self.bgView addSubview:self.theUseBtn];
-    [self.theUseBtn mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.bottom.equalTo(self.bgView).offset(-42.0);
-        make.right.mas_equalTo(@(-12.0));
-        make.height.mas_equalTo(28); // 固定高度
-        make.width.greaterThanOrEqualTo(@60); // 可以根据需要改为最小宽度
-    }];
-    self.theUseBtn.hidden = YES;
-    
     self.previousIndex = 0;
 }
 
 - (void)categoryView:(JXCategoryBaseView *)categoryView didSelectedItemAtIndex:(NSInteger)index{
     
     if(index == 0){
-        self.theUseBtn.hidden = YES;
         self.theChooseProps = nil;
         
         if(self.topTipView.hidden == NO){
@@ -214,6 +191,14 @@
     self.previousIndex = index;
 }
 
+- (void)updatePropCollectionBy:(MOShopList *)item {
+    if (item.used) {
+        [self.propsCollectionView toUseThePropsWith:item];
+    } else {
+        [self.propsCollectionView toNoUseAction];
+    }
+}
+
 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
     UIView *hitView = [super hitTest:point withEvent:event];
     
@@ -381,267 +366,10 @@
     return _listContainerView;
 }
 
-- (MOChooseNumView *)chooseNumView{
-    if(!_chooseNumView){
-        WEAKSELF
-        _chooseNumView = [[MOChooseNumView alloc] initWithFrame:CGRectMake(0, 0, kChooseNumBaseViewWidth, kChooseNumBaseViewHeight)];
-        _chooseNumView.numArr = @[@(1),@(3)];
-        _chooseNumView.chooseNumBlock = ^(NSInteger num) {
-            weakSelf.giftNum = num;
-            [weakSelf toUpdataTheSelectIndexPathCell];
-        };
-        _chooseNumView.customNumBlock = ^{
-            weakSelf.customNumBlock ? weakSelf.customNumBlock() : nil;
-        };
-    }
-    return _chooseNumView;
-}
-
 - (void)toUpdataTheSelectIndexPathCell{
     [self.bagCollectionView toUpdataTheSelectIndexPathCell];
 }
 
-- (void)setGiftNum:(NSInteger)giftNum{
-    _giftNum = giftNum;
-    self.bagCollectionView.giftNum = giftNum;
-}
-
-- (BigBtn *)theUseBtn{
-    if (!_theUseBtn) {
-        _theUseBtn = [BigBtn buttonWithType:UIButtonTypeCustom];
-        [_theUseBtn addTarget:self action:@selector(theUseBtnClick) forControlEvents:UIControlEventTouchUpInside];
-        [_theUseBtn setFont:[MOTextTools poppinsMediumFont:12.0]];
-        [_theUseBtn setTitle:NSLocalString(@"mimo_2_gift_list_prpps_use") forState:UIControlStateNormal];
-        [_theUseBtn setTitle:NSLocalString(@"mimo_2_gift_list_prpps_a_use") forState:UIControlStateSelected];
-        
-        NSArray *selectColorArr = @[[MOTools colorWithHexString:@"#FFFFFF" alpha:0.06],[MOTools colorWithHexString:@"#FFFFFF" alpha:0.06]];
-        UIImage *selectImg = [MOTools createGradientRectImageWithBounds:CGRectMake(0, 0, 80.0, 30.0) Colors:selectColorArr GradientType:0];
-        [_theUseBtn setBackgroundImage:selectImg forState:UIControlStateSelected];
-        
-        NSArray *colorArr = @[kBaseColorLeft,kBaseColorRight];
-        UIImage *image = [MOTools createGradientRectImageWithBounds:CGRectMake(0, 0, 80.0, 30.0) Colors:colorArr GradientType:0];
-        [_theUseBtn setBackgroundImage:image forState:UIControlStateNormal];
-        
-        [_theUseBtn setImage:[UIImage imageNamed:@"v_2_prop_use"] forState:UIControlStateNormal];
-        [_theUseBtn setImage:[UIImage imageNamed:@"v_2_prop_no_use"] forState:UIControlStateSelected];
-        
-        [_theUseBtn setTitleColor:[MOTools colorWithHexString:@"#FFFFFF"] forState:UIControlStateNormal];
-        [_theUseBtn setTitleColor:[MOTools colorWithHexString:@"#878A99"] forState:UIControlStateSelected];
-                
-        // 调整图文间距和内边距
-        CGFloat spacing = 5.0; // 减小图文间距
-        _theUseBtn.contentEdgeInsets = UIEdgeInsetsMake(2, 12, 2, 12); // 增加左右内边距
-        _theUseBtn.imageEdgeInsets = UIEdgeInsetsMake(0, -spacing/2, 0, spacing/2);
-        _theUseBtn.titleEdgeInsets = UIEdgeInsetsMake(0, spacing/2, 0, -spacing/2);
-        
-        // 2. 防止被压缩和截断
-        [_theUseBtn setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
-        [_theUseBtn setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
-        _theUseBtn.titleLabel.lineBreakMode = NSLineBreakByClipping;
-        _theUseBtn.titleLabel.adjustsFontSizeToFitWidth = NO; // 不自动缩小字体
-        
-        _theUseBtn.layer.cornerRadius = 8.0;
-        _theUseBtn.layer.masksToBounds = YES;
-    }
-    return _theUseBtn;
-}
-
-- (void)theUseBtnClick{
-    if(!self.theChooseProps){
-        return;
-    }
-    
-    if(self.theUseBtn.selected){
-        //取消使用
-        [self toUseThePropsWithPropsId:self.theChooseProps.id AndUse:NO];
-    }
-    else{
-        //使用
-        [self toUseThePropsWithPropsId:self.theChooseProps.id AndUse:YES];
-    }
-}
-
-- (void)toUseThePropsWithPropsId:(NSString *)propsId AndUse:(BOOL)isUse{
-    
-    if(propsId.length == 0){
-        return;
-    }
-    
-    WEAKSELF
-    NSDictionary *dict = @{@"id":propsId,
-                           @"use":@(isUse)};
-    [kHttpManager toUseThePropWithParams:dict andBlock:^(id  _Nonnull data, NSError * _Nonnull error) {
-        if(kCode_Success){
-            
-            //刷新当前界面
-            weakSelf.theChooseProps.used = isUse;
-            if(isUse){
-                [weakSelf.propsCollectionView toUseThePropsWith:weakSelf.theChooseProps];
-            }
-            else{
-                [weakSelf.propsCollectionView toNoUseAction];
-            }
-            
-            //按钮动画
-            [weakSelf useBtnAnimationActionWith:isUse];
-            
-            //更新本地 缓存
-            [weakSelf toUpdateTheBaseCacheAndUse:isUse];
-            
-            if(isUse){
-                [MBProgressHUD showTipMessageInWindow:NSLocalString(@"mimo_2_bag_prop_equip_tip")];
-            }
-            else{
-                [MBProgressHUD showTipMessageInWindow:NSLocalString(@"mimo_2_bag_prop_un_equip_tip")];
-            }
-        }
-        else{
-            kShowNetError(data)
-            weakSelf.theUseBtn.selected = !isUse;//报错 - 重置为原来
-        }
-    }];
-}
-
-- (void)toUpdateTheBaseCacheAndUse:(BOOL)isUse{
-    //道具分类\n * 1: 头饰\n * 2: 气泡\n * 3: 入场座驾(旧:进场条)\n * 4: 名片框\n * 5: 直播徽章\n * 6: 用户徽章\n * 7: 进场条(旧:进场飘屏)\n * 8: 打赏横幅\n * 9: 连麦边框\n * 10: 直播弹幕
-    
-    NSInteger type = (NSInteger)self.theChooseProps.category;
-    
-    if(isUse){
-        //使用的时候, code必不为0
-        NSInteger code = self.theChooseProps.propInfo.storeInfo.code;
-        if(code == 0){
-            return;
-        }
-    }
-    
-    switch (type) {
-        case 1:
-        {
-            //头饰 - 刷新房间自己的头饰
-            if(isUse){
-                self.headDressChangeBlock ? self.headDressChangeBlock(self.theChooseProps.propInfo.storeInfo) : nil;
-            }
-            else{
-                self.headDressChangeBlock ? self.headDressChangeBlock(nil) : nil;
-            }
-            
-        }
-            break;
-        case 2:
-        {
-            NSInteger bubbleCode;
-            //进场条
-            if(isUse){
-                bubbleCode = self.theChooseProps.propInfo.storeInfo.code;
-            }
-            else{
-                bubbleCode = 0;
-            }
-            [[NSUserDefaults standardUserDefaults] setObject:@(bubbleCode) forKey:kUserBubbleCode];
-            [[NSUserDefaults standardUserDefaults] synchronize];
-        }
-            break;
-        case 3:
-        {
-            //入场特效
-            NSInteger enterBar;
-            //进场条
-            if(isUse){
-                enterBar = self.theChooseProps.propInfo.storeInfo.code;
-            }
-            else{
-                enterBar = 0;
-            }
-            [[NSUserDefaults standardUserDefaults] setObject:@(enterBar) forKey:kUserEnterBar];
-            [[NSUserDefaults standardUserDefaults] synchronize];
-        }
-            break;
-        case 4:
-        {
-            //名片框
-            NSInteger cardFrame;
-            //进场条
-            if(isUse){
-                cardFrame = self.theChooseProps.propInfo.storeInfo.code;
-            }
-            else{
-                cardFrame = 0;
-            }
-            [[NSUserDefaults standardUserDefaults] setObject:@(cardFrame) forKey:kCardFrameCode];
-            [[NSUserDefaults standardUserDefaults] synchronize];
-        }
-            break;
-        case 7:
-        {
-            NSInteger enterFloating;
-            //进场条 - 进场飘屏
-            if(isUse){
-                enterFloating = self.theChooseProps.propInfo.storeInfo.code;
-            }
-            else{
-                enterFloating = 0;
-            }
-            [[NSUserDefaults standardUserDefaults] setObject:@(enterFloating) forKey:kEnterFloatingCode];
-            [[NSUserDefaults standardUserDefaults] synchronize];
-            
-        }
-            break;
-        case 8:
-        {
-            //打赏横幅
-            NSInteger rewardBanner;
-            if(isUse){
-                rewardBanner = self.theChooseProps.propInfo.storeInfo.code;
-            }
-            else{
-                rewardBanner = 0;
-            }
-            [[NSUserDefaults standardUserDefaults] setObject:@(rewardBanner) forKey:kRewardBannerCode];
-            [[NSUserDefaults standardUserDefaults] synchronize];
-        }
-            break;
-        case 9:
-        {
-            //连麦边框
-            NSInteger linkMicFrame;
-            if(isUse){
-                linkMicFrame = self.theChooseProps.propInfo.storeInfo.code;
-            }
-            else{
-                linkMicFrame = 0;
-            }
-            [[NSUserDefaults standardUserDefaults] setObject:@(linkMicFrame) forKey:kLinkMicFrameCode];
-            [[NSUserDefaults standardUserDefaults] synchronize];
-            
-            if(isUse){
-                self.linkMicPropChangeBlock ? self.linkMicPropChangeBlock(self.theChooseProps.propInfo.storeInfo) : nil;
-            }
-            else{
-                self.linkMicPropChangeBlock ? self.linkMicPropChangeBlock(nil) : nil;
-            }
-        }
-            break;
-        case 10:
-        {
-            //直播弹幕
-            NSInteger liveBarrage;
-            if(isUse){
-                liveBarrage = self.theChooseProps.propInfo.storeInfo.code;
-            }
-            else{
-                liveBarrage = 0;
-            }
-            [[NSUserDefaults standardUserDefaults] setObject:@(liveBarrage) forKey:kLiveBarrageCode];
-            [[NSUserDefaults standardUserDefaults] synchronize];
-        }
-            break;
-            
-        default:
-            break;
-    }
-}
-
 - (MOBagCollectionView *)bagCollectionView{
     if(!_bagCollectionView){
         _bagCollectionView = [[MOBagCollectionView alloc] initWith:self.giftViewModel];
@@ -650,15 +378,6 @@
         _bagCollectionView.selectGiftBlock = ^(MOGiftlist * _Nonnull selectGiftModel, NSInteger giftType) {
             weakSelf.selectGiftBlock ? weakSelf.selectGiftBlock(selectGiftModel, giftType) : nil;
         };
-        //选中回调
-        _bagCollectionView.selectCellBlock = ^(MOGiftlist * _Nonnull selectGiftMode) {
-            weakSelf.giftNum = 1;
-//            [weakSelf toUpdateTheChooseNumView];
-            weakSelf.selectCellBlock ? weakSelf.selectCellBlock(selectGiftMode) : nil;
-        };
-        _bagCollectionView.comboCountdownBlock = ^{
-            weakSelf.comboCountdownBlock ? weakSelf.comboCountdownBlock() : nil;
-        };
         _bagCollectionView.theFirstGiftBlock = ^{
             weakSelf.theFirstGiftBlock ? weakSelf.theFirstGiftBlock() : nil;
         };
@@ -666,11 +385,6 @@
     return _bagCollectionView;
 }
 
-- (void)toUpdateTheChooseNumView{
-    self.chooseNumView.hidden = NO;
-    [self.chooseNumView toResetTheView];
-}
-
 - (MOPropsCollectionView *)propsCollectionView{
     if(!_propsCollectionView){
         _propsCollectionView = [[MOPropsCollectionView alloc] init];
@@ -678,7 +392,6 @@
         WEAKSELF
         _propsCollectionView.selectCellBlock = ^(MOShopList * _Nonnull selectModel) {
             weakSelf.theChooseProps = selectModel;
-            weakSelf.theUseBtn.hidden = NO;
             
             if(selectModel.propInfo.obtainSource > 0){
                 
@@ -697,8 +410,6 @@
                     make.top.equalTo(weakSelf.contentView).offset(kTheAnimationTop);
                 }];
             }
-
-            [weakSelf useBtnAnimationActionWith:selectModel.used];
         };
         
         _propsCollectionView.toShopBlock = ^{
@@ -731,20 +442,6 @@
     }];
 }
 
-//按钮动画
-- (void)useBtnAnimationActionWith:(BOOL)isUse{
-    // 先更新文本状态(不动画)
-    [UIView performWithoutAnimation:^{
-        self.theUseBtn.selected = isUse;
-        [self.theUseBtn layoutIfNeeded]; // 立即更新按钮内部布局
-    }];
-    
-    [UIView animateWithDuration:0.25 animations:^{
-        // 2. 让 Auto Layout 更新布局
-        [self layoutIfNeeded];
-    }];
-}
-
 - (MOBagTopTipView *)topTipView{
     if(!_topTipView){
         _topTipView = [[MOBagTopTipView alloc] init];

+ 7 - 33
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListBagView/Props/MOPropsItemCell.m

@@ -12,8 +12,6 @@
 /** 背景 */
 @property (nonatomic, strong) UIView *bgView;
 
-@property (nonatomic, strong) UIImageView *bgStatusOneImgView;
-
 @property (nonatomic, strong) UIImageView *bgStatusTwoImgView;
 
 @property (nonatomic, strong) UIImageView *iconImgView;//图标
@@ -54,22 +52,12 @@
     }];
     
     CGFloat theStatusWidth = kScaleWidth(82.0);
-    CGFloat theStatusHeight = kScaleWidth(96.0);
-    
-    [self.bgView addSubview:self.bgStatusOneImgView];
-    [self.bgStatusOneImgView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.height.equalTo(@(theStatusHeight));
-        make.width.equalTo(@(theStatusWidth));
-        make.top.equalTo(self.bgView).offset(4.0);
-        make.centerX.equalTo(self.bgView);
-    }];
-    self.bgStatusOneImgView.hidden = YES;
     
     [self.bgView addSubview:self.bgStatusTwoImgView];
     [self.bgStatusTwoImgView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.height.equalTo(@(theStatusHeight));
-        make.width.equalTo(@(theStatusWidth));
-        make.top.equalTo(self.bgView).offset(4.0);
+        make.height.equalTo(self.bgView);
+        make.width.equalTo(@94);
+        make.top.equalTo(self.bgView);
         make.centerX.equalTo(self.bgView);
     }];
     self.bgStatusTwoImgView.hidden = YES;
@@ -124,9 +112,8 @@
     
     [self.bgView addSubview:self.useImgView];
     [self.useImgView mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.top.equalTo(self.bgStatusOneImgView.mas_top);
-        make.left.equalTo(self.bgStatusOneImgView.mas_left);
-        make.width.height.equalTo(@32.0);
+        make.top.equalTo(self.bgStatusTwoImgView.mas_top).offset(4);
+        make.left.equalTo(self.bgStatusTwoImgView.mas_left).offset(4);
     }];
     self.useImgView.hidden = YES;
     
@@ -155,16 +142,16 @@
     [self toUpdateTheTypeImageView];
     
     if(cellModel.used){
-        self.bgStatusOneImgView.hidden = NO;
         self.useImgView.hidden = NO;
     }
     else{
-        self.bgStatusOneImgView.hidden = YES;
         self.useImgView.hidden = YES;
     }
     
     if(cellModel.isSelect){
         self.bgStatusTwoImgView.hidden = NO;
+        NSString *path = [[NSBundle mainBundle] pathForResource:@"icon_gift_selected_bg" ofType:@"webp"];
+        [self.bgStatusTwoImgView sd_setImageWithURL:[NSURL fileURLWithPath:path]];
     }
     else{
         self.bgStatusTwoImgView.hidden = YES;
@@ -265,19 +252,6 @@
     return _bgView;
 }
 
-- (UIImageView *)bgStatusOneImgView{
-    if (!_bgStatusOneImgView)
-    {
-        _bgStatusOneImgView = [[UIImageView alloc] init];
-        _bgStatusOneImgView.clipsToBounds = YES;
-        _bgStatusOneImgView.userInteractionEnabled = NO;
-        _bgStatusOneImgView.contentMode = UIViewContentModeScaleToFill;
-        [_bgStatusOneImgView setImage:[UIImage imageNamed:@"icon_bag_bg_status_1"]];
-        _bgStatusOneImgView.hidden = YES;
-    }
-    return _bgStatusOneImgView;
-}
-
 - (UIImageView *)bgStatusTwoImgView{
     if (!_bgStatusTwoImgView)
     {

+ 1 - 4
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListView.h

@@ -40,9 +40,6 @@ NS_ASSUME_NONNULL_BEGIN
 @property (nonatomic, copy) void (^dismissBlock)(void);
 @property (nonatomic, copy) void (^showUpBlock)();
 
-/** comboView 倒计时结束回调*/
-@property (nonatomic, copy) void (^comboCountdownBlock)(void);
-
 @property (nonatomic, assign) BOOL isSingleLinkMic;//是否单人连麦
 @property (nonatomic, assign) BOOL multiple;//是否多人直播间
 @property (nonatomic, strong) MOUserProfile *anchorUser;//主播
@@ -65,7 +62,7 @@ NS_ASSUME_NONNULL_BEGIN
 /** 打开商店 */
 @property (nonatomic, copy) void(^toShopBlock)(void);
 
-+ (instancetype)moGiftListView:(MOGiftListViewModel *)listViewModel;
+- (instancetype)initWith:(MOGiftListViewModel *)listViewModel;
 
 - (void)showGiftListView;
 

File diff suppressed because it is too large
+ 261 - 612
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListView.m


+ 0 - 211
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftListView.xib

@@ -1,211 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina6_12" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
-        <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="MOGiftListView">
-            <rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
-            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-            <subviews>
-                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="myZ-DO-7cl">
-                    <rect key="frame" x="0.0" y="0.0" width="393" height="422"/>
-                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                    <connections>
-                        <action selector="dismissBtnClick:" destination="iN0-l3-epB" eventType="touchUpInside" id="Gz9-Qp-Rmh"/>
-                    </connections>
-                </button>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gXK-WE-Afp">
-                    <rect key="frame" x="0.0" y="422" width="393" height="430"/>
-                    <subviews>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="F0N-cX-RgR">
-                            <rect key="frame" x="0.0" y="56" width="393" height="374"/>
-                            <color key="backgroundColor" red="0.070588235294117646" green="0.070588235294117646" blue="0.12156862745098039" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
-                        </view>
-                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.90000000000000002" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="7ve-MS-enP">
-                            <rect key="frame" x="0.0" y="0.0" width="393" height="430"/>
-                        </imageView>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YQ2-WU-vgs">
-                            <rect key="frame" x="12" y="357" width="63" height="28"/>
-                            <color key="backgroundColor" red="0.12156862745098039" green="0.12156862745098039" blue="0.16862745098039217" alpha="0.93999999999999995" colorSpace="custom" customColorSpace="calibratedRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="28" id="KOt-Za-hvf"/>
-                            </constraints>
-                        </view>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5JE-RE-Wzz">
-                            <rect key="frame" x="20" y="362" width="35" height="18"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="35" id="2MD-dt-ssP"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" pointSize="15"/>
-                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                            <state key="normal" title="33" image="icon_gift_zuan">
-                                <color key="titleColor" red="0.88235294117647056" green="0.81960784313725488" blue="0.89803921568627454" alpha="1" colorSpace="calibratedRGB"/>
-                            </state>
-                            <connections>
-                                <action selector="topUpBtnClick:" destination="iN0-l3-epB" eventType="touchUpInside" id="C0Q-Eh-Qzm"/>
-                            </connections>
-                        </button>
-                        <button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EvQ-SR-4XV" customClass="BigBtn">
-                            <rect key="frame" x="323" y="354.66666666666663" width="60" height="33"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="60" id="5fW-gy-Zts"/>
-                                <constraint firstAttribute="height" constant="33" id="EhV-6F-P3I"/>
-                            </constraints>
-                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                            <state key="normal" title="Send"/>
-                            <connections>
-                                <action selector="sentBtnClick:" destination="iN0-l3-epB" eventType="touchUpInside" id="Myj-aB-4dq"/>
-                            </connections>
-                        </button>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="J8H-cI-lc0" customClass="BigBtn">
-                            <rect key="frame" x="55" y="366" width="10" height="10"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="10" id="D4x-gI-qTS"/>
-                                <constraint firstAttribute="width" constant="10" id="d6K-cc-bh6"/>
-                            </constraints>
-                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                            <state key="normal" image="v_2_mine_white_right"/>
-                            <connections>
-                                <action selector="topUpBtnClick:" destination="iN0-l3-epB" eventType="touchUpInside" id="DFV-Ur-4rg"/>
-                            </connections>
-                        </button>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="s7r-7d-RQo">
-                            <rect key="frame" x="163" y="356" width="218" height="30"/>
-                            <subviews>
-                                <stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="99w-uA-2ze">
-                                    <rect key="frame" x="0.0" y="0.0" width="152" height="30"/>
-                                    <subviews>
-                                        <button opaque="NO" tag="20" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="PPf-Nh-Jhb">
-                                            <rect key="frame" x="0.0" y="0.0" width="38" height="30"/>
-                                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                                            <state key="normal" title="1"/>
-                                            <connections>
-                                                <action selector="giftNumSelectBtnClick:" destination="iN0-l3-epB" eventType="touchUpInside" id="KbO-eh-1c6"/>
-                                            </connections>
-                                        </button>
-                                        <button opaque="NO" tag="21" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="O96-lR-gxD">
-                                            <rect key="frame" x="38" y="0.0" width="38" height="30"/>
-                                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                                            <state key="normal" title="10"/>
-                                            <connections>
-                                                <action selector="giftNumSelectBtnClick:" destination="iN0-l3-epB" eventType="touchUpInside" id="rkB-sW-KLd"/>
-                                            </connections>
-                                        </button>
-                                        <button opaque="NO" tag="22" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9qT-ga-6jJ">
-                                            <rect key="frame" x="76" y="0.0" width="38" height="30"/>
-                                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                                            <state key="normal" title="99"/>
-                                            <connections>
-                                                <action selector="giftNumSelectBtnClick:" destination="iN0-l3-epB" eventType="touchUpInside" id="vyu-J0-e5s"/>
-                                            </connections>
-                                        </button>
-                                        <button opaque="NO" tag="23" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LbU-At-PsZ">
-                                            <rect key="frame" x="114" y="0.0" width="38" height="30"/>
-                                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                                            <state key="normal" title="999"/>
-                                            <connections>
-                                                <action selector="giftNumSelectBtnClick:" destination="iN0-l3-epB" eventType="touchUpInside" id="iZn-dB-e27"/>
-                                            </connections>
-                                        </button>
-                                    </subviews>
-                                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                                </stackView>
-                                <button opaque="NO" tag="24" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IZ1-4L-eLj">
-                                    <rect key="frame" x="152" y="0.0" width="66" height="30"/>
-                                    <constraints>
-                                        <constraint firstAttribute="width" constant="66" id="7MC-qe-b3O"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                                    <state key="normal" title="Kustom"/>
-                                    <connections>
-                                        <action selector="giftNumSelectBtnClick:" destination="iN0-l3-epB" eventType="touchUpInside" id="QrR-du-HMk"/>
-                                    </connections>
-                                </button>
-                            </subviews>
-                            <color key="backgroundColor" red="0.12156862745098039" green="0.12156862745098039" blue="0.16862745098039217" alpha="0.93999999999999995" colorSpace="custom" customColorSpace="calibratedRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="bottom" secondItem="IZ1-4L-eLj" secondAttribute="bottom" id="BDz-2v-ouE"/>
-                                <constraint firstAttribute="height" constant="30" id="R1Q-Hz-7Xh"/>
-                                <constraint firstItem="IZ1-4L-eLj" firstAttribute="leading" secondItem="99w-uA-2ze" secondAttribute="trailing" id="aBb-LA-lsT"/>
-                                <constraint firstItem="99w-uA-2ze" firstAttribute="top" secondItem="s7r-7d-RQo" secondAttribute="top" id="bX9-oG-CFj"/>
-                                <constraint firstAttribute="width" constant="218" id="cnx-Wc-y8B"/>
-                                <constraint firstItem="IZ1-4L-eLj" firstAttribute="top" secondItem="s7r-7d-RQo" secondAttribute="top" id="ctG-zt-LYO"/>
-                                <constraint firstAttribute="bottom" secondItem="99w-uA-2ze" secondAttribute="bottom" id="hAU-4J-GkH"/>
-                                <constraint firstItem="99w-uA-2ze" firstAttribute="leading" secondItem="s7r-7d-RQo" secondAttribute="leading" id="p6k-8A-Xf0"/>
-                                <constraint firstAttribute="trailing" secondItem="IZ1-4L-eLj" secondAttribute="trailing" id="unI-hG-6eZ"/>
-                            </constraints>
-                        </view>
-                    </subviews>
-                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                    <constraints>
-                        <constraint firstAttribute="bottom" secondItem="F0N-cX-RgR" secondAttribute="bottom" id="0Zw-Fx-KkH"/>
-                        <constraint firstItem="J8H-cI-lc0" firstAttribute="leading" secondItem="5JE-RE-Wzz" secondAttribute="trailing" id="87C-gq-aAy"/>
-                        <constraint firstAttribute="trailing" secondItem="EvQ-SR-4XV" secondAttribute="trailing" constant="10" id="EAY-BF-utw"/>
-                        <constraint firstItem="5JE-RE-Wzz" firstAttribute="trailing" secondItem="YQ2-WU-vgs" secondAttribute="trailing" constant="-20" id="GBA-sv-u8m"/>
-                        <constraint firstItem="5JE-RE-Wzz" firstAttribute="leading" secondItem="gXK-WE-Afp" secondAttribute="leading" constant="20" id="GVv-XN-zBP"/>
-                        <constraint firstAttribute="trailing" secondItem="7ve-MS-enP" secondAttribute="trailing" id="Igz-1z-BcW"/>
-                        <constraint firstAttribute="bottom" secondItem="7ve-MS-enP" secondAttribute="bottom" id="Mce-rk-ipS"/>
-                        <constraint firstItem="EvQ-SR-4XV" firstAttribute="centerY" secondItem="5JE-RE-Wzz" secondAttribute="centerY" id="Nj5-Ch-DRg"/>
-                        <constraint firstItem="J8H-cI-lc0" firstAttribute="centerY" secondItem="5JE-RE-Wzz" secondAttribute="centerY" id="Qml-Wg-vOR"/>
-                        <constraint firstItem="F0N-cX-RgR" firstAttribute="top" secondItem="gXK-WE-Afp" secondAttribute="top" constant="56" id="UT5-Ia-kIx"/>
-                        <constraint firstItem="5JE-RE-Wzz" firstAttribute="centerY" secondItem="s7r-7d-RQo" secondAttribute="centerY" id="XDn-4u-Ikc"/>
-                        <constraint firstItem="F0N-cX-RgR" firstAttribute="leading" secondItem="gXK-WE-Afp" secondAttribute="leading" id="ajZ-K3-iaX"/>
-                        <constraint firstItem="5JE-RE-Wzz" firstAttribute="centerY" secondItem="YQ2-WU-vgs" secondAttribute="centerY" id="bhg-If-BWO"/>
-                        <constraint firstAttribute="trailing" secondItem="s7r-7d-RQo" secondAttribute="trailing" constant="12" id="dV2-9f-RSW"/>
-                        <constraint firstItem="7ve-MS-enP" firstAttribute="top" secondItem="gXK-WE-Afp" secondAttribute="top" id="daB-K8-bNA"/>
-                        <constraint firstAttribute="bottom" secondItem="5JE-RE-Wzz" secondAttribute="bottom" constant="50" id="dwl-xl-BBB"/>
-                        <constraint firstAttribute="trailing" secondItem="F0N-cX-RgR" secondAttribute="trailing" id="ghM-DY-BbR"/>
-                        <constraint firstAttribute="height" constant="430" id="gw8-rN-z4I"/>
-                        <constraint firstItem="YQ2-WU-vgs" firstAttribute="leading" secondItem="gXK-WE-Afp" secondAttribute="leading" constant="12" id="i9b-ZI-yVi"/>
-                        <constraint firstItem="7ve-MS-enP" firstAttribute="leading" secondItem="gXK-WE-Afp" secondAttribute="leading" id="tZn-J6-CNH"/>
-                    </constraints>
-                </view>
-            </subviews>
-            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-            <constraints>
-                <constraint firstItem="myZ-DO-7cl" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="1bo-Ol-UiG"/>
-                <constraint firstItem="myZ-DO-7cl" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="FZH-yl-Fe2"/>
-                <constraint firstItem="gXK-WE-Afp" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="ZfD-N1-XHF"/>
-                <constraint firstAttribute="trailing" secondItem="gXK-WE-Afp" secondAttribute="trailing" id="foF-yX-gee"/>
-                <constraint firstAttribute="bottom" secondItem="gXK-WE-Afp" secondAttribute="bottom" id="gBm-4V-His"/>
-                <constraint firstAttribute="trailing" secondItem="myZ-DO-7cl" secondAttribute="trailing" id="iIs-t4-wDe"/>
-                <constraint firstItem="gXK-WE-Afp" firstAttribute="top" secondItem="myZ-DO-7cl" secondAttribute="bottom" id="w87-7h-t39"/>
-            </constraints>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <connections>
-                <outlet property="bgImgView" destination="7ve-MS-enP" id="Sl1-vz-Fde"/>
-                <outlet property="bgView" destination="gXK-WE-Afp" id="4sA-Lt-G9r"/>
-                <outlet property="bgViewHeight" destination="gw8-rN-z4I" id="HR7-w9-KjM"/>
-                <outlet property="bottomView" destination="F0N-cX-RgR" id="zXl-ZU-Ran"/>
-                <outlet property="bottomViewTop" destination="UT5-Ia-kIx" id="wRQ-Te-X7g"/>
-                <outlet property="btnFour" destination="LbU-At-PsZ" id="QdN-7B-ybU"/>
-                <outlet property="btnOne" destination="PPf-Nh-Jhb" id="886-PN-DtX"/>
-                <outlet property="btnThree" destination="9qT-ga-6jJ" id="mTD-oV-NHN"/>
-                <outlet property="btnTwo" destination="O96-lR-gxD" id="slf-t7-3Mb"/>
-                <outlet property="customBtn" destination="IZ1-4L-eLj" id="uLd-Ck-3Xd"/>
-                <outlet property="giftNumBgView" destination="s7r-7d-RQo" id="9Sc-QU-uHA"/>
-                <outlet property="numStackView" destination="99w-uA-2ze" id="Iyy-cd-NVJ"/>
-                <outlet property="sendBtn" destination="EvQ-SR-4XV" id="oLo-o8-RFB"/>
-                <outlet property="zuanBgView" destination="YQ2-WU-vgs" id="P6V-Bk-tgp"/>
-                <outlet property="zuanBtnWidth" destination="2MD-dt-ssP" id="H9q-Lg-8sN"/>
-                <outlet property="zuanNumBtn" destination="5JE-RE-Wzz" id="5on-PG-R3V"/>
-            </connections>
-            <point key="canvasLocation" x="130.53435114503816" y="-11.267605633802818"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="icon_gift_zuan" width="16" height="16"/>
-        <image name="v_2_mine_white_right" width="12" height="12"/>
-    </resources>
-</document>

+ 324 - 0
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOGiftPanelsView.swift

@@ -0,0 +1,324 @@
+//
+//  MOGiftPanelsView.swift
+//  MiMoLive
+//
+//  Created by OneeChan on 2025/9/5.
+//
+
+import Foundation
+import UIKit
+import JXCategoryView
+import SnapKit
+
+@objc protocol MOGiftPanelsViewDelegate {
+    func onGiftPanelsViewSelectGift(view: MOGiftPanelsView, category: MOGiftCategoryList, giftMode: MOGiftlist, giftType: Int)
+    func onGiftPanelsViewFirstGiftSelected(category: MOGiftCategoryList)
+    func onGiftPanelsViewClickBagButton()
+    func onGiftPanelsViewScripeClick(script: MOStripe)
+    func onGiftPanelsViewSkinClick(skin: MOEffect)
+}
+
+@objcMembers
+class MOGiftPanelsView: UIView {
+    private let giftViewModel: MOGiftListViewModel
+    var isBag = false
+    var category = 0
+    var isHaveGiftCategory = false
+    
+    var delegate: MOGiftPanelsViewDelegate?
+    
+    private var listContainerView: JXCategoryListContainerView?
+    private var listContainerViewTop: Constraint?
+    private var categoryView: JXCategoryTitleView?
+    private var stripeView: MOStripeView?
+    private var bagButton: BigBtn?
+    private var bagRedView: UIView?
+    
+    init(_ viewModel: MOGiftListViewModel) {
+        giftViewModel = viewModel
+        super.init(frame: .zero)
+        
+        setupViews()
+        categoryView?.reloadData()
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    func toUpdateTheCurrentCollectionData() {
+        guard let selectedIndex = categoryView?.selectedIndex else { return }
+        let view = self.listContainerView?.validListDict[selectedIndex as NSNumber]
+        (view as? MOGiftCollectionView)?.toUpdataTheSelectIndexPathCell()
+    }
+    
+    func updateStripViewWith(
+        selected: MOGiftlist,
+        stripe: MOStripe?,
+        or skins: [MOEffect]?
+    ) {
+        if stripe?.title?.isEmpty == false || skins?.isEmpty == false {
+            self.stripeView?.isHidden = false
+            listContainerViewTop?.update(priority: .high)
+        }
+        else{
+            self.stripeView?.isHidden = true
+            listContainerViewTop?.update(priority: .low)
+            return;
+        }
+        
+        if skins?.isEmpty != false {
+            self.stripeView?.viewModel = stripe
+        } else {
+            self.stripeView?.selectGiftMode = selected
+            self.stripeView?.dataArr = skins
+        }
+    }
+    
+    func enableBagRedDot(_ enable: Bool) {
+        self.bagRedView?.isHidden = enable
+    }
+    
+    func handleResume() {
+        guard let selectedIndex = categoryView?.selectedIndex else { return }
+        let view = self.listContainerView?.validListDict[selectedIndex as NSNumber]
+        (view as? MOGiftCollectionView)?.listDidAppear()
+    }
+    
+    func toJudgeIsNeedChangeTheSelectTitle() {
+        if let giftModel = MOSvgaSourceManage.shareManager().hitGiftModel {
+            var theIndex = 0
+            var isHave = false
+            for mode in MOSvgaSourceManage.shareManager().giftCategoryArr {
+                if let mode = mode as? MOGiftCategoryList,
+                   mode.code == giftModel.giftCategory {
+                    isHave = true
+                    break
+                }
+                theIndex += 1
+            }
+            
+            if isHave {
+                self.categoryView?.selectItem(at: theIndex)
+            }
+        }
+    }
+}
+
+// MARK: JXCategoryViewDelegate
+extension MOGiftPanelsView: JXCategoryViewDelegate {
+    // 点击选中或者滚动选中都会调用该方法。适用于只关心选中事件,不关心具体是点击还是滚动选中的。
+    func categoryView(
+        _ categoryView: JXCategoryBaseView!,
+        didClickSelectedItemAt index: Int
+    ) {
+#if DEBUG
+        print("变换了 index - %zd",index);
+#endif
+        
+        //        self.lineView.hidden = NO;
+        //        [self.bottomMenuView selectGiftNum:1];
+        //        self.expView.giftNum = 1; // TODO: cwy
+        
+        if self.bagButton?.isSelected == true {
+            self.bagButton?.isSelected = false
+            self.categoryView?.titleSelectedColor = .white
+            self.categoryView?.reloadDataWithoutListContainer()
+        }
+        
+        UserDefaults.standard.set(index, forKey: kUserGiftSelectTypeNum)
+        UserDefaults.standard.synchronize()
+    }
+}
+
+// MARK: JXCategoryListContainerViewDelegate
+extension MOGiftPanelsView: JXCategoryListContainerViewDelegate {
+    func number(ofListsInlistContainerView listContainerView: JXCategoryListContainerView!) -> Int {
+        giftViewModel.categoryTitles.count
+    }
+    
+    func listContainerView(_ listContainerView: JXCategoryListContainerView!, initListFor index: Int) -> (any JXCategoryListContentViewDelegate)! {
+        let view = MOGiftCollectionView.init(giftViewModel)
+        // 选中回调
+        view.selectCellBlock = {
+            [weak self] selectGiftMode, giftType in
+            guard let self, let category = self.giftViewModel.category(at: index) else { return }
+            
+            self.category = giftType
+            self.delegate?
+                .onGiftPanelsViewSelectGift(
+                    view: self,
+                    category: category,
+                    giftMode: selectGiftMode,
+                    giftType: giftType
+                )
+        }
+        
+        // 第一个礼物回调
+        view.theFirstGiftBlock = { [weak self] in
+            guard let self, let category = self.giftViewModel.category(at: index) else { return }
+            self.delegate?.onGiftPanelsViewFirstGiftSelected(category: category)
+        }
+        
+        // 设置视图类型
+        if let category = self.giftViewModel.category(at: index) {
+            view.type = Int(category.code)
+        } else {
+            view.type = 1 // Hot
+        }
+        return view
+    }
+    
+}
+
+// MARK: UI 事件
+extension MOGiftPanelsView {
+    @objc private func handleBagButtonClick() {
+        self.bagRedView?.isHidden = true
+        self.delegate?.onGiftPanelsViewClickBagButton()
+    }
+}
+
+// MARK: UI 视图构建
+extension MOGiftPanelsView {
+    // UI 组装
+    private func setupViews() {
+        let category = buildCategoryTitleView()
+        addSubview(category)
+        category.snp.makeConstraints { make in
+            make.top.equalToSuperview()
+            make.leading.equalToSuperview().offset(12)
+            make.trailing.equalToSuperview().offset(-48)
+            make.height.equalTo(24)
+        }
+        category.indicators = [buildCategoryLine()]
+        self.categoryView = category
+        
+        let bagBtn = buildBagButton()
+        addSubview(bagBtn)
+        bagBtn.snp.makeConstraints { make in
+            make.trailing.equalToSuperview().offset(-12)
+            make.width.height.equalTo(24)
+            make.centerY.equalTo(category)
+        }
+        self.bagButton = bagBtn
+        
+        let redDot = buildBagRedView()
+        redDot.isHidden = true
+        addSubview(redDot)
+        redDot.snp.makeConstraints { make in
+            make.top.equalTo(bagBtn.snp.bottom).offset(2)
+            make.width.equalTo(10.0)
+            make.height.equalTo(1.5)
+            make.centerX.equalTo(bagBtn)
+        }
+        self.bagRedView = redDot
+        
+        let stripe = buildStripeView()
+        addSubview(stripe)
+        stripe.snp.makeConstraints { make in
+            make.leading.equalToSuperview().offset(12)
+            make.trailing.equalToSuperview().offset(-12)
+            make.height.equalTo(44)
+            make.top.equalTo(category.snp.bottom).offset(6)
+        }
+        self.stripeView = stripe
+        
+        let container = buildPanelContainerView()
+        addSubview(container)
+        container.snp.makeConstraints { make in
+            make.top.equalTo(category.snp.bottom).offset(6).priority(.medium)
+            listContainerViewTop = make.top
+                .equalTo(stripe.snp.bottom)
+                .priority(.low).constraint
+            make.leading.trailing.equalToSuperview()
+            make.bottom.equalToSuperview()
+        }
+        category.listContainer = container
+        self.listContainerView = container
+    }
+    
+    private func buildCategoryTitleView() -> JXCategoryTitleView {
+        let view = JXCategoryTitleView()
+        view.titles = giftViewModel.categoryTitles
+        view.isTitleColorGradientEnabled = true
+        view.titleColor = .white.withAlphaComponent(0.5)
+        view.titleSelectedColor = .white
+        view.titleFont = MOTextTools.poppinsRegularFont(14.0)
+        view.titleSelectedFont = MOTextTools.poppinsRegularFont(14.0)
+        view.contentEdgeInsetLeft = 0;
+        view.contentEdgeInsetRight = 0
+        view.isContentScrollViewClickTransitionAnimationEnabled = false
+        view.cellSpacing = 20.0
+        view.delegate = self
+        
+        let selectNum = UserDefaults.standard.integer(
+            forKey: "kUserGiftSelectTypeNum"
+        )
+        if selectNum < view.titles.count {
+            view.defaultSelectedIndex = selectNum
+        }
+        
+        return view
+    }
+    
+    private func buildCategoryLine() -> JXCategoryIndicatorLineView {
+        let view = JXCategoryIndicatorLineView()
+        view.indicatorColor = .white
+        //        view.indicatorWidth = kScaleWidth(10.0);
+        view.indicatorWidth = 10.0
+        view.indicatorHeight = 1.5
+        return view
+    }
+    
+    private func buildPanelContainerView() -> JXCategoryListContainerView {
+        let view = JXCategoryListContainerView(
+            type: .scrollView,
+            delegate: self
+        )
+        
+        return view!
+    }
+    
+    private func buildBagButton() -> BigBtn {
+        let button = BigBtn(type: .custom)
+        button.setImage(UIImage(named: "v_2_bag_48"), for: .normal)
+        button.setImage(UIImage(named: "v_2_bag_white_48"), for: .selected)
+        button
+            .addTarget(
+                self,
+                action: #selector(handleBagButtonClick),
+                for: .touchUpInside
+            )
+        
+        return button
+    }
+    
+    private func buildBagRedView() -> UIView {
+        let view = UIView()
+        view.layer.cornerRadius = 4
+        view.layer.masksToBounds = true
+        view.backgroundColor = .red
+        return view
+    }
+    
+    private func buildStripeView() -> MOStripeView {
+        let view = MOStripeView()
+        view.isHidden = true
+        view.stripeClickBlock = { [weak self] stripe in
+            guard let self else { return }
+            self.delegate?.onGiftPanelsViewScripeClick(script: stripe)
+        }
+        view.skinClickBlock = { [weak self] skin in
+            guard let self else { return }
+            if let index = self.categoryView?.selectedIndex,
+               let view = self.listContainerView?.validListDict[index as NSNumber] as? MOGiftCollectionView {
+                view.selectSkin = skin
+                view.toUpdataTheSelectIndexPathCell()
+            }
+            self.delegate?.onGiftPanelsViewSkinClick(skin: skin)
+        }
+        
+        return view
+    }
+}

+ 313 - 0
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOSendGiftView.swift

@@ -0,0 +1,313 @@
+//
+//  MOSendGiftView.swift
+//  MiMoLive
+//
+//  Created by OneeChan on 2025/9/3.
+//
+
+import Foundation
+import UIKit
+import Combine
+import SnapKit
+
+protocol MOSendGiftViewDelegate {
+    func sendGiftViewDidSelectNum(view: MOSendGiftView, num: Int, isCustom: Bool)
+    func sendGiftViewClickSend(view: MOSendGiftView)
+    func sendGiftViewClickCustom(view: MOSendGiftView)
+}
+
+class MOSendGiftView: UIView {
+    private static let nums = [1, 10, 99, 999]
+    
+    private var curNum = 1
+    
+    private var customNum: Int? = nil {
+        didSet {
+            if let customNum {
+                self.customLabel?.text = "\(customNum)"
+            }
+        }
+    }
+    
+    private var selectedViewTag: Int? = nil
+    private var numButtons: [UIView] = []
+    
+    private var customLabel: UILabel?
+    private var selectedViewBg: UIView?
+    private var sendButton: UIView?
+    
+    public var delegate: MOSendGiftViewDelegate?
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        
+        setupViews()
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    func updateGiftNum(_ num: Int) {
+        guard let index = Self.nums.firstIndex(of: num) else { return }
+        guard let view = numButtons.first(where: { $0.tag == index }) else { return }
+        curNum = num
+        updateSelectedView(view)
+    }
+    
+    func curGiftNum() -> Int {
+        return curNum
+    }
+    
+    func enableGiftNum(_ enable: Bool) {
+        subviews.forEach { view in
+            if view != sendButton {
+                view.isHidden = !enable
+            }
+        }
+        if !enable {
+            curNum = 1
+        }
+    }
+    
+    func updateCustomNum(_ num: Int) {
+        customNum = num
+        curNum = num
+        guard let view = numButtons.first(where: { $0.tag == Self.nums.count }) else { return }
+        updateSelectedView(view)
+    }
+}
+
+// MARK: UI 事件
+extension MOSendGiftView {
+    @objc
+    private func handleGiftNumClick(_ sender: UIButton) {
+        let index = sender.tag
+        guard index < Self.nums.count else { return }
+        let num = Self.nums[index]
+        self.curNum = num
+        self.updateSelectedView(sender)
+        self.delegate?.sendGiftViewDidSelectNum(view: self, num: num, isCustom: false)
+    }
+    
+    @objc
+    private func handleCustomClick(_ sender: UIButton) {
+        if let customNum, sender.tag != self.selectedViewTag {
+            self.curNum = customNum
+            updateSelectedView(sender)
+            self.delegate?.sendGiftViewDidSelectNum(view: self, num: customNum, isCustom: true)
+            return
+        }
+        
+        self.delegate?.sendGiftViewClickCustom(view: self)
+    }
+    
+    @objc
+    private func handleSendClick() {
+        self.delegate?.sendGiftViewClickSend(view: self)
+    }
+    
+    private func updateSelectedView(_ view: UIView) {
+        self.selectedViewTag = view.tag
+        self.selectedViewBg?.snp.remakeConstraints({ make in
+            make.centerX.width.equalTo(view)
+            make.centerY.height.equalToSuperview()
+        })
+        UIView.animate(withDuration: 0.3) {
+            self.layoutIfNeeded()
+        }
+    }
+}
+
+// MARK: UI 视图构建
+extension MOSendGiftView {
+    override func layoutSubviews() {
+        super.layoutSubviews()
+        
+        selectedViewBg?.layer.sublayers?.forEach({ layer in
+            if layer is CAGradientLayer {
+                layer.frame = selectedViewBg!.bounds
+            }
+        })
+        sendButton?.layer.sublayers?.forEach({ layer in
+            if layer is CAGradientLayer {
+                layer.frame = sendButton!.bounds
+            }
+        })
+    }
+    
+    // UI 组装
+    private func setupViews() {
+        let container = UIView()
+        container.backgroundColor = .white.withAlphaComponent(0.16)
+        container.layer.cornerRadius = 10
+        addSubview(container)
+        container.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+        let selectedBg = buildSelectedBgView()
+        addSubview(selectedBg)
+        self.selectedViewBg = selectedBg
+        
+        var leading: UIView = container
+        for (index, num) in Self.nums.enumerated() {
+            let button = buildGiftNumView(index, num)
+            addSubview(button)
+            button.snp.makeConstraints { make in
+                make.centerY.equalToSuperview()
+                if leading == container {
+                    make.leading.equalToSuperview()
+                } else {
+                    make.leading.equalTo(leading.snp.trailing)
+                    make.width.equalTo(leading)
+                }
+            }
+            leading = button
+            if index == 0 {
+                updateSelectedView(button)
+            }
+        }
+        
+        let custom = buildCustomView()
+        addSubview(custom)
+        custom.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.leading.equalTo(leading.snp.trailing)
+        }
+        
+        let send = buildSendButton()
+        addSubview(send)
+        send.snp.makeConstraints { make in
+            make.top.bottom.trailing.equalToSuperview()
+            make.leading.equalTo(custom.snp.trailing)
+        }
+        sendButton = send
+    }
+    
+    // 数量选中的背景
+    private func buildSelectedBgView() -> UIView {
+        let container = UIView()
+        
+        let graLayer = CAGradientLayer()
+        graLayer.startPoint = CGPoint(x: 0, y: 0.5)
+        graLayer.endPoint = CGPoint(x: 1, y: 0.5)
+        graLayer.colors = [UIColor(red: 255/255.0, green: 77/255.0, blue: 166/255.0, alpha: 1).cgColor,
+                           UIColor(red: 67/255.0, green: 99/255.0, blue: 255/255.0, alpha: 1).cgColor];
+        graLayer.locations = [0, 1.0]
+        container.layer.insertSublayer(graLayer, at: 0)
+        container.layer.cornerRadius = 10
+        container.layer.masksToBounds = true
+        
+        let cover = UIView()
+        cover.backgroundColor = .black.withAlphaComponent(0.4)
+        cover.layer.cornerRadius = 10
+        container.addSubview(cover)
+        cover.snp.makeConstraints { make in
+            make.edges.equalToSuperview().inset(0.5)
+        }
+        
+        return container
+    }
+    
+    // 每个数量的视图
+    private func buildGiftNumView(_ index: Int, _ num: Int) -> UIView {
+        let button = UIButton()
+        button.tag = index
+        button.setTitle("\(num)", for: .normal)
+        button.titleLabel?.font = MOTextTools.mediumFont(12.0)
+        button.addTarget(self, action: #selector(handleGiftNumClick), for: .touchUpInside)
+        
+        numButtons.append(button)
+        
+        return button
+    }
+    
+    // 自定义数量视图
+    private func buildCustomView() -> UIView {
+        let custom = UIButton()
+        custom.tag = Self.nums.count
+        custom.addTarget(self, action: #selector(handleCustomClick), for: .touchUpInside)
+        
+        let title = UILabel()
+        title.textColor = .white
+        title.text = "Cust"
+        title.font = MOTextTools.mediumFont(12.0)
+        custom.addSubview(title)
+        title.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.leading.equalToSuperview().offset(16)
+        }
+        self.customLabel = title
+        
+        let ic = UIImageView()
+        ic.tintColor = .white
+        ic.image = UIImage(named: "icon_create_edit")
+        custom.addSubview(ic)
+        ic.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.leading.equalTo(title.snp.trailing)
+            make.trailing.equalToSuperview().offset(-16)
+            make.width.height.equalTo(9)
+        }
+        
+        numButtons.append(custom)
+        
+        return custom
+    }
+    
+    // 发送按钮
+    private func buildSendButton() -> UIView {
+        let send = UIButton()
+        send.addTarget(self, action: #selector(handleSendClick), for: .touchUpInside)
+        send.layer.cornerRadius = 10
+        
+        let title = UILabel()
+        title.text = "Send"
+        title.font = MOTextTools.mediumFont(12.0)
+        title.textColor = .white
+        send.addSubview(title)
+        title.snp.makeConstraints { make in
+            make.edges.equalToSuperview().inset(UIEdgeInsets(top: 6, left: 16, bottom: 6, right: 16))
+        }
+        
+        let graLayer = CAGradientLayer()
+        graLayer.startPoint = CGPoint(x: 0, y: 0.5)
+        graLayer.endPoint = CGPoint(x: 1, y: 0.5)
+        graLayer.colors = [UIColor(red: 255/255.0, green: 77/255.0, blue: 166/255.0, alpha: 1).cgColor,
+                           UIColor(red: 67/255.0, green: 99/255.0, blue: 255/255.0, alpha: 1).cgColor];
+        graLayer.locations = [0, 1.0]
+        send.layer.insertSublayer(graLayer, at: 0)
+        send.layer.cornerRadius = 10
+        send.layer.masksToBounds = true
+        
+        return send
+    }
+}
+
+//#if DEBUG
+//import SwiftUI
+//
+//struct MOSendGiftViewPreview: UIViewRepresentable {
+//    func makeUIView(context: Context) -> some UIView {
+//        let container = UIView()
+//        container.backgroundColor = .black
+//        let view = MOSendGiftView()
+//        container.addSubview(view)
+//        view.snp.makeConstraints { make in
+//            make.center.equalToSuperview()
+//            make.leading.trailing.equalToSuperview()
+//        }
+//        return container
+//    }
+//    
+//    func updateUIView(_ uiView: UIViewType, context: Context) { }
+//}
+//
+//#Preview(body: {
+//    ZStack {
+//        MOSendGiftViewPreview()
+//    }
+//})
+//
+//#endif

+ 2 - 2
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/GiftListView/MOStripeView/MOStripeView.h

@@ -19,9 +19,9 @@ NS_ASSUME_NONNULL_BEGIN
 
 @property (nonatomic, assign) MOStripeViewType viewType;
 
-@property (nonatomic, strong) NSArray *dataArr;//礼物皮肤源
+@property (nonatomic, strong, nullable) NSArray *dataArr;//礼物皮肤源
 
-@property (nonatomic, strong) MOStripe *viewModel;//词条
+@property (nonatomic, strong, nullable) MOStripe *viewModel;//词条
 @property (nonatomic, copy) void (^stripeClickBlock)(MOStripe *stripe);//词条点击
 
 @property (nonatomic, strong) MOGiftlist *selectGiftMode;

+ 2 - 0
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/MOShowRoomLiveView.h

@@ -333,6 +333,8 @@ typedef void(^MsgTableViewpanGestureBeganBlock)(BOOL beginPan);
 @property (nonatomic, strong) NSMutableArray *loveBubbleArr;
 //震动反馈
 @property (nonatomic, strong) UIImpactFeedbackGenerator *generator;
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *canvasBottomOffset;
+
 /** 添加气泡 */
 - (void)addLoveBubbleWith:(NSInteger)clickNum;
 /** 缓存气泡数据 */

+ 5 - 5
MiMoLive/MiMoLive/Classes/Live/View/LiveingView/MOShowRoomLiveView.xib

@@ -1,9 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23727" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="24128" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina6_12" orientation="portrait" appearance="light"/>
     <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24063"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -375,7 +374,7 @@
                 <constraint firstItem="0oa-aM-t0W" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="JDD-yT-D9q"/>
                 <constraint firstAttribute="bottom" secondItem="oMl-2P-fhx" secondAttribute="bottom" id="KZB-sm-paW"/>
                 <constraint firstItem="PuI-bj-9j8" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="42" id="LH3-re-e8L"/>
-                <constraint firstItem="0oa-aM-t0W" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="NZl-N2-oPW"/>
+                <constraint firstItem="0oa-aM-t0W" firstAttribute="height" secondItem="iN0-l3-epB" secondAttribute="height" id="MS8-g2-1fS"/>
                 <constraint firstAttribute="bottom" secondItem="2Le-US-MhH" secondAttribute="bottom" id="Yx1-IC-Wt7"/>
                 <constraint firstAttribute="trailing" secondItem="oMl-2P-fhx" secondAttribute="trailing" id="cjJ-d5-TGB"/>
                 <constraint firstAttribute="bottom" secondItem="0oa-aM-t0W" secondAttribute="bottom" id="eVs-w6-wzk"/>
@@ -389,6 +388,7 @@
                 <outlet property="bgViewLeft" destination="DTN-bP-0mI" id="WdT-Lq-y2x"/>
                 <outlet property="bgViewWidth" destination="Pwb-TY-q5x" id="Q0c-4p-Bwm"/>
                 <outlet property="bottomLeftBgView" destination="4OT-3H-i2S" id="GMq-r3-DQ6"/>
+                <outlet property="canvasBottomOffset" destination="eVs-w6-wzk" id="4n9-VM-TAQ"/>
                 <outlet property="canvasView" destination="0oa-aM-t0W" id="OmV-8m-hMW"/>
                 <outlet property="chatBtn" destination="gxJ-DZ-TiB" id="beX-id-ico"/>
                 <outlet property="cleanCloseBtn" destination="PuI-bj-9j8" id="DtR-qE-VsR"/>
@@ -447,7 +447,7 @@
             <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
         </systemColor>
         <systemColor name="systemRedColor">
-            <color red="1" green="0.23137254901960785" blue="0.18823529411764706" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+            <color red="1" green="0.2196078431372549" blue="0.23529411764705882" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
         </systemColor>
     </resources>
 </document>

+ 187 - 0
MiMoLive/MiMoLive/Classes/Live/View/MOComboSendGiftView/MOComboCountDownView.swift

@@ -0,0 +1,187 @@
+//
+//  MOComboCountDownView.swift
+//  MiMoLive
+//
+//  Created by OneeChan on 2025/9/3.
+//
+
+import Foundation
+import UIKit
+import SnapKit
+
+class MOComboCountDownView: UIView {
+    // 圆环属性
+    private static let lineWidth: CGFloat = 4
+    
+    // 进度相关
+    private static let delayCount: TimeInterval = 0.2 // 延时倒计时
+    private static let totalDuration: TimeInterval = 4 - delayCount
+    private static let timerInterval: TimeInterval = 0.05
+    private var currentProgress: CGFloat = 1.0
+    private var countdownTimer: Timer?
+    private var startTime: Date?
+    
+    // 图层
+    private let progressLayer = CAShapeLayer()
+    private let gradientLayer = CAGradientLayer()
+    
+    // 倒计时结束回调
+    var onCountdownFinished: (() -> Void)?
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        setupLayers()
+    }
+    
+    required init?(coder: NSCoder) {
+        super.init(coder: coder)
+        setupLayers()
+    }
+    
+    deinit {
+        countdownTimer?.invalidate()
+    }
+    
+    // 开始倒计时
+    func startCountdown() {
+        countdownTimer?.invalidate()
+        
+        // 重置状态
+        currentProgress = 1.0
+        CATransaction.begin()
+        CATransaction.setDisableActions(true)
+        progressLayer.strokeEnd = currentProgress
+        CATransaction.commit()
+        
+        // 延迟开始倒计时,避免每次都无法从起始点开始
+        NSObject.cancelPreviousPerformRequests(withTarget: self)
+        self.perform(#selector(startTimer), afterDelay: Self.delayCount)
+    }
+    
+    // 暂停倒计时
+    func pauseCountdown() {
+        countdownTimer?.invalidate()
+    }
+    
+    // 重置倒计时
+    func resetCountdown() {
+        countdownTimer?.invalidate()
+        
+        currentProgress = 1.0
+        CATransaction.begin()
+        CATransaction.setDisableActions(true)
+        progressLayer.strokeEnd = currentProgress
+        CATransaction.commit()
+    }
+    
+    func updateGradientColor(_ colors: [UIColor]) {
+        gradientLayer.colors = colors.map { $0.cgColor }
+    }
+}
+
+// MARK: Private
+extension MOComboCountDownView {
+    @objc private func startTimer() {
+        startTime = Date()
+        countdownTimer = Timer
+            .scheduledTimer(withTimeInterval: Self.timerInterval, repeats: true) { [weak self] _ in
+                self?.updateProgress()
+            }
+    }
+}
+
+// MARK: UI 视图构建
+extension MOComboCountDownView {
+    // UI 组装
+    private func setupLayers() {
+        // 配置进度图层
+        progressLayer.fillColor = UIColor.clear.cgColor
+        progressLayer.strokeColor = UIColor.white.cgColor
+        progressLayer.lineCap = .butt
+        progressLayer.strokeEnd = 0.9
+        layer.addSublayer(progressLayer)
+        
+        // 配置渐变图层
+        gradientLayer.colors = [UIColor.systemOrange, UIColor.systemYellow]
+            .map { $0.cgColor }
+        gradientLayer.mask = progressLayer
+        gradientLayer.startPoint = CGPoint(x: 0, y: 1)
+        gradientLayer.endPoint = CGPoint(x: 1, y: 0)
+        layer.addSublayer(gradientLayer)
+    }
+    
+    override func layoutSubviews() {
+        super.layoutSubviews()
+        
+        // 更新图层帧
+        let center = CGPoint(x: bounds.midX, y: bounds.midY)
+        let radius = (min(bounds.width, bounds.height) - Self.lineWidth) / 2
+        let startAngle = -CGFloat.pi / 2
+        let endAngle = startAngle + 2 * CGFloat.pi
+        
+        // 创建圆环路径
+        let path = UIBezierPath(arcCenter: center,
+                                radius: radius,
+                                startAngle: startAngle,
+                                endAngle: endAngle,
+                                clockwise: true)
+        
+        // 更新进度图层
+        progressLayer.path = path.cgPath
+        progressLayer.lineWidth = Self.lineWidth
+        progressLayer.frame = bounds
+        
+        // 更新渐变图层
+        gradientLayer.frame = bounds
+    }
+    
+    // 更新进度
+    private func updateProgress() {
+        guard let startTime = startTime else { return }
+        
+        let elapsedTime = Date().timeIntervalSince(startTime)
+        currentProgress = 1.0 - CGFloat(elapsedTime / Self.totalDuration)
+        
+        if currentProgress <= 0 {
+            currentProgress = 0
+            progressLayer.strokeEnd = currentProgress
+            countdownTimer?.invalidate()
+            onCountdownFinished?()
+        } else {
+            // 使用隐式动画使进度变化更平滑
+            progressLayer.strokeEnd = currentProgress
+        }
+    }
+}
+
+//#if DEBUG
+//import SwiftUI
+//
+//struct MOComboCountDownViewPreview: UIViewRepresentable {
+//    func makeUIView(context: Context) -> some UIView {
+//        let container = UIView()
+//        container.backgroundColor = .black
+//        
+//        let view = MOComboCountDownView()
+//        container.addSubview(view)
+//        view.snp.makeConstraints { make in
+//            make.center.equalToSuperview()
+//            make.width.height.equalTo(100)
+//        }
+//        view.startCountdown()
+//        
+//        return container
+//    }
+//    
+//    func updateUIView(_ uiView: UIViewType, context: Context) {
+//        
+//    }
+//}
+//
+//#Preview(body: {
+//    VStack {
+//        MOComboCountDownViewPreview()
+//    }
+//})
+//
+//#endif

+ 407 - 0
MiMoLive/MiMoLive/Classes/Live/View/MOComboSendGiftView/MOGiftComboView.swift

@@ -0,0 +1,407 @@
+//
+//  MOGiftComboView.swift
+//  MiMoLive
+//
+//  Created by OneeChan on 2025/9/2.
+//
+
+import Foundation
+import UIKit
+import Combine
+
+// 每个 Combo 阶段的 UI 配置
+private class MOGiftComboLevelUIConfig {
+    let circleColors: [UIColor]
+    let comboIcName: String
+    
+    init(
+        _ circleColors: [UIColor],
+        _ comboIcName: String
+    ) {
+        self.circleColors = circleColors
+        self.comboIcName = comboIcName
+    }
+}
+
+@objc protocol MOGiftComboViewDelegate {
+    func giftComboViewOnCountdownFinished(view: MOGiftComboView)
+    func giftComboViewOnComboFired(view: MOGiftComboView, combo: Int)
+    
+    @objc optional
+    func giftComboViewRequireHideGiftPanel(view: MOGiftComboView)
+}
+
+@objcMembers
+class MOGiftComboView: UIView {
+    weak var delegate: MOGiftComboViewDelegate?
+    
+    // 监听相关
+    private var cur = 0 {
+        didSet {
+            handleComboChange()
+        }
+    }
+    
+    // 视图相关
+    private var animateView: UIImageView?
+    private var comboView: UIView?
+    private var comboIc: UIImageView?
+    private var countLabel: UILabel?
+    private var countDownView: MOComboCountDownView?
+    
+    //震动反馈
+    private let feedback = UIImpactFeedbackGenerator()
+    
+    // 长按
+    private var longPressTimer: Timer?
+    
+    private var firstFireTime: Date?
+    var needResumeGiftPanel: Bool = false
+    
+    private static let animaConfig = [
+        5: "icon_gift_combo_lv_1",
+        20: "icon_gift_combo_lv_2",
+        50: "icon_gift_combo_lv_3",
+        100: "icon_gift_combo_lv_4"
+    ]
+    private static let levelConfig = [
+        1:  MOGiftComboLevelUIConfig(
+            [
+                MOTools.color(withHexString: "#FF4DA6"),
+                MOTools.color(withHexString: "#4363FF")
+            ],
+            "icon_combo_lv1"
+        ),
+        7:  MOGiftComboLevelUIConfig(
+            [
+                MOTools.color(withHexString: "#FF6B4D"),
+                MOTools.color(withHexString: "#F441FF")
+            ],
+            "icon_combo_lv2"
+        ),
+        13:  MOGiftComboLevelUIConfig(
+            [
+                MOTools.color(withHexString: "#FF894D"),
+                MOTools.color(withHexString: "#FF2A2A")
+            ],
+            "icon_combo_lv3"
+        ),
+        19:  MOGiftComboLevelUIConfig(
+            [
+                MOTools.color(withHexString: "#FFBB4D"),
+                MOTools.color(withHexString: "#FF652A")
+            ],
+            "icon_combo_lv4"
+        ),
+    ]
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        
+        setupViews()
+        
+        feedback.prepare()
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    deinit {
+        stopLongPressTimer()
+    }
+    
+    func startCombo() {
+        showPopupAnimate()
+        countDownView?.resetCountdown()
+        self.cur = 1
+        countDownView?.startCountdown()
+        firstFireTime = Date()
+    }
+    
+    func stopCombo() {
+        countDownView?.pauseCountdown()
+        needResumeGiftPanel = false
+        self.delegate?.giftComboViewOnCountdownFinished(view: self)
+    }
+}
+
+// MARK: UI 事件
+extension MOGiftComboView {
+    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
+        let view = super.hitTest(point, with: event)
+        
+        if (view == nil) {
+            self.stopCombo()
+        }
+        
+        return view
+    }
+    
+    private func handleComboChange() {
+        self.countLabel?.text = "x\(cur)"
+        
+        // 阶段变更
+        if let config = Self.levelConfig[cur]  {
+            countDownView?.updateGradientColor(config.circleColors)
+            comboIc?.image = UIImage(named: config.comboIcName)
+        }
+        if let src = Self.animaConfig[cur],
+           let animaPath = Bundle.main.path(
+            forResource: src,
+            ofType: "webp"
+           ) {
+            let fileUrl = URL(fileURLWithPath: animaPath)
+            animateView?
+                .sd_setImage(with: fileUrl) { [weak self] image, _, _, _ in
+                    guard let self else { return }
+                    self.showComboLevelAnimate(image?.duration ?? 0)
+                }
+        }
+    }
+    
+    @objc
+    private func handleComboClick() {
+        cur += 1
+        showComboScaleAnimate()
+        countDownView?.resetCountdown()
+        countDownView?.startCountdown()
+        feedback.impactOccurred()
+        
+        self.delegate?.giftComboViewOnComboFired(view: self, combo: cur)
+        
+        if !self.needResumeGiftPanel, let firstFireTime, Date()
+            .timeIntervalSince(firstFireTime) > 4 {
+            // combo 超过 4 秒,需要自动收起礼物面板
+            self.needResumeGiftPanel = true
+            self.delegate?.giftComboViewRequireHideGiftPanel?(view: self)
+        }
+    }
+}
+
+// MARK: 长按
+extension MOGiftComboView {
+    private func setupLongPressGesture(_ view: UIView) {
+        let longPress = UILongPressGestureRecognizer(
+            target: self,
+            action: #selector(handleLongPress(_:))
+        )
+        longPress.minimumPressDuration = 0.5 // 长按0.5秒后开始触发
+        view.addGestureRecognizer(longPress)
+    }
+    
+    @objc
+    private func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
+        switch gesture.state {
+        case .began:
+            // 长按开始:启动定时器,每0.3秒触发一次事件
+            startLongPressTimer()
+        case .ended, .cancelled, .failed:
+            // 长按结束/取消/失败:停止定时器
+            stopLongPressTimer()
+        default:
+            // 其他状态(如长按中移动):不处理
+            break
+        }
+    }
+    
+    // 长按启动定时器
+    private func startLongPressTimer() {
+        // 避免重复创建定时器
+        guard longPressTimer == nil else { return }
+        
+        let timer = Timer.scheduledTimer(
+            timeInterval: 0.3,
+            target: self,
+            selector: #selector(handleComboClick),
+            userInfo: nil,
+            repeats: true
+        )
+        
+        // 将定时器加入RunLoop,确保在滑动等场景下也能正常触发
+        RunLoop.current.add(timer, forMode: .common)
+        longPressTimer = timer
+    }
+    
+    // 停止定时器
+    private func stopLongPressTimer() {
+        longPressTimer?.invalidate()
+        longPressTimer = nil
+    }
+}
+
+// MARK: Animation 动画
+extension MOGiftComboView {
+    private func showPopupAnimate() {
+        layer.removeAllAnimations()
+        // 缩放动画
+        let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
+        scaleAnimation.fromValue = 0.0
+        scaleAnimation.toValue = 1.0
+        scaleAnimation.duration = 0.1
+        scaleAnimation.timingFunction = .init(name: .easeInEaseOut)
+        
+        layer.add(scaleAnimation, forKey: nil)
+    }
+    
+    private func showComboScaleAnimate() {
+        comboView?.layer.removeAllAnimations()
+        // 缩放动画
+        let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
+        scaleAnimation.fromValue = 1.0
+        scaleAnimation.toValue = 0.96
+        scaleAnimation.duration = 0.1
+        scaleAnimation.timingFunction = .init(name: .easeInEaseOut)
+        
+        comboView?.layer.add(scaleAnimation, forKey: nil)
+    }
+    
+    private func showComboLevelAnimate(_ duration: Double) {
+        if duration == 0 { return }
+        
+        animateView?.isHidden = false
+        
+        countLabel?.layer.removeAllAnimations()
+        // 缩放动画
+        let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
+        scaleAnimation.fromValue = 0
+        scaleAnimation.toValue = 0.0
+        scaleAnimation.duration = duration
+        scaleAnimation.delegate = self
+        scaleAnimation.timingFunction = .init(name: .easeInEaseOut)
+        
+        countLabel?.layer.add(scaleAnimation, forKey: nil)
+    }
+}
+
+extension MOGiftComboView: CAAnimationDelegate {
+    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
+        animateView?.isHidden = true
+    }
+}
+
+// MARK: UI 视图构建
+extension MOGiftComboView {
+    // UI 组装
+    private func setupViews() {
+        let animateView = buildAnimateView()
+        addSubview(animateView)
+        animateView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+            make.width.equalTo(140)
+            make.height.equalTo(196)
+        }
+        
+        let combo = buildComboView()
+        addSubview(combo)
+        combo.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.bottom.equalToSuperview().offset(-10)
+        }
+        self.comboView = combo
+        
+        let countView = buildCountView()
+        addSubview(countView)
+        countView.snp.makeConstraints { make in
+            make.centerX.equalToSuperview()
+            make.bottom.equalTo(combo.snp.top).offset(-12)
+        }
+        
+        let button = UIButton()
+        button
+            .addTarget(
+                self,
+                action: #selector(handleComboClick),
+                for: .touchUpInside
+            )
+        addSubview(button)
+        button.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
+        setupLongPressGesture(button)
+    }
+    
+    // 播放每个阶段的动画界面
+    private func buildAnimateView() -> UIView {
+        let animateView = UIImageView()
+        animateView.isHidden = true
+        
+        self.animateView = animateView
+        
+        return animateView
+    }
+    
+    // 展示 Combo 数的界面
+    private func buildCountView() -> UIView {
+        let label = UILabel()
+        label.font = MOTextTools.boldFont(22).withBoldItalic()
+        label.textColor = .white
+        
+        self.countLabel = label
+        
+        return label
+    }
+    
+    // Combo 界面
+    private func buildComboView() -> UIView {
+        let container = UIView()
+        
+        let comboIc = UIImageView()
+        container.addSubview(comboIc)
+        comboIc.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        self.comboIc = comboIc
+        
+        let countDown = MOComboCountDownView()
+        countDown.onCountdownFinished = { [weak self] in
+            guard let self else { return }
+            self.delegate?.giftComboViewOnCountdownFinished(view: self)
+        }
+        container.addSubview(countDown)
+        countDown.snp.makeConstraints { make in
+            make.center.equalToSuperview()
+            make.width.equalTo(comboIc).offset(10)
+            make.height.equalTo(comboIc).offset(10)
+        }
+        
+        self.countDownView = countDown
+        
+        return container
+    }
+}
+
+//#if DEBUG
+//import SwiftUI
+//
+//struct MOGiftComboViewPreview: UIViewRepresentable {
+//    func makeUIView(context: Context) -> some UIView {
+//        let container = UIView()
+//        container.backgroundColor = .black
+//        let view = MOGiftComboView()
+//        view.onCountdownFinished = {
+//            
+//        }
+//        view.onComboFired = {
+//            
+//        }
+//        container.addSubview(view)
+//        view.snp.makeConstraints { make in
+//            make.center.equalToSuperview()
+//            make.width.height.equalTo(150)
+//        }
+//        view.startCombo()
+//        return container
+//    }
+//    
+//    func updateUIView(_ uiView: UIViewType, context: Context) { }
+//}
+//
+//#Preview(body: {
+//    ZStack {
+//        MOGiftComboViewPreview()
+//    }
+//})
+//
+//#endif

BIN
MiMoLive/MiMoLive/File/Gift/icon_gift_combo_lv_1.webp


BIN
MiMoLive/MiMoLive/File/Gift/icon_gift_combo_lv_2.webp


BIN
MiMoLive/MiMoLive/File/Gift/icon_gift_combo_lv_3.webp


BIN
MiMoLive/MiMoLive/File/Gift/icon_gift_combo_lv_4.webp


BIN
MiMoLive/MiMoLive/File/Gift/icon_gift_selected_bg.webp


+ 1 - 1
MiMoLive/MiMoLive/Global/MOGlobal.h

@@ -11,7 +11,7 @@
 /**
  * kAPP_Environment 1为正式环境 2为测试环境
  */
-#define kAPP_Environment 1
+#define kAPP_Environment 2
 
 #if kAPP_Environment == 1
 #pragma mark - 正式环境配置

+ 4 - 0
MiMoLive/MiMoLive/MiMoLive-Bridging-Header.h

@@ -8,6 +8,7 @@
 #import "MODataCache.h"
 #import "MOLiveList.h"
 #import "MOGiftList.h"
+#import "MOShopList.h"
 #import "MOHttpManager.h"
 #import "MODataManager.h"
 #import "MBProgressHUD.h"
@@ -34,3 +35,6 @@
 #import "MOSystemAlertView.h"
 #import "MOAgoraRTMManager.h"
 #import "MOHeadCustomView.h"
+#import "MOStripeView.h"
+#import "MOGiftCollectionView.h"
+#import "MOStripe.h"

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