南鑫林 5 rokov pred
rodič
commit
f6e16d944c

+ 37 - 1
RainbowPlanet/RainbowPlanet.xcodeproj/project.pbxproj

@@ -213,6 +213,11 @@
 		A76068E922E4922F008DF18F /* Skittles.json in Resources */ = {isa = PBXBuildFile; fileRef = A76068E822E4922F008DF18F /* Skittles.json */; };
 		A76068EB22E49BC1008DF18F /* collect.json in Resources */ = {isa = PBXBuildFile; fileRef = A76068EA22E49BC0008DF18F /* collect.json */; };
 		A76068ED22E4A2B4008DF18F /* verywell.json in Resources */ = {isa = PBXBuildFile; fileRef = A76068EC22E4A2B4008DF18F /* verywell.json */; };
+		A76068F022E4AE91008DF18F /* loading.gif in Resources */ = {isa = PBXBuildFile; fileRef = A76068EF22E4AE91008DF18F /* loading.gif */; };
+		A76068F322E4B11B008DF18F /* UIImage+Gif.swift in Sources */ = {isa = PBXBuildFile; fileRef = A76068F222E4B11B008DF18F /* UIImage+Gif.swift */; };
+		A76068F522E4BCF4008DF18F /* MJDIYHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A76068F422E4BCF4008DF18F /* MJDIYHeader.swift */; };
+		A76068F722E4C401008DF18F /* MJDIYAutoFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A76068F622E4C401008DF18F /* MJDIYAutoFooter.swift */; };
+		A76068F922E4C566008DF18F /* MJDIYBackFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A76068F822E4C566008DF18F /* MJDIYBackFooter.swift */; };
 		A7636AC52268139C00374F9E /* LocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7636AC42268139C00374F9E /* LocationViewController.swift */; };
 		A7636AC822682BAF00374F9E /* LocationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7636AC722682BAF00374F9E /* LocationView.swift */; };
 		A76390EB2248E27A0067EEE0 /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A76390EA2248E27A0067EEE0 /* UserNotifications.framework */; };
@@ -924,6 +929,11 @@
 		A76068E822E4922F008DF18F /* Skittles.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Skittles.json; sourceTree = "<group>"; };
 		A76068EA22E49BC0008DF18F /* collect.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = collect.json; sourceTree = "<group>"; };
 		A76068EC22E4A2B4008DF18F /* verywell.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = verywell.json; sourceTree = "<group>"; };
+		A76068EF22E4AE91008DF18F /* loading.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = loading.gif; sourceTree = "<group>"; };
+		A76068F222E4B11B008DF18F /* UIImage+Gif.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Gif.swift"; sourceTree = "<group>"; };
+		A76068F422E4BCF4008DF18F /* MJDIYHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MJDIYHeader.swift; sourceTree = "<group>"; };
+		A76068F622E4C401008DF18F /* MJDIYAutoFooter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MJDIYAutoFooter.swift; sourceTree = "<group>"; };
+		A76068F822E4C566008DF18F /* MJDIYBackFooter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MJDIYBackFooter.swift; sourceTree = "<group>"; };
 		A7636AC42268139C00374F9E /* LocationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationViewController.swift; sourceTree = "<group>"; };
 		A7636AC722682BAF00374F9E /* LocationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationView.swift; sourceTree = "<group>"; };
 		A76390EA2248E27A0067EEE0 /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; };
@@ -2518,6 +2528,7 @@
 		A72C011E227539800065E0C3 /* Src */ = {
 			isa = PBXGroup;
 			children = (
+				A76068EE22E4AE65008DF18F /* gif */,
 				A75B787522E079BC007B986A /* AnimationJSON */,
 				A75B783422DFFDFE007B986A /* json */,
 			);
@@ -2707,6 +2718,9 @@
 			children = (
 				A757C9322274882E00226355 /* UIScrollView+MJRefreshEX.m */,
 				A757C9332274882E00226355 /* UIScrollView+MJRefreshEX.h */,
+				A76068F422E4BCF4008DF18F /* MJDIYHeader.swift */,
+				A76068F822E4C566008DF18F /* MJDIYBackFooter.swift */,
+				A76068F622E4C401008DF18F /* MJDIYAutoFooter.swift */,
 			);
 			path = MJRefreshEX;
 			sourceTree = "<group>";
@@ -2749,6 +2763,22 @@
 			path = AnimationJSON;
 			sourceTree = "<group>";
 		};
+		A76068EE22E4AE65008DF18F /* gif */ = {
+			isa = PBXGroup;
+			children = (
+				A76068EF22E4AE91008DF18F /* loading.gif */,
+			);
+			path = gif;
+			sourceTree = "<group>";
+		};
+		A76068F122E4B0ED008DF18F /* UImage+Gif */ = {
+			isa = PBXGroup;
+			children = (
+				A76068F222E4B11B008DF18F /* UIImage+Gif.swift */,
+			);
+			path = "UImage+Gif";
+			sourceTree = "<group>";
+		};
 		A7636ABD2268123B00374F9E /* LocationModule */ = {
 			isa = PBXGroup;
 			children = (
@@ -3178,9 +3208,9 @@
 		A77F2CA22232010F001BD3F6 /* Modules */ = {
 			isa = PBXGroup;
 			children = (
-				A714348522DD9CD000132DA9 /* RedemptionAreaModule */,
 				A77F2CAE2232010F001BD3F6 /* RegisterLoginModule */,
 				A719EE6622AF4374001AAC98 /* CommunityModule */,
+				A714348522DD9CD000132DA9 /* RedemptionAreaModule */,
 				A77F2CA32232010F001BD3F6 /* ShoppingMallModule */,
 				BD12B67122B4E96100AEB10B /* PublishModule */,
 				BD3AA45422AE635700EF4F20 /* MessageModule */,
@@ -3297,6 +3327,7 @@
 		A77F2CBC2232022A001BD3F6 /* Tools */ = {
 			isa = PBXGroup;
 			children = (
+				A76068F122E4B0ED008DF18F /* UImage+Gif */,
 				BD5CA89322DDA27000364A67 /* CustomSlider */,
 				A7297C6422D72F7F001A7AE6 /* KeyBoardCommentView */,
 				A770E5E522D3421700CBD0A4 /* CommentInputView */,
@@ -5876,6 +5907,7 @@
 				BD108C9A22A60C3300837DAB /* HGImage.xcassets in Resources */,
 				A7F3069922E1C72D00DC7917 /* json_Image_1.png in Resources */,
 				A76068ED22E4A2B4008DF18F /* verywell.json in Resources */,
+				A76068F022E4AE91008DF18F /* loading.gif in Resources */,
 				A729B5AA2266F6FD004AE098 /* Launch Screen.storyboard in Resources */,
 				BD24FABB22B509CF00C7AA3B /* PublishModule.xcassets in Resources */,
 			);
@@ -6095,6 +6127,7 @@
 				BD01B20122BC677900CE9F36 /* PublishFilterView.swift in Sources */,
 				BD5CA89522DDA2A100364A67 /* CustomSlider.swift in Sources */,
 				A75B782522DEC592007B986A /* SpecialOneTypeCollectionViewCell.swift in Sources */,
+				A76068F522E4BCF4008DF18F /* MJDIYHeader.swift in Sources */,
 				A77F2CCA223209F2001BD3F6 /* BaseTabbarViewController.swift in Sources */,
 				BD61229A22C3605C00D3F513 /* AliyunEffectFilterCell.m in Sources */,
 				A7BF202B22B396F300396DB3 /* CardContentTitleTableViewCell.swift in Sources */,
@@ -6387,6 +6420,7 @@
 				BD13B6C222BA034D008BB323 /* PublishEditAddImgCollectionCell.swift in Sources */,
 				A7778CAB2244B12500C7C47A /* CountDownManager.swift in Sources */,
 				BD50F47222E158FB0077D4BF /* PublishAgreementController.swift in Sources */,
+				A76068F322E4B11B008DF18F /* UIImage+Gif.swift in Sources */,
 				A775CBFE2237493600EBDCF8 /* ShoppingMallNavigationBarView.swift in Sources */,
 				A71AA5212272E527008FF1A5 /* Extension+UINavigationController.swift in Sources */,
 				BD981A8F22C9FEEF0043D951 /* CommunityPublishModel.swift in Sources */,
@@ -6480,6 +6514,7 @@
 				A7274C5A228EE636000E3A07 /* LBXScanView.swift in Sources */,
 				A7FF1560228C693D00A85748 /* OrderViewController.swift in Sources */,
 				A729B5B42267254B004AE098 /* PasswordLoginViewController.swift in Sources */,
+				A76068F722E4C401008DF18F /* MJDIYAutoFooter.swift in Sources */,
 				A7B4E7582282897B0012914A /* ProductFloorLeftHeaderCollectionReusableView.swift in Sources */,
 				A7D4608E227616F800A5A54E /* SQLiteManager.swift in Sources */,
 				A70B2C6B2288815300B2449F /* PickHeaderView.swift in Sources */,
@@ -6554,6 +6589,7 @@
 				BDE376E922C22D4E0055E2EA /* AlivcUIConfig.m in Sources */,
 				A7C2567C22CD8EEE00420828 /* CommunityPostCommentsModel.swift in Sources */,
 				A7541502224C5ECB002480B5 /* BaiduMapManager.swift in Sources */,
+				A76068F922E4C566008DF18F /* MJDIYBackFooter.swift in Sources */,
 				A773D02F229FDC3B007A5751 /* DIYEmptyView.swift in Sources */,
 				BD6122B022C3638300D3F513 /* AliyunEffectInfo.m in Sources */,
 				A757C9342274882E00226355 /* UIScrollView+MJRefreshEX.m in Sources */,

+ 0 - 1
RainbowPlanet/RainbowPlanet/Modules/PublishModule/PublishViewController.swift

@@ -50,7 +50,6 @@ class PublishViewController: BaseViewController {
         setupViews()
         setupLayouts()
         setupData()
-                
         observe = NotificationCenter.default.addObserver(forName: NSNotification.Name("DismissFromPublishEditVc"), object: nil, queue: OperationQueue.main) {[weak self] (notification) in
             self?.dismiss(animated: true, completion: nil)
         }

+ 22 - 0
RainbowPlanet/RainbowPlanet/Modules/SearchModule/SearchContentList/View/SearchContentListCollectionCell.swift

@@ -8,6 +8,7 @@
 
 import UIKit
 import RxSwift
+import Lottie
 
 class SearchContentListCollectionCell: UICollectionViewCell {
     
@@ -61,6 +62,8 @@ class SearchContentListCollectionCell: UICollectionViewCell {
         addSubview(nameButton)
         addSubview(likeBtn)
         contentImageView.addSubview(pauseImageView)
+        likeBtn.imageView?.addSubview(praiseAnimationView)
+
     }
     
     private func setupLayouts() {
@@ -88,6 +91,9 @@ class SearchContentListCollectionCell: UICollectionViewCell {
             make.height.equalTo(18)
         }
         likeBtn.layoutButton(edgeInsetsStyle: ButtonEdgeInsetsStyle.left, imageTitleSpace: 5)
+        praiseAnimationView.snp.makeConstraints { (make) in
+            make.edges.equalToSuperview()
+        }
         pauseImageView.snp_makeConstraints { (make) in
             make.center.equalToSuperview()
         }
@@ -151,11 +157,27 @@ class SearchContentListCollectionCell: UICollectionViewCell {
         likeBtn.setImage(kImage(name: "btn_praise_pre_36px"), for: UIControl.State.selected)
         likeBtn.titleLabel?.font = kRegularFont12
         likeBtn.rx.tap.subscribe(onNext: { [weak self] (data) in
+            if self?.communityPostDataModel?.isLike == 0 {
+                self?.praiseAnimationView.isHidden = false
+                self?.praiseAnimationView.play(completion: { (_) in
+                    self?.praiseAnimationView.isHidden = true
+                })
+            }
             VirusViewModel.shared.likeVirueRecordAddApi(communityPostDataModel: (self?.communityPostDataModel!)!, cell: self!)
         }).disposed(by: disposeBag)
         return likeBtn
     }()
     
+    private lazy var praiseAnimationView: AnimationView = {
+        let praiseAnimationView = AnimationView()
+        let animation = Animation.named("verywell")
+        praiseAnimationView.animation = animation
+        praiseAnimationView.contentMode = .scaleAspectFit
+        praiseAnimationView.loopMode = .playOnce
+        praiseAnimationView.isHidden = true
+        return praiseAnimationView
+    }()
+    
     private lazy var pauseImageView: UIImageView = {
         let pauseImageView = UIImageView.init(image: kImage(name: "btn_pause"))
         pauseImageView.isUserInteractionEnabled = true

BIN
RainbowPlanet/RainbowPlanet/Src/gif/loading.gif


+ 82 - 0
RainbowPlanet/RainbowPlanet/Tools/MJRefreshEX/MJDIYAutoFooter.swift

@@ -0,0 +1,82 @@
+//
+//  MJDIYAutoFooter.swift
+//  RainbowPlanet
+//
+//  Created by 南鑫林 on 2019/7/22.
+//  Copyright © 2019 RainbowPlanet. All rights reserved.
+//
+
+import Foundation
+import MJRefresh
+
+class MJDIYAutoFooter: MJRefreshAutoFooter
+{
+    var label:UILabel!
+    var loading:UIActivityIndicatorView!
+    
+    //在这里做一些初始化配置(比如添加子控件)
+    override func prepare()
+    {
+        super.prepare()
+        
+        // 设置控件的高度
+        self.mj_h = 50
+        
+        // 添加label
+        self.label =  UILabel()
+        self.label.textColor = UIColor(red:1.0, green:0.5, blue:0.0, alpha:1.0)
+        self.label.font = UIFont.boldSystemFont(ofSize: 16)
+        self.label.textAlignment = .center
+        self.addSubview(self.label)
+        
+        // loading
+        self.loading =  UIActivityIndicatorView(style: .gray)
+        self.addSubview(self.loading)
+    }
+    
+    //在这里设置子控件的位置和尺寸
+    override func placeSubviews()
+    {
+        super.placeSubviews()
+        self.label.frame = self.bounds
+        self.loading.center = CGPoint(x:30, y:self.mj_h * 0.5)
+    }
+    
+    //监听控件的刷新状态
+    override var state: MJRefreshState{
+        didSet
+        {
+            switch (state) {
+            case .idle:
+                self.label.text = ""
+                self.loading.stopAnimating()
+                break
+            case .refreshing:
+                self.label.text = "加载中..."
+                self.loading.startAnimating()
+                break
+            case .noMoreData:
+                self.label.text = "这是我的底线啦~"
+                self.loading.stopAnimating()
+                break
+            default:
+                break
+            }
+        }
+    }
+    
+    //监听scrollView的contentOffset改变
+    override func scrollViewContentOffsetDidChange(_ change: [AnyHashable : Any]!) {
+        super.scrollViewContentOffsetDidChange(change)
+    }
+    
+    //监听scrollView的contentSize改变
+    override func scrollViewContentSizeDidChange(_ change: [AnyHashable : Any]!) {
+        super.scrollViewContentSizeDidChange(change)
+    }
+    
+    //监听scrollView的拖拽状态改变
+    override func scrollViewPanStateDidChange(_ change: [AnyHashable : Any]!) {
+        super.scrollViewPanStateDidChange(change)
+    }
+}

+ 97 - 0
RainbowPlanet/RainbowPlanet/Tools/MJRefreshEX/MJDIYBackFooter.swift

@@ -0,0 +1,97 @@
+//
+//  MJDIYFooter.swift
+//  RainbowPlanet
+//
+//  Created by 南鑫林 on 2019/7/22.
+//  Copyright © 2019 RainbowPlanet. All rights reserved.
+//
+
+import Foundation
+import MJRefresh
+
+class MJDIYBackFooter: MJRefreshBackFooter {
+    var label:UILabel!
+    var loading:UIActivityIndicatorView!
+    
+    //在这里做一些初始化配置(比如添加子控件)
+    override func prepare()
+    {
+        super.prepare()
+        
+        // 设置控件的高度
+        self.mj_h = 50
+        
+        // 添加label
+        self.label =  UILabel()
+        self.label.textColor = UIColor(red:1.0, green:0.5, blue:0.0, alpha:1.0)
+        self.label.font = UIFont.boldSystemFont(ofSize: 16)
+        self.label.textAlignment = .center
+        self.addSubview(self.label)
+        // loading
+        self.loading =  UIActivityIndicatorView(style: .gray)
+        self.addSubview(self.loading)
+    }
+    
+    //在这里设置子控件的位置和尺寸
+    override func placeSubviews()
+    {
+        super.placeSubviews()
+        
+        self.label.frame = self.bounds
+        self.loading.center = CGPoint(x:self.mj_w - 30, y:self.mj_h * 0.5)
+    }
+    
+    //监听控件的刷新状态
+    override var state: MJRefreshState{
+        didSet
+        {
+            switch (state) {
+            case .idle:
+                self.loading.stopAnimating()
+                self.label.text = ""
+                break
+            case .pulling:
+                self.loading.stopAnimating()
+                self.label.text = "加载中..."
+                break
+            case .refreshing:
+                self.loading.startAnimating()
+                self.label.text = "加载中..."
+                break
+            case .noMoreData:
+                self.loading.stopAnimating()
+                self.label.text = "这是我的底线啦~"
+            default:
+                break
+            }
+        }
+    }
+    
+    //监听拖拽比例(控件被拖出来的比例)
+    override var pullingPercent: CGFloat {
+        didSet
+        {
+            // 1.0 0.5 0.0
+            // 0.5 0.0 0.5
+            let  red =  1.0 - pullingPercent * 0.5
+            let green =  0.5 - 0.5 * pullingPercent
+            let blue =  0.5 * pullingPercent
+            self.label.textColor = UIColor(red:red, green:green, blue:blue, alpha:1.0)
+        }
+    }
+    
+    //监听scrollView的contentOffset改变
+    override func scrollViewContentOffsetDidChange(_ change: [AnyHashable : Any]!) {
+        super.scrollViewContentOffsetDidChange(change)
+    }
+    
+    //监听scrollView的contentSize改变
+    override func scrollViewContentSizeDidChange(_ change: [AnyHashable : Any]!) {
+        super.scrollViewContentSizeDidChange(change)
+    }
+    
+    //监听scrollView的拖拽状态改变
+    override func scrollViewPanStateDidChange(_ change: [AnyHashable : Any]!) {
+        super.scrollViewPanStateDidChange(change)
+    }
+}

+ 81 - 0
RainbowPlanet/RainbowPlanet/Tools/MJRefreshEX/MJDIYHeader.swift

@@ -0,0 +1,81 @@
+//
+//  MJDIYHeader.swift
+//  RainbowPlanet
+//
+//  Created by 南鑫林 on 2019/7/21.
+//  Copyright © 2019 RainbowPlanet. All rights reserved.
+//
+
+import Foundation
+import MJRefresh
+
+class MJDIYHeader: MJRefreshHeader {
+    
+    var imageView : UIImageView!
+    
+    //在这里做一些初始化配置(比如添加子控件)
+    override func prepare()
+    {
+        super.prepare()
+        
+        // 设置控件的高度
+        self.mj_h = 50
+
+        self.imageView = UIImageView(image: UIImage.gif(name: "loading"))
+        imageView.stopAnimating()
+        imageView.contentMode = .scaleAspectFill        
+        
+        self.addSubview(self.imageView)
+    }
+    
+    //在这里设置子控件的位置和尺寸
+    override func placeSubviews()
+    {
+        super.placeSubviews()
+        self.imageView.snp.makeConstraints { (make) in
+            make.center.equalToSuperview()
+            make.size.equalTo(37)
+        }
+    }
+    
+    //监听控件的刷新状态
+    override var state: MJRefreshState{
+        didSet
+        {
+            switch (state) {
+            case .idle:
+                self.imageView.stopAnimating()
+                break
+            case .pulling:
+                self.imageView.stopAnimating()
+                break
+            case .refreshing:
+                self.imageView.startAnimating()
+                break
+            default:
+                break
+            }
+        }
+    }
+    
+    //监听拖拽比例(控件被拖出来的比例)
+    override var pullingPercent: CGFloat {
+        didSet {
+        }
+    }
+    
+    //监听scrollView的contentOffset改变
+    override func scrollViewContentOffsetDidChange(_ change: [AnyHashable : Any]!) {
+        super.scrollViewContentOffsetDidChange(change)
+    }
+    
+    //监听scrollView的contentSize改变
+    override func scrollViewContentSizeDidChange(_ change: [AnyHashable : Any]!) {
+        super.scrollViewContentSizeDidChange(change)
+    }
+    
+    //监听scrollView的拖拽状态改变
+    override func scrollViewPanStateDidChange(_ change: [AnyHashable : Any]!) {
+        super.scrollViewPanStateDidChange(change)
+    }
+}

+ 72 - 22
RainbowPlanet/RainbowPlanet/Tools/MJRefreshEX/UIScrollView+MJRefreshEX.m

@@ -9,6 +9,7 @@
 #import "UIScrollView+MJRefreshEX.h"
 #import "MJRefresh.h"
 #import <objc/runtime.h>
+#import "RainbowPlanet-Swift.h"
 
 typedef void(^RefreshBlock)(NSInteger pageIndex);
 typedef void(^LoadMoreBlock)(NSInteger pageIndex);
@@ -31,26 +32,49 @@ typedef void(^LoadMoreBlock)(NSInteger pageIndex);
     __weak typeof(self) weakSelf = self;
     self.refreshBlock = refreshBlock;
     
-    MJRefreshNormalHeader * header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
-        [weakSelf resetPageNum];
-        
-        if (weakSelf.refreshBlock) {
-            weakSelf.refreshBlock(weakSelf.pageIndex);
+//    MJRefreshNormalHeader * header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
+//        [weakSelf resetPageNum];
+//
+//        if (weakSelf.refreshBlock) {
+//            weakSelf.refreshBlock(weakSelf.pageIndex);
+//        }
+//        [weakSelf endHeaderRefresh];
+//    }];
+//
+//    if (beginRefresh && animation) {
+//        //有动画的刷新
+//        [self resetPageNum];
+//        [header beginRefreshing];
+//    }else if (beginRefresh && !animation){
+//        //刷新,但是没有动画
+//        [header executeRefreshingCallback];
+//    }
+//
+//    header.mj_h = 70.0;
+//    self.mj_header = header;
+    
+        MJDIYHeader * header = [MJDIYHeader headerWithRefreshingBlock:^{
+            [weakSelf resetPageNum];
+
+            if (weakSelf.refreshBlock) {
+                weakSelf.refreshBlock(weakSelf.pageIndex);
+            }
+            [weakSelf endHeaderRefresh];
+        }];
+
+        if (beginRefresh && animation) {
+            //有动画的刷新
+            [self resetPageNum];
+            [header beginRefreshing];
+        }else if (beginRefresh && !animation){
+            //刷新,但是没有动画
+            [header executeRefreshingCallback];
         }
-        [weakSelf endHeaderRefresh];
-    }];    
+
+        header.mj_h = 50.0;
+        self.mj_header = header;
     
-    if (beginRefresh && animation) {
-        //有动画的刷新
-        [self resetPageNum];
-        [header beginRefreshing];
-    }else if (beginRefresh && !animation){
-        //刷新,但是没有动画
-        [header executeRefreshingCallback];
-    }
     
-    header.mj_h = 70.0;
-    self.mj_header = header;
 }
 
 - (void)addFooterWithWithHeaderWithAutomaticallyRefresh:(BOOL)automaticallyRefresh loadMoreBlock:(void(^)(NSInteger pageIndex))loadMoreBlock{
@@ -65,16 +89,16 @@ typedef void(^LoadMoreBlock)(NSInteger pageIndex);
             }
             [self endFooterRefresh];
         }];
-        
+
         footer.automaticallyRefresh = automaticallyRefresh;
         footer.triggerAutomaticallyRefreshPercent = 1;
         footer.onlyRefreshPerDrag = YES;
-        
+
         footer.stateLabel.font = [UIFont systemFontOfSize:13.0];
         footer.stateLabel.textColor = [UIColor colorWithWhite:0.400 alpha:1.000];
         [footer setTitle:@"加载中…" forState:MJRefreshStateRefreshing];
         [footer setTitle:@"这是我的底线啦~" forState:MJRefreshStateNoMoreData];
-        
+
         self.mj_footer = footer;
     }
     else{
@@ -85,15 +109,41 @@ typedef void(^LoadMoreBlock)(NSInteger pageIndex);
             }
             [self endFooterRefresh];
         }];
-        
+
         footer.stateLabel.font = [UIFont systemFontOfSize:13.0];
         footer.stateLabel.textColor = [UIColor colorWithWhite:0.400 alpha:1.000];
         [footer setTitle:@"加载中…" forState:MJRefreshStateRefreshing];
         [footer setTitle:@"这是我的底线啦~" forState:MJRefreshStateNoMoreData];
-        
+
+        footer.mj_h = 50.0;
         self.mj_footer = footer;
     }
     
+//        if (automaticallyRefresh) {
+//            MJDIYAutoFooter * footer = [MJDIYAutoFooter footerWithRefreshingBlock:^{
+//                self.pageIndex += 1;
+//                if (self.loadMoreBlock) {
+//                    self.loadMoreBlock(self.pageIndex);
+//                }
+//                [self endFooterRefresh];
+//            }];
+//
+//            footer.automaticallyRefresh = automaticallyRefresh;
+//            footer.triggerAutomaticallyRefreshPercent = 1;
+//            footer.onlyRefreshPerDrag = YES;
+//            self.mj_footer = footer;
+//        }
+//        else{
+//            MJDIYBackFooter * footer = [MJDIYBackFooter footerWithRefreshingBlock:^{
+//                self.pageIndex += 1;
+//                if (self.loadMoreBlock) {
+//                    self.loadMoreBlock(self.pageIndex);
+//                }
+//                [self endFooterRefresh];
+//            }];
+//            self.mj_footer = footer;
+//        }
+    
 }
 
 -(void)beginHeaderRefresh {

+ 1 - 1
RainbowPlanet/RainbowPlanet/Tools/SwiftProgressHUD/SwiftProgressHUD.swift

@@ -159,7 +159,7 @@ class SwiftProgressHUD: NSObject {
 
     /// 隐藏
     func hide(){
-        hud.hide(animated: true)
+        hud.hide(animated: true, afterDelay: TimeInterval(afterDelay))
     }
 
 }

+ 226 - 0
RainbowPlanet/RainbowPlanet/Tools/UImage+Gif/UIImage+Gif.swift

@@ -0,0 +1,226 @@
+//
+//  UIImage+Gif.swift
+//  RainbowPlanet
+//
+//  Created by 南鑫林 on 2019/7/21.
+//  Copyright © 2019 RainbowPlanet. All rights reserved.
+//
+
+import Foundation
+import ImageIO
+
+extension UIImageView {
+    
+    public func loadGif(name: String) {
+        DispatchQueue.global().async {
+            let image = UIImage.gif(name: name)
+            DispatchQueue.main.async {
+                self.image = image
+            }
+        }
+    }
+    
+    @available(iOS 9.0, *)
+    public func loadGif(asset: String) {
+        DispatchQueue.global().async {
+            let image = UIImage.gif(asset: asset)
+            DispatchQueue.main.async {
+                self.image = image
+            }
+        }
+    }
+    
+}
+
+extension UIImage {
+    
+    public class func gif(data: Data) -> UIImage? {
+        // Create source from data
+        guard let source = CGImageSourceCreateWithData(data as CFData, nil) else {
+            print("SwiftGif: Source for the image does not exist")
+            return nil
+        }
+        
+        return UIImage.animatedImageWithSource(source)
+    }
+    
+    public class func gif(url: String) -> UIImage? {
+        // Validate URL
+        guard let bundleURL = URL(string: url) else {
+            print("SwiftGif: This image named \"\(url)\" does not exist")
+            return nil
+        }
+        
+        // Validate data
+        guard let imageData = try? Data(contentsOf: bundleURL) else {
+            print("SwiftGif: Cannot turn image named \"\(url)\" into NSData")
+            return nil
+        }
+        
+        return gif(data: imageData)
+    }
+    
+    public class func gif(name: String) -> UIImage? {
+        // Check for existance of gif
+        guard let bundleURL = Bundle.main
+            .url(forResource: name, withExtension: "gif") else {
+                print("SwiftGif: This image named \"\(name)\" does not exist")
+                return nil
+        }
+        
+        // Validate data
+        guard let imageData = try? Data(contentsOf: bundleURL) else {
+            print("SwiftGif: Cannot turn image named \"\(name)\" into NSData")
+            return nil
+        }
+        
+        return gif(data: imageData)
+    }
+    
+    @available(iOS 9.0, *)
+    public class func gif(asset: String) -> UIImage? {
+        // Create source from assets catalog
+        guard let dataAsset = NSDataAsset(name: asset) else {
+            print("SwiftGif: Cannot turn image named \"\(asset)\" into NSDataAsset")
+            return nil
+        }
+        
+        return gif(data: dataAsset.data)
+    }
+    
+    internal class func delayForImageAtIndex(_ index: Int, source: CGImageSource!) -> Double {
+        var delay = 0.1
+        
+        // Get dictionaries
+        let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)
+        let gifPropertiesPointer = UnsafeMutablePointer<UnsafeRawPointer?>.allocate(capacity: 0)
+        defer {
+            gifPropertiesPointer.deallocate()
+        }
+        let unsafePointer = Unmanaged.passUnretained(kCGImagePropertyGIFDictionary).toOpaque()
+        if CFDictionaryGetValueIfPresent(cfProperties, unsafePointer, gifPropertiesPointer) == false {
+            return delay
+        }
+        
+        let gifProperties: CFDictionary = unsafeBitCast(gifPropertiesPointer.pointee, to: CFDictionary.self)
+        
+        // Get delay time
+        var delayObject: AnyObject = unsafeBitCast(
+            CFDictionaryGetValue(gifProperties,
+                                 Unmanaged.passUnretained(kCGImagePropertyGIFUnclampedDelayTime).toOpaque()),
+            to: AnyObject.self)
+        if delayObject.doubleValue == 0 {
+            delayObject = unsafeBitCast(CFDictionaryGetValue(gifProperties,
+                                                             Unmanaged.passUnretained(kCGImagePropertyGIFDelayTime).toOpaque()), to: AnyObject.self)
+        }
+        
+        if let delayObject = delayObject as? Double, delayObject > 0 {
+            delay = delayObject
+        } else {
+            delay = 0.1 // Make sure they're not too fast
+        }
+        
+        return delay
+    }
+    
+    internal class func gcdForPair(_ lhs: Int?, _ rhs: Int?) -> Int {
+        var lhs = lhs
+        var rhs = rhs
+        // Check if one of them is nil
+        if rhs == nil || lhs == nil {
+            if rhs != nil {
+                return rhs!
+            } else if lhs != nil {
+                return lhs!
+            } else {
+                return 0
+            }
+        }
+        
+        // Swap for modulo
+        if lhs! < rhs! {
+            let ctp = lhs
+            lhs = rhs
+            rhs = ctp
+        }
+        
+        // Get greatest common divisor
+        var rest: Int
+        while true {
+            rest = lhs! % rhs!
+            
+            if rest == 0 {
+                return rhs! // Found it
+            } else {
+                lhs = rhs
+                rhs = rest
+            }
+        }
+    }
+    
+    internal class func gcdForArray(_ array: [Int]) -> Int {
+        if array.isEmpty {
+            return 1
+        }
+        
+        var gcd = array[0]
+        
+        for val in array {
+            gcd = UIImage.gcdForPair(val, gcd)
+        }
+        
+        return gcd
+    }
+    
+    internal class func animatedImageWithSource(_ source: CGImageSource) -> UIImage? {
+        let count = CGImageSourceGetCount(source)
+        var images = [CGImage]()
+        var delays = [Int]()
+        
+        // Fill arrays
+        for index in 0..<count {
+            // Add image
+            if let image = CGImageSourceCreateImageAtIndex(source, index, nil) {
+                images.append(image)
+            }
+            
+            // At it's delay in cs
+            let delaySeconds = UIImage.delayForImageAtIndex(Int(index),
+                                                            source: source)
+            delays.append(Int(delaySeconds * 1000.0)) // Seconds to ms
+        }
+        
+        // Calculate full duration
+        let duration: Int = {
+            var sum = 0
+            
+            for val: Int in delays {
+                sum += val
+            }
+            
+            return sum
+        }()
+        
+        // Get frames
+        let gcd = gcdForArray(delays)
+        var frames = [UIImage]()
+        
+        var frame: UIImage
+        var frameCount: Int
+        for index in 0..<count {
+            frame = UIImage(cgImage: images[Int(index)])
+            frameCount = Int(delays[Int(index)] / gcd)
+            
+            for _ in 0..<frameCount {
+                frames.append(frame)
+            }
+        }
+        
+        // Heyhey
+        let animation = UIImage.animatedImage(with: frames,
+                                              duration: Double(duration) / 1000.0)
+        
+        return animation
+    }
+    
+}