Browse Source

首界面 UI

jsonwang 4 năm trước cách đây
mục cha
commit
3766a60837
29 tập tin đã thay đổi với 1001 bổ sung29 xóa
  1. 54 2
      MusicVideoPlus/MusicVideoPlus.xcodeproj/project.pbxproj
  2. 4 3
      MusicVideoPlus/MusicVideoPlus/AppDelegate.swift
  3. 23 0
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/home_marks.imageset/Contents.json
  4. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/home_marks.imageset/home_marks.png
  5. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/home_marks.imageset/home_marks@2x.png
  6. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/home_marks.imageset/home_marks@3x.png
  7. 23 0
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/reCreate.imageset/Contents.json
  8. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/reCreate.imageset/reCreate.png
  9. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/reCreate.imageset/reCreate@2x.png
  10. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/reCreate.imageset/reCreate@3x.png
  11. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/set.imageset/set.png
  12. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/set.imageset/set@2x.png
  13. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/set.imageset/set@3x.png
  14. 22 0
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/videomk_music_default.imageset/Contents.json
  15. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/videomk_music_default.imageset/videomk_music_default@2x.png
  16. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/videomk_music_default.imageset/videomk_music_default@3x.png
  17. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/wode.imageset/wode.png
  18. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/wode.imageset/wode@2x.png
  19. BIN
      MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/wode.imageset/wode@3x.png
  20. 153 24
      MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/MVHomeController.swift
  21. 47 0
      MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Models/MVTagsModel.swift
  22. 68 0
      MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/ViewModels/MVHomeViewModel.swift
  23. 261 0
      MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/Banner/MVBanner.swift
  24. 108 0
      MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/Banner/MVBannerFlowLayout.swift
  25. BIN
      MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/Banner/images/banner0.jpeg
  26. BIN
      MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/Banner/images/banner1.jpeg
  27. BIN
      MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/Banner/images/banner2.jpeg
  28. 142 0
      MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/MVBannerCell.swift
  29. 96 0
      MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/MVTagsCell.swift

+ 54 - 2
MusicVideoPlus/MusicVideoPlus.xcodeproj/project.pbxproj

@@ -7,6 +7,15 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		4112DD832669BFA600A5AFD9 /* MVBanner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4112DD822669BFA600A5AFD9 /* MVBanner.swift */; };
+		4112DD862669BFFA00A5AFD9 /* MVBannerFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4112DD852669BFFA00A5AFD9 /* MVBannerFlowLayout.swift */; };
+		4112DD8C2669C0F500A5AFD9 /* banner2.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = 4112DD892669C0F500A5AFD9 /* banner2.jpeg */; };
+		4112DD8D2669C0F500A5AFD9 /* banner1.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = 4112DD8A2669C0F500A5AFD9 /* banner1.jpeg */; };
+		4112DD8E2669C0F500A5AFD9 /* banner0.jpeg in Resources */ = {isa = PBXBuildFile; fileRef = 4112DD8B2669C0F500A5AFD9 /* banner0.jpeg */; };
+		4112DD912669C11C00A5AFD9 /* MVBannerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4112DD902669C11C00A5AFD9 /* MVBannerCell.swift */; };
+		4149C8932669FE6F0055CAA2 /* MVTagsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4149C8922669FE6F0055CAA2 /* MVTagsCell.swift */; };
+		4149C8962669FE9D0055CAA2 /* MVTagsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4149C8952669FE9D0055CAA2 /* MVTagsModel.swift */; };
+		417D868C266A2E8400DA2444 /* MVHomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 417D868B266A2E8400DA2444 /* MVHomeViewModel.swift */; };
 		418532302665342100DCA2C1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4185322F2665342100DCA2C1 /* AppDelegate.swift */; };
 		418532392665342200DCA2C1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 418532382665342200DCA2C1 /* Assets.xcassets */; };
 		41CA6E5E266782EC00874B19 /* MVBaseController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41CA6E5D266782EC00874B19 /* MVBaseController.swift */; };
@@ -24,6 +33,15 @@
 		3FA19A38D145C54301B3CD85 /* Pods_MusicVideoPlus.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MusicVideoPlus.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		4112DCF02668C45B00A5AFD9 /* MusicVideoPlus.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MusicVideoPlus.entitlements; sourceTree = "<group>"; };
 		4112DD492668D6A600A5AFD9 /* MusicVideoPlus-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MusicVideoPlus-Bridging-Header.h"; sourceTree = "<group>"; };
+		4112DD822669BFA600A5AFD9 /* MVBanner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVBanner.swift; sourceTree = "<group>"; };
+		4112DD852669BFFA00A5AFD9 /* MVBannerFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVBannerFlowLayout.swift; sourceTree = "<group>"; };
+		4112DD892669C0F500A5AFD9 /* banner2.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = banner2.jpeg; sourceTree = "<group>"; };
+		4112DD8A2669C0F500A5AFD9 /* banner1.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = banner1.jpeg; sourceTree = "<group>"; };
+		4112DD8B2669C0F500A5AFD9 /* banner0.jpeg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = banner0.jpeg; sourceTree = "<group>"; };
+		4112DD902669C11C00A5AFD9 /* MVBannerCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MVBannerCell.swift; sourceTree = "<group>"; };
+		4149C8922669FE6F0055CAA2 /* MVTagsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVTagsCell.swift; sourceTree = "<group>"; };
+		4149C8952669FE9D0055CAA2 /* MVTagsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVTagsModel.swift; sourceTree = "<group>"; };
+		417D868B266A2E8400DA2444 /* MVHomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVHomeViewModel.swift; sourceTree = "<group>"; };
 		4185322C2665342100DCA2C1 /* MusicVideoPlus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MusicVideoPlus.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		4185322F2665342100DCA2C1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
 		418532382665342200DCA2C1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@@ -52,6 +70,26 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		4112DD812669BF8900A5AFD9 /* Banner */ = {
+			isa = PBXGroup;
+			children = (
+				4112DD882669C0F500A5AFD9 /* images */,
+				4112DD822669BFA600A5AFD9 /* MVBanner.swift */,
+				4112DD852669BFFA00A5AFD9 /* MVBannerFlowLayout.swift */,
+			);
+			path = Banner;
+			sourceTree = "<group>";
+		};
+		4112DD882669C0F500A5AFD9 /* images */ = {
+			isa = PBXGroup;
+			children = (
+				4112DD892669C0F500A5AFD9 /* banner2.jpeg */,
+				4112DD8A2669C0F500A5AFD9 /* banner1.jpeg */,
+				4112DD8B2669C0F500A5AFD9 /* banner0.jpeg */,
+			);
+			path = images;
+			sourceTree = "<group>";
+		};
 		418532232665342100DCA2C1 = {
 			isa = PBXGroup;
 			children = (
@@ -143,6 +181,7 @@
 		41CA6E3F266782C900874B19 /* ViewModels */ = {
 			isa = PBXGroup;
 			children = (
+				417D868B266A2E8400DA2444 /* MVHomeViewModel.swift */,
 			);
 			path = ViewModels;
 			sourceTree = "<group>";
@@ -150,6 +189,7 @@
 		41CA6E40266782C900874B19 /* Models */ = {
 			isa = PBXGroup;
 			children = (
+				4149C8952669FE9D0055CAA2 /* MVTagsModel.swift */,
 			);
 			path = Models;
 			sourceTree = "<group>";
@@ -165,6 +205,9 @@
 		41CA6E42266782C900874B19 /* Views */ = {
 			isa = PBXGroup;
 			children = (
+				4112DD812669BF8900A5AFD9 /* Banner */,
+				4112DD902669C11C00A5AFD9 /* MVBannerCell.swift */,
+				4149C8922669FE6F0055CAA2 /* MVTagsCell.swift */,
 			);
 			path = Views;
 			sourceTree = "<group>";
@@ -455,6 +498,9 @@
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				4112DD8C2669C0F500A5AFD9 /* banner2.jpeg in Resources */,
+				4112DD8D2669C0F500A5AFD9 /* banner1.jpeg in Resources */,
+				4112DD8E2669C0F500A5AFD9 /* banner0.jpeg in Resources */,
 				418532392665342200DCA2C1 /* Assets.xcassets in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -525,13 +571,19 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				4112DD862669BFFA00A5AFD9 /* MVBannerFlowLayout.swift in Sources */,
 				41CA6E702667953700874B19 /* MVSettingController.swift in Sources */,
+				4112DD912669C11C00A5AFD9 /* MVBannerCell.swift in Sources */,
 				41CA6E6C266788F700874B19 /* MVPlayerConntroller.swift in Sources */,
 				41CA6E5E266782EC00874B19 /* MVBaseController.swift in Sources */,
+				4149C8962669FE9D0055CAA2 /* MVTagsModel.swift in Sources */,
 				41CA6E632667853C00874B19 /* MVHomeController.swift in Sources */,
+				4149C8932669FE6F0055CAA2 /* MVTagsCell.swift in Sources */,
+				4112DD832669BFA600A5AFD9 /* MVBanner.swift in Sources */,
 				41CA6E69266788C000874B19 /* MVLoginController.swift in Sources */,
 				41CA6E662667887C00874B19 /* MVMineController.swift in Sources */,
 				41CA6F4B26689F4400874B19 /* PQMineViewModel.swift in Sources */,
+				417D868C266A2E8400DA2444 /* MVHomeViewModel.swift in Sources */,
 				41CA6F782668B80D00874B19 /* PQPhoneLoginController.swift in Sources */,
 				418532302665342100DCA2C1 /* AppDelegate.swift in Sources */,
 			);
@@ -674,7 +726,7 @@
 					"@executable_path/Frameworks",
 				);
 				MARKETING_VERSION = 1.0.0;
-				PRODUCT_BUNDLE_IDENTIFIER = com.piaoquan.pqspeed;
+				PRODUCT_BUNDLE_IDENTIFIER = com.piaoquan.shanyin;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "MusicVideoPlus/MusicVideoPlus-Bridging-Header.h";
 				SWIFT_VERSION = 5.0;
@@ -700,7 +752,7 @@
 					"@executable_path/Frameworks",
 				);
 				MARKETING_VERSION = 1.0.0;
-				PRODUCT_BUNDLE_IDENTIFIER = com.piaoquan.pqspeed;
+				PRODUCT_BUNDLE_IDENTIFIER = com.piaoquan.shanyin;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "MusicVideoPlus/MusicVideoPlus-Bridging-Header.h";
 				SWIFT_VERSION = 5.0;

+ 4 - 3
MusicVideoPlus/MusicVideoPlus/AppDelegate.swift

@@ -26,14 +26,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
         
         let wxappInfo = WXApiInfo.init()
         wxappInfo.state = "com.piaoquan.pqspeed"
-        wxappInfo.appid = "wxfc2fc07ab379e4bf"
-        wxappInfo.secret = "06f696424accb17b7234dce32e4821b4"
-        wxappInfo.universalLink = "https://speed.piaoquantv.com/"
+        wxappInfo.appid = "wx0e8234aac576d1e0"
+        wxappInfo.secret = "a6c35e4e8adf60039f94f4c18e2aabdb"
+        wxappInfo.universalLink = "https://speed.piaoquantv.com"
         wxappInfo.scope = "snsapi_userinfo"
         PQSingletoWXApiUtil.shared.registerApp(appInfo: wxappInfo)
         
         
         return true
+        
  
     }
 

+ 23 - 0
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/home_marks.imageset/Contents.json

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

BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/home_marks.imageset/home_marks.png


BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/home_marks.imageset/home_marks@2x.png


BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/home_marks.imageset/home_marks@3x.png


+ 23 - 0
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/reCreate.imageset/Contents.json

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

BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/reCreate.imageset/reCreate.png


BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/reCreate.imageset/reCreate@2x.png


BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/reCreate.imageset/reCreate@3x.png


BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/set.imageset/set.png


BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/set.imageset/set@2x.png


BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/set.imageset/set@3x.png


+ 22 - 0
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/videomk_music_default.imageset/Contents.json

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

BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/videomk_music_default.imageset/videomk_music_default@2x.png


BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/videomk_music_default.imageset/videomk_music_default@3x.png


BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/wode.imageset/wode.png


BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/wode.imageset/wode@2x.png


BIN
MusicVideoPlus/MusicVideoPlus/Assets.xcassets/Home/wode.imageset/wode@3x.png


+ 153 - 24
MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/MVHomeController.swift

@@ -4,10 +4,19 @@
 //
 //  Created by ak on 2021/6/2.
 //  首界面
- 
+
 import BFFramework
-class MVHomeController: MVBaseController{
-    
+class MVHomeController: MVBaseController {
+    // 当前选择的位置
+    var lastIndexPath: IndexPath = IndexPath(row: 0, section: 0)
+    private var banner: MVBanner = {
+        let banner = MVBanner(frame: .zero, margin: 30, lineSpacing: 12, minScale: MVBanner.Scale(scale: 1))
+        banner.backgroundColor = UIColor.white
+
+        banner.register(classCellType: MVBannerCell.self)
+        return banner
+    }()
+
     // 卡点视频 btn
     lazy var stuckPointBtn: UIButton = {
         let stuckPointBtn = UIButton(type: .custom)
@@ -16,13 +25,12 @@ class MVHomeController: MVBaseController{
         stuckPointBtn.adjustsImageWhenHighlighted = false
         stuckPointBtn.tag = 2000
         stuckPointBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#3DC1C1")
-  
-        stuckPointBtn.addCorner(corner: 30)
 
+        stuckPointBtn.addCorner(corner: 30)
 
         return stuckPointBtn
     }()
-    
+
     // 个人中心btn
     lazy var mineBtn: UIButton = {
         let mineBtn = UIButton(type: .custom)
@@ -32,7 +40,7 @@ class MVHomeController: MVBaseController{
         mineBtn.tag = 1000
         return mineBtn
     }()
-    
+
     // 设置btn
     lazy var settingBtn: UIButton = {
         let settingBtn = UIButton(type: .custom)
@@ -42,21 +50,60 @@ class MVHomeController: MVBaseController{
         settingBtn.tag = 3000
         return settingBtn
     }()
-    
-    
-    
+
+    // 所有分类数据
+    var itemList: [MVTagsModel] = Array<MVTagsModel>.init()
+    // 标签分类
+    lazy var collectionView: UICollectionView = {
+        let flowLayout = UICollectionViewFlowLayout()
+        flowLayout.sectionInset = UIEdgeInsets.zero
+        flowLayout.minimumLineSpacing = 0
+        flowLayout.minimumInteritemSpacing = 10
+        flowLayout.scrollDirection = .horizontal
+        let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 35), collectionViewLayout: flowLayout)
+        collectionView.showsVerticalScrollIndicator = false
+        collectionView.showsHorizontalScrollIndicator = false
+        collectionView.delegate = self
+        collectionView.dataSource = self
+        collectionView.backgroundColor = UIColor.clear
+        collectionView.register(MVTagsCell.self, forCellWithReuseIdentifier: String(describing: MVTagsCell.self))
+        if #available(iOS 11.0, *) {
+            collectionView.contentInsetAdjustmentBehavior = .never
+        } else {
+            automaticallyAdjustsScrollViewInsets = false
+        }
+        // 延迟scrollView上子视图的响应,所以当直接拖动UISlider时,如果此时touch时间在150ms以内,UIScrollView会认为是拖动自己,从而拦截了event,导致UISlider接收不到滑动的event
+        collectionView.delaysContentTouches = false
+        return collectionView
+    }()
+
     override func viewDidLoad() {
         super.viewDidLoad()
         view.addSubview(mineBtn)
         view.addSubview(stuckPointBtn)
         view.addSubview(settingBtn)
-        
+        view.addSubview(banner)
+        view.addSubview(collectionView)
+        banner.dataSource = self
+        banner.delegate = self
+        banner.reloadData()
+        banner.isShowPageControl = false
+
         addLayout()
-  
+
+        for i in 0 ... 10 {
+            var model: MVTagsModel = MVTagsModel()
+            model.tagEmoji = "https://img0.baidu.com/it/u=3433562696,4282002140&fm=26&fmt=auto&gp=0.jpg"
+            model.tagName = "热门"
+            if(i == 5){
+                model.tagName = "我是中华人民有共和国"
+            }
+         
+            itemList.append(model)
+        }
     }
-    
+
     func addLayout() {
-        
         mineBtn.snp.remakeConstraints { make in
             make.width.equalTo(60)
             make.height.equalTo(60)
@@ -69,7 +116,7 @@ class MVHomeController: MVBaseController{
             make.centerX.equalToSuperview()
             make.bottom.equalToSuperview().offset(-50)
         }
-        
+
         settingBtn.snp.remakeConstraints { make in
             make.width.equalTo(60)
             make.height.equalTo(60)
@@ -77,31 +124,113 @@ class MVHomeController: MVBaseController{
             make.bottom.equalToSuperview().offset(-50)
         }
 
+        banner.snp.remakeConstraints { make in
+            make.width.equalTo(cScreenWidth)
+            make.height.equalTo(560)
+            make.left.equalToSuperview().offset(0)
+            make.bottom.equalToSuperview().offset(-136)
+        }
+
+        collectionView.snp.remakeConstraints { make in
+            make.width.equalTo(cScreenWidth)
+            make.height.equalTo(35)
+            make.left.equalToSuperview().offset(0)
+            make.top.equalToSuperview().offset(cDevice_iPhoneStatusBarHei)
+        }
     }
+
     @objc func btnClick(sender: UIButton) {
-        
-        //先判断是否登录
-        if(!BFLoginUserInfo.shared.isLogin() && sender.tag != 3000){
+        // 先判断是否登录
+        if !BFLoginUserInfo.shared.isLogin() && sender.tag != 3000 {
             navigationController?.present(MVLoginController(), animated: true, completion: nil)
             return
         }
-     
-        
+
         switch sender.tag {
-       
         case 1000:
             navigationController?.pushViewController(MVMineController(), animated: true)
-          break
+            break
         case 2000:
             navigationController?.pushViewController(PQStuckPointMaterialController(), animated: true)
             break
-        
+
         case 3000:
             navigationController?.pushViewController(MVSettingController(), animated: true)
             break
-      
+
         default:
             break
         }
     }
 }
+
+// MARK: - MVBannerDataSource
+
+extension MVHomeController: MVBannerDataSource, MVBannerDelegate {
+    func numberOfItems() -> Int {
+        return 3
+    }
+
+    func banner(_ banner: MVBanner, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        let cell: MVBannerCell = banner.dequeueReusableCell(for: indexPath)
+        cell.contentView.layer.masksToBounds = true
+        cell.contentView.layer.cornerRadius = 10
+        cell.contentView.backgroundColor = UIColor.red
+        cell.iconIView.image = UIImage(named: String(format: "banner%d.jpeg", indexPath.row))
+        cell.reCreateBtnClicHandle = { [weak self] _, _ in
+            BFLog(message: "点击了创同款")
+        }
+//        cell.typeLabe.text = String(indexPath.row)
+
+        return cell
+    }
+
+    // MARK: - GXBannerDelegate
+
+    func banner(_: MVBanner, didSelectItemAt indexPath: IndexPath) {
+        NSLog("didSelectItemAt %d", indexPath.row)
+    }
+}
+
+// MARK: - 卡点音乐相关代理
+
+/// 卡点音乐相关代理
+extension MVHomeController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UIScrollViewDelegate {
+    func collectionView(_: UICollectionView, numberOfItemsInSection _: Int) -> Int {
+        return itemList.count
+    }
+
+    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        let itemData: MVTagsModel = itemList[indexPath.item]
+        let cell = MVTagsCell.tagsCell(collectionView: collectionView, indexPath: indexPath)
+        cell.bgmData = itemData
+        return cell
+    }
+
+    func collectionView(_ collectionView: UICollectionView, layout _: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
+        let itemData: MVTagsModel = itemList[indexPath.item]
+        let width:CGFloat = CGFloat(CGFloat((itemData.tagName ?? "" as String).ga_widthForComment(font:UIFont.boldSystemFont(ofSize: 17),height:17.0)) + 36.0 + 20.0)
+ 
+        return CGSize(width: width, height: collectionView.frame.height)
+    }
+  
+
+    func collectionView(_: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        let itemData: MVTagsModel = itemList[lastIndexPath.item]
+        itemData.isSelected = false
+        lastIndexPath = indexPath
+        let itemDataNew: MVTagsModel = itemList[lastIndexPath.item]
+        itemDataNew.isSelected = true
+        collectionView.reloadData()
+    }
+
+    func scrollViewDidScroll(_: UIScrollView) {
+//        if scroDidScroHandle != nil {
+//            scroDidScroHandle!()
+//        }
+    }
+
+    func collectionView(_: UICollectionView, willDisplay _: UICollectionViewCell, forItemAt indexPath: IndexPath) {
+        let itemData: Any = itemList[indexPath.item]
+    }
+}

+ 47 - 0
MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Models/MVTagsModel.swift

@@ -0,0 +1,47 @@
+//
+//  MVTagsModel.swift
+//  MusicVideoPlus
+//
+//  Created by ak on 2021/6/4.
+//
+
+import Foundation
+import BFFramework
+
+class MVTagsModel: NSObject {
+    var parentTagId: Int64? // 父级 ID(如果是第一层,值为 0) ,
+    var rankScore: Int64 = 0 // 排序分数 ,
+    var tagColor: String? // 标签颜色(16进制格式,例如 #FF0000) ,
+    var tagEmoji: String? // 标签emoji表情 ,
+    var tagId: Int64? // 标签ID ,
+    var tagName: String? // 标签名
+    var isSelected: Bool = false // 是否被选中
+    // 标签大小
+    var tagSize: CGSize = CGSize(width: cDefaultMargin * 6, height: cDefaultMargin * 3)
+
+    override init() {
+        super.init()
+    }
+    
+    init(jsonDict: [String: Any]) {
+        super.init()
+        if jsonDict.keys.contains("parentTagId") {
+            parentTagId = Int64("\(jsonDict["parentTagId"] ?? "")") ?? 0
+        }
+        if jsonDict.keys.contains("rankScore") {
+            rankScore = Int64("\(jsonDict["rankScore"] ?? "")") ?? 0
+        }
+        if jsonDict.keys.contains("tagColor"), "\(jsonDict["tagColor"] ?? "")" != "<null>" {
+            tagColor = "\(jsonDict["tagColor"] ?? "")"
+        }
+        if jsonDict.keys.contains("tagEmoji"), "\(jsonDict["tagEmoji"] ?? "")" != "<null>" {
+            tagEmoji = "\(jsonDict["tagEmoji"] ?? "")"
+        }
+        if jsonDict.keys.contains("tagId") {
+            tagId = Int64("\(jsonDict["tagId"] ?? "")") ?? 0
+        }
+        if jsonDict.keys.contains("tagName"), "\(jsonDict["tagName"] ?? "")" != "<null>" {
+            tagName = "\(jsonDict["tagName"] ?? "")"
+        }
+    }
+}

+ 68 - 0
MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/ViewModels/MVHomeViewModel.swift

@@ -0,0 +1,68 @@
+//
+//  MVHomeViewModel.swift
+//  MusicVideoPlus
+//
+//  Created by ak on 2021/6/4.
+//
+
+import Foundation
+import ObjectMapper
+import RealmSwift
+import BFFramework
+
+class PQVideoEditViewModel: NSObject {
+  
+    /// 获取首界面
+    /// - Parameters:
+    ///   - type: 1-最新列表 2-最热列表
+    ///   - targetUid: 目标用户
+    ///   - pageSize: 页面大小
+    ///   - pageNo: 当前页
+    ///   - currentVideoId: 当前视频ID
+    ///   - sortField: 排序方式 1:时间,2:热度
+    ///   - layoutType: 页面排版方式 1:单列,2:双列
+    ///   - lastTimestamp: 最后一条记录的时间戳
+    /// - Returns: <#description#>
+    class func  getHomeHotVideos(type: Int = 1, targetUid: Int, pageSize: Int = 10, pageNo: Int, currentVideoId _: Int = 0, sortField _: Int = 1, layoutType _: Int = 2, lastTimestamp: Int, completeHander: @escaping (_ listData: [PQVideoListModel]?, _ videoList: [[PQVideoListModel]]?, _ msg: String?) -> Void) {
+        var url: String = PQENVUtil.shared.longvideoapi
+        if type == 1 {
+            url = url + latelyByCollectionIdUrl
+        } else {
+            url = url + hotByCollectionIdUrl
+        }
+        var params: [String: Any] = ["targetUid": targetUid, "pageSize": pageSize, "sortField": type]
+        if type == 1 {
+            params["lastTimestamp"] = lastTimestamp
+        } else {
+            params["pageNo"] = pageNo
+        }
+//        SWNetRequest.postRequestData(url: url, parames: params) { response, _, error, _ in
+//
+//            DispatchQueue.global().async {
+//
+//                var listData = Array<PQVideoListModel>.init()
+//                var videoList = Array<[PQVideoListModel]>.init()
+//
+//                if !(response is NSNull), response != nil {
+//                    let tempArr = response as! [[String: Any]]
+//                    for item in tempArr {
+//                        let tempModel = PQVideoListModel(jsonDict: item)
+//                        listData.append(tempModel)
+//                        if tempModel.auditStatus == 5, tempModel.transcodeStatus == 3 {
+//                            videoList.append([tempModel])
+//                        }
+//                    }
+//                    DispatchQueue.main.async {
+//
+//                        completeHander(listData, videoList, nil)
+//                    }
+//                } else {
+//                    DispatchQueue.main.async {
+//
+//                        completeHander(listData, videoList, error?.msg)
+//                    }
+//                }
+//            }
+//        }
+    }
+}

+ 261 - 0
MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/Banner/MVBanner.swift

@@ -0,0 +1,261 @@
+//
+//  MVBanner.swift
+//  MusicVideoPlus
+//
+//  Created by ak on 2021/6/4.
+//
+
+import Foundation
+
+import UIKit
+
+public protocol MVBannerDataSource: NSObjectProtocol {
+    func numberOfItems() -> Int
+    func banner(_ banner: MVBanner, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
+}
+
+@objc public protocol MVBannerDelegate: NSObjectProtocol {
+    @objc optional func banner(_ banner: MVBanner, didSelectItemAt indexPath: IndexPath)
+    @objc optional func pageControl(currentPage page: Int)
+}
+
+private let MVInsetCount: Int = 2
+public class MVBanner: UIView {
+    private var currentIndex: Int = MVInsetCount
+    private var collectionView: UICollectionView!
+    private var flowLayout: MVBannerFlowLayout!
+    public weak var dataSource: MVBannerDataSource?
+    public weak var delegate: MVBannerDelegate?
+    
+    public var isAutoPlay: Bool = true
+    public var autoTimeInterval: TimeInterval = 0
+    public var isShowPageControl: Bool = true {
+        didSet {
+            self.pageControl.isHidden = !self.isShowPageControl
+        }
+    }
+    public override var backgroundColor: UIColor? {
+        didSet {
+            self.collectionView.backgroundColor = self.backgroundColor
+        }
+    }
+ 
+    
+    private(set) lazy var pageControl: UIPageControl = {
+        let pageControl = UIPageControl()
+        pageControl.pageIndicatorTintColor = UIColor.black
+        pageControl.currentPageIndicatorTintColor = UIColor.white
+        pageControl.hidesForSinglePage = true
+        pageControl.addTarget(self, action: #selector(self.pageControlChanged(_:)), for: .valueChanged)
+        return pageControl
+    }()
+    
+    deinit {
+        self.bannerStop()
+    }
+    
+    public required init(frame: CGRect = .zero, margin: CGFloat = 0, lineSpacing: CGFloat = 0, minScale: Scale = Scale()) {
+        super.init(frame: frame)
+        self.flowLayout = MVBannerFlowLayout(margin: margin, lineSpacing: lineSpacing, minScale: minScale)
+        self.setupSubviews()
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    public override func layoutSubviews() {
+        super.layoutSubviews()
+        self.collectionView.frame = self.bounds
+        var size = self.pageControl.size(forNumberOfPages: self.pageControl.numberOfPages)
+        size.width = min(self.flowLayout.itemSize.width, size.width)
+        self.pageControl.frame = CGRect(origin: .zero, size: size)
+        var center = self.center
+        center.y = self.flowLayout.itemSize.height - self.pageControl.frame.height * 0.5
+        self.pageControl.center = center
+    }
+    
+    private func setupSubviews() {
+        self.collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: self.flowLayout)
+        self.collectionView.backgroundColor = .clear
+        self.collectionView.isScrollEnabled = true
+        self.collectionView.isPagingEnabled = false
+        self.collectionView.showsVerticalScrollIndicator = false
+        self.collectionView.showsHorizontalScrollIndicator = false
+        self.collectionView.dataSource = self
+        self.collectionView.delegate = self
+        self.addSubview(self.collectionView)
+
+        self.addSubview(self.pageControl)
+
+    }
+}
+
+fileprivate extension MVBanner {
+    func realNumberOfItems() -> Int {
+        return self.dataSource?.numberOfItems() ?? 0
+    }
+    func numberOfItems() -> Int {
+        let count = self.dataSource?.numberOfItems() ?? 0
+        self.pageControl.numberOfPages = count
+        guard count > 1 else { return count }
+        return count + MVInsetCount * 2
+    }
+    func realIndex(index: Int) -> Int {
+        let count = self.dataSource?.numberOfItems() ?? 0
+        guard count > 1 else { return count }
+        return (index + count - MVInsetCount) % count
+    }
+    func realIndexPath(index: Int) -> IndexPath {
+        return IndexPath(item: self.realIndex(index: index), section: 0)
+    }
+    func index(realIndex: Int) -> Int {
+        let count = self.dataSource?.numberOfItems() ?? 0
+        guard count > 1 else { return 0 }
+        return realIndex + MVInsetCount
+    }
+    func indexPath(realIndex: Int) -> IndexPath {
+        return IndexPath(item: self.index(realIndex: realIndex), section: 0)
+    }
+    func setCurrentPage(_ page: Int) {
+        if (delegate?.responds(to: #selector(delegate?.pageControl(currentPage:))) ?? false) {
+            self.delegate?.pageControl?(currentPage: page)
+        } else {
+            if self.pageControl.currentPage != page {
+                self.pageControl.currentPage = page
+            }
+        }
+    }
+    func checkRealOutOfBounds() {
+        if self.currentIndex <= (MVInsetCount - 1) {
+            self.currentIndex = self.realNumberOfItems() + MVInsetCount - 1
+            self.scrollToItem(at: self.currentIndex, animated: false)
+        }
+        else if self.currentIndex >= (self.realNumberOfItems() + MVInsetCount) {
+            self.currentIndex = MVInsetCount
+            self.scrollToItem(at: self.currentIndex, animated: false)
+        }
+    }
+    func bannerPlay() {
+        self.bannerStop()
+        if(autoTimeInterval > 0){
+            self.perform(#selector(self.bannerScrollNext), with: nil, afterDelay: self.autoTimeInterval)
+        }
+     
+    }
+    func bannerStop() {
+        NSObject.cancelPreviousPerformRequests(withTarget: self)
+    }
+    @objc func pageControlChanged(_ sender: UIPageControl) {
+        self.bannerStop()
+        self.scrollToItem(realAt: sender.currentPage, animated: true)
+    }
+    @objc func bannerScrollNext() {
+        guard self.isAutoPlay && self.realNumberOfItems() > 1 else { return }
+        self.currentIndex += 1
+        self.scrollToItem(at: self.currentIndex, animated: true)
+        self.perform(#selector(self.bannerScrollNext), with: nil, afterDelay: self.autoTimeInterval)
+    }
+}
+
+public extension MVBanner {
+    final func register<T: UICollectionViewCell>(classCellType: T.Type) {
+        let cellID = String(describing: classCellType)
+        self.collectionView.register(classCellType, forCellWithReuseIdentifier: cellID)
+    }
+    final func register<T: UICollectionViewCell>(nibCellType: T.Type) {
+        let cellID = String(describing: nibCellType)
+        let nib = UINib.init(nibName: cellID, bundle: nil)
+        self.collectionView.register(nib, forCellWithReuseIdentifier: cellID)
+    }
+    final func dequeueReusableCell<T: UICollectionViewCell>(for indexPath: IndexPath, cellType: T.Type = T.self) -> T {
+        let cellID = String(describing: cellType)
+        let bareCell = self.collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath)
+        guard let cell = bareCell as? T else {
+            fatalError(
+                "Failed to dequeue a cell with identifier \(cellID) matching type \(cellType.self). "
+                    + "Check that the reuseIdentifier is set properly in your XIB/Storyboard "
+                    + "and that you registered the cell beforehand"
+            )
+        }
+        return cell
+    }
+    final func reloadData() {
+        let count = self.dataSource?.numberOfItems() ?? 0
+        self.collectionView.isUserInteractionEnabled = count > 1
+        self.collectionView.reloadData()
+        self.scrollToItem(realAt: 0, animated: true)
+    }
+    final func scrollToItem(realAt index: Int, animated: Bool) {
+        let indexPath = self.indexPath(realIndex: index)
+        self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: animated)
+        self.setCurrentPage(index)
+    }
+    final func scrollToItem(at index: Int, animated: Bool) {
+        let indexPath = IndexPath(item: index, section: 0)
+        self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: animated)
+        let page = self.realIndex(index: index)
+        self.setCurrentPage(page)
+    }
+}
+
+extension MVBanner: UICollectionViewDataSource, UICollectionViewDelegate {
+    // MARK: - UICollectionViewDataSource
+    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+        return self.numberOfItems()
+    }
+    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+        let realIndexPath = self.realIndexPath(index: indexPath.item)
+        return self.dataSource?.banner(self, cellForItemAt: realIndexPath) ?? UICollectionViewCell()
+    }
+    // MARK: - UICollectionViewDelegate
+    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+        if (delegate?.responds(to: #selector(delegate?.banner(_:didSelectItemAt:))) ?? false) {
+            let realIndexPath = self.realIndexPath(index: indexPath.item)
+            self.delegate?.banner?(self, didSelectItemAt: realIndexPath)
+        }
+    }
+}
+ 
+extension MVBanner: UIScrollViewDelegate {
+    // MARK: - UIScrollViewDelegate
+    public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
+        scrollView.isPagingEnabled = true
+        self.bannerStop()
+    }
+    public func scrollViewDidScroll(_ scrollView: UIScrollView) {
+    }
+    public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
+        if(velocity.x > 0) {
+            self.currentIndex += 1
+        }
+        else if (velocity.x < 0) {
+            self.currentIndex -= 1
+        }
+        else if (velocity.x == 0) {
+            let centerX = scrollView.contentOffset.x + scrollView.frame.size.width * 0.5
+            var minDistance: CGFloat = CGFloat.greatestFiniteMagnitude
+            let indexPaths = self.collectionView.indexPathsForVisibleItems
+            for indexPath in indexPaths {
+                let attributes = self.collectionView.layoutAttributesForItem(at: indexPath)
+                if let attri = attributes {
+                    let distance = abs(attri.center.x - centerX)
+                    if (abs(minDistance) > abs(distance)) {
+                        minDistance = distance
+                        self.currentIndex = attri.indexPath.row
+                    }
+                }
+            }
+        }
+    }
+    public func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
+        scrollView.isPagingEnabled = false
+        self.scrollToItem(at: self.currentIndex, animated: true)
+    }
+    public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
+        scrollView.isPagingEnabled = false
+        self.checkRealOutOfBounds()
+        self.bannerPlay()
+    }
+}
+

+ 108 - 0
MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/Banner/MVBannerFlowLayout.swift

@@ -0,0 +1,108 @@
+//
+//  MVBannerFlowLayout.swift
+//  MusicVideoPlus
+//
+//  Created by ak on 2021/6/4.
+//
+
+import Foundation
+import UIKit
+
+public extension MVBanner {
+    struct Scale {
+        var scaleX: CGFloat!
+        var scaleY: CGFloat!
+        
+        public init(scale: CGFloat) {
+            self.scaleX = scale
+            self.scaleY = scale
+        }
+        public init(sx: CGFloat = 1.0, sy: CGFloat = 1.0) {
+            self.scaleX = sx
+            self.scaleY = sy
+        }
+    }
+}
+public class MVBannerFlowLayout: UICollectionViewFlowLayout {
+    public var margin: CGFloat = 0
+    public var lineSpacing: CGFloat = 0
+    public var minScale: MVBanner.Scale = MVBanner.Scale()
+    
+    public required init(margin: CGFloat = 0, lineSpacing: CGFloat = 0, minScale: MVBanner.Scale) {
+        super.init()
+        self.margin = margin
+        self.lineSpacing = lineSpacing
+        self.minScale = minScale
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+    
+    public override func prepare() {
+        super.prepare()
+        self.scrollDirection = .horizontal
+        self.minimumInteritemSpacing = 0
+        self.minimumLineSpacing = self.lineSpacing
+        self.itemSize = self.itemSize()
+    }
+    
+    public override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
+        guard self.minScale.scaleX < 1 || self.minScale.scaleX != self.minScale.scaleY else {
+            return super.shouldInvalidateLayout(forBoundsChange: newBounds)
+        }
+        return true
+    }
+
+    public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
+        guard self.minScale.scaleX < 1 || self.minScale.scaleX != self.minScale.scaleY else {
+            return super.layoutAttributesForElements(in: rect)
+        }
+        let layoutArray: [UICollectionViewLayoutAttributes] = super.layoutAttributesForElements(in: rect) ?? []
+        var attributesArrayCopy = [UICollectionViewLayoutAttributes]()
+        for attributes in layoutArray {
+            let itemAttributesCopy = attributes.copy() as! UICollectionViewLayoutAttributes
+            attributesArrayCopy.append(itemAttributesCopy)
+        }
+        let centerX = self.collectionView!.contentOffset.x + self.collectionView!.frame.size.width * 0.5
+        let maxDistance = self.itemSize.width + self.minimumLineSpacing
+        for attributes in attributesArrayCopy {
+            let distance = abs(attributes.center.x - centerX)
+            if self.minScale.scaleX == self.minScale.scaleY {
+                let scale = distance/maxDistance * (self.minScale.scaleX - 1) + 1
+                attributes.zIndex = (distance >= maxDistance) ? 1 : 0
+                if attributesArrayCopy.count == 1 {
+                    attributes.center = CGPoint(x: centerX, y: attributes.center.y)
+                }
+                else if scale < 1.0 {
+                    attributes.transform = CGAffineTransform(scaleX: scale, y: scale)
+                }
+            }
+            else {
+                let scaleX = distance/maxDistance * (self.minScale.scaleX - 1) + 1
+                let scaleY = distance/maxDistance * (self.minScale.scaleY - 1) + 1
+                let scale = MVBanner.Scale(sx: scaleX, sy: scaleY)
+                attributes.zIndex = (distance >= maxDistance) ? 1 : 0
+                if attributesArrayCopy.count == 1 {
+                    attributes.center = CGPoint(x: centerX, y: attributes.center.y)
+                }
+                else if scaleX < 1.0 {
+                    let xHeight = self.itemSize.width * (1 - scale.scaleX) * 0.5
+                    let yHeight = self.itemSize.height * (1 - scale.scaleY) * 0.5
+                    let insets = UIEdgeInsets(top: yHeight, left: xHeight, bottom: yHeight, right: xHeight)
+                    attributes.frame = attributes.frame.inset(by: insets)
+                }
+            }
+        }
+        return attributesArrayCopy
+    }
+}
+
+fileprivate extension MVBannerFlowLayout {
+    func itemSize() -> CGSize {
+        let width: CGFloat = self.collectionView!.frame.size.width - self.margin * 2
+        let height: CGFloat = self.collectionView!.frame.size.height
+        return CGSize(width: width, height: height)
+    }
+}
+

BIN
MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/Banner/images/banner0.jpeg


BIN
MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/Banner/images/banner1.jpeg


BIN
MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/Banner/images/banner2.jpeg


+ 142 - 0
MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/MVBannerCell.swift

@@ -0,0 +1,142 @@
+//
+//  GXBannerTestCell.swift
+//  GXBannerSample
+//
+//  Created by Gin on 2020/7/24.
+//  Copyright © 2020 gin. All rights reserved.
+//
+
+import UIKit
+import BFFramework
+
+class MVBannerCell: UICollectionViewCell {
+    
+    lazy var iconIView: UIImageView = {
+        let iv = UIImageView()
+        iv.contentMode = .scaleAspectFill
+        return iv
+    }()
+    
+    lazy var bottmMaskView: UIImageView = {
+        let bottmMaskView = UIImageView.init(image: UIImage.init(named: "home_marks"))
+        
+        return bottmMaskView
+    }()
+    
+    /// 音乐歌曲名称
+    lazy var musicNameLab: LMJHorizontalScrollText = {
+        let name:String = "文件名称"
+        let nameWidth: CGFloat = sizeWithText(text: "\(name)", font: UIFont.systemFont(ofSize: 13), size: CGSize(width: cScreenWidth - ((cDefaultMargin * 6 + 16 * 2) * 2) - (25 + cDefaultMargin * 3), height: cDefaultMargin * 3)).width
+        let musicNameLab = LMJHorizontalScrollText(frame: CGRect(x: 0, y: 0, width: nameWidth < cDefaultMargin * 4 ? cDefaultMargin * 4 : nameWidth, height: cDefaultMargin * 3))
+        musicNameLab.textColor = UIColor.white
+        musicNameLab.textFont = UIFont.systemFont(ofSize: 13)
+        musicNameLab.speed = 0.03
+        musicNameLab.moveDirection = LMJTextScrollMoveLeft
+        musicNameLab.moveMode = LMJTextScrollContinuous
+        if nameWidth < cDefaultMargin * 4 {
+            musicNameLab.text = " \(name) "
+        } else {
+            musicNameLab.text = "\(name)"
+        }
+        return musicNameLab
+    }()
+    
+    /// 音乐标题
+    lazy var musicNameView: UIView = {
+        let musicNameView = UIView()
+        musicNameView.addSubview(musicNameLab)
+        let nameWidth: CGFloat = musicNameLab.frame.width + (25 + cDefaultMargin * 3)
+        musicNameView.frame = CGRect(x: 16, y: 492, width: nameWidth, height: cDefaultMargin * 3)
+//        musicNameView.backgroundColor = UIColor.hexColor(hexadecimal: "#333333")
+        musicNameView.addCorner(corner: musicNameView.frame.height / 2)
+    
+        let musicImageView = UIImageView(image:UIImage.init().BF_Image(named: "stuckPoint_reCreate_music"))
+        musicImageView.frame = CGRect(x: musicNameView.frame.height / 2 - 5, y: (musicNameView.frame.height - 22) / 2, width: 22, height: 22)
+        musicNameView.addSubview(musicImageView)
+        musicNameLab.frame.origin.x = musicImageView.frame.maxX + 5
+        return musicNameView
+    }()
+    
+    //做同款
+    var reCreateBtnClicHandle: ((_ sender: UIButton, _ videoInfo: PQVideoListModel?) -> Void)?
+    lazy var reCreateBtn: UIButton = {
+        let reCreateBtn = UIButton(type: .custom)
+        reCreateBtn.addCorner(corner: 8)
+        reCreateBtn.setImage(UIImage(named: "reCreate"), for: .normal)
+        reCreateBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
+        reCreateBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#3DC1C1")
+        return reCreateBtn
+    }()
+    
+    //视频分类
+    lazy var typeLabe: UILabel = {
+        let typeLabe = UILabel()
+        typeLabe.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.2)
+        typeLabe.alpha = 0.8
+        typeLabe.textColor = .white
+        typeLabe.text = "热门"
+        typeLabe.textAlignment = .center
+        typeLabe.addCorner()
+        typeLabe.font = UIFont.systemFont(ofSize: 13)
+        return typeLabe
+    }()
+    var videoData: PQVideoListModel? {
+        didSet {
+            addData()
+
+        }
+    }
+    
+    override func layoutSubviews() {
+        super.layoutSubviews()
+        self.iconIView.frame = CGRect.init(x: 60, y: 0, width: self.bounds.size.width - 200, height: self.bounds.size.height)
+
+        
+        self.typeLabe.snp.remakeConstraints { make in
+            make.width.equalTo(50)
+            make.height.equalTo(24)
+            make.left.equalToSuperview().offset(17)
+            make.bottom.equalToSuperview().offset(-14)
+        }
+        
+        self.bottmMaskView.snp.remakeConstraints { make in
+            make.width.equalTo(630 / 2)
+            make.height.equalTo(150)
+            make.left.equalToSuperview()
+            make.bottom.equalToSuperview()
+        }
+        
+        self.reCreateBtn.snp.remakeConstraints { make in
+            make.width.equalTo(92)
+            make.height.equalTo(46)
+            make.right.equalToSuperview().offset(-16)
+            make.bottom.equalToSuperview().offset(-20)
+        }
+    }
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        self.contentView.addSubview(self.iconIView)
+        self.contentView.addSubview(self.bottmMaskView)
+        self.contentView.addSubview(self.typeLabe)
+        self.contentView.addSubview(self.musicNameView)
+        self.contentView.addSubview(self.reCreateBtn)
+    
+    }
+    
+    
+
+    func addData() {
+    
+    }
+    
+    @objc func btnClick(sender: UIButton) {
+        if reCreateBtnClicHandle != nil {
+            reCreateBtnClicHandle!(sender, videoData)
+        }
+    }
+    
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+}

+ 96 - 0
MusicVideoPlus/MusicVideoPlus/Classes/Modules/Home/Views/MVTagsCell.swift

@@ -0,0 +1,96 @@
+//
+//  MVTagsCell.swift
+//  MusicVideoPlus
+//
+//  Created by ak on 2021/6/4.
+//
+
+import BFFramework
+import Foundation
+
+class MVTagsCell: UICollectionViewCell {
+    // 按钮点击的回调
+    var btnClickHandle: ((_ sender: UIButton, _ bgmData: Any?) -> Void)?
+
+    lazy var audioImageView: UIImageView = {
+        let audioImageView = UIImageView(image: UIImage(named: "videomk_music_default"))
+        audioImageView.contentMode = .scaleAspectFill
+        return audioImageView
+    }()
+ 
+ 
+    lazy var titleLab: UILabel = {
+        let titleLab = UILabel()
+        titleLab.font = UIFont.boldSystemFont(ofSize: 15)
+        titleLab.textColor = UIColor.white
+        return titleLab
+    }()
+ 
+
+    @objc class func tagsCell(collectionView: UICollectionView, indexPath: IndexPath) -> MVTagsCell {
+        let cell: MVTagsCell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: MVTagsCell.self), for: indexPath) as! MVTagsCell
+        return cell
+    }
+
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        contentView.addSubview(audioImageView)
+
+        contentView.addSubview(titleLab)
+
+
+
+    }
+
+    required init?(coder _: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    var bgmData: MVTagsModel? {
+        didSet {
+            addData()
+            addLayout()
+        }
+    }
+
+    func addData() {
+        if (bgmData)?.tagEmoji != nil {
+            audioImageView.setNetImage(url: "\((bgmData)?.tagEmoji ?? "")", placeholder: UIImage(named: "videomk_music_default")!)
+        } else {
+            audioImageView.image = UIImage(named: "videomk_music_default")
+        }
+        titleLab.text = " \((bgmData)?.tagName ?? "")"
+        if(bgmData?.isSelected ?? false){
+            contentView.backgroundColor = UIColor.hexColor(hexadecimal: "#EEF0F3")
+            titleLab.textColor = UIColor.hexColor(hexadecimal: "#333333")
+            contentView.addCorner()
+            titleLab.font = UIFont.boldSystemFont(ofSize: 15)
+        }else{
+            contentView.backgroundColor = UIColor.clear
+            titleLab.textColor = UIColor.hexColor(hexadecimal: "#9B9B9B")
+            titleLab.font = UIFont.systemFont(ofSize: 15)
+        }
+//        titleLab.frame.size.width = CGFloat((titleLab.text?.count ?? 0) * 17)
+    
+     
+
+    }
+
+    func addLayout() {
+        let margin: CGFloat = 10
+ 
+        audioImageView.snp.remakeConstraints { make in
+            make.left.equalToSuperview().offset(13)
+            make.centerY.equalToSuperview()
+            make.width.height.equalTo(22)
+        }
+     
+        titleLab.snp.remakeConstraints { make in
+            make.left.equalTo(audioImageView.snp_right).offset(7)
+            make.right.equalToSuperview().offset(-margin)
+            make.centerY.equalToSuperview()
+        }
+    }
+
+   
+}