浏览代码

做了一些修改

100Years 4 天之前
父节点
当前提交
020766c171

+ 2 - 1
TSSmalCoacopods/Classes/Ex/UILabel+Ex.swift

@@ -161,7 +161,8 @@ public extension UILabel {
         
         // 移除旧的渐变层(如果存在)
         removeExistingGradientLayer()
-
+        self.alpha = 1
+        self.isHidden = false
         // 创建渐变图层
         let gradientLayer = CAGradientLayer()
         gradientLayer.name = "GradientTextLayer"

+ 82 - 0
TSSmalCoacopods/Classes/Ex/UIView+Animation.swift

@@ -0,0 +1,82 @@
+//
+//  UIView+Animation.swift
+//  KittensTravelNotes
+//
+//  Created by 100Years on 2025/7/7.
+//
+import UIKit
+public extension UIView {
+    private struct AssociatedKeys {
+        static var timerKey = "UIView.timerKey"
+        static var imagesKey = "UIView.imagesKey"
+        static var currentIndexKey = "UIView.currentIndexKey"
+    }
+    
+    private var transitionTimer: Timer? {
+        get {
+            return objc_getAssociatedObject(self, &AssociatedKeys.timerKey) as? Timer
+        }
+        set {
+            objc_setAssociatedObject(self, &AssociatedKeys.timerKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+    }
+    
+    private var transitionImages: [Any]? {
+        get {
+            return objc_getAssociatedObject(self, &AssociatedKeys.imagesKey) as? [UIImage]
+        }
+        set {
+            objc_setAssociatedObject(self, &AssociatedKeys.imagesKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+    }
+    
+    private var currentImageIndex: Int {
+        get {
+            return objc_getAssociatedObject(self, &AssociatedKeys.currentIndexKey) as? Int ?? 0
+        }
+        set {
+            objc_setAssociatedObject(self, &AssociatedKeys.currentIndexKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+    }
+    
+    /// 开始图片循环切换动画
+    /// - Parameters:
+    ///   - images: 要切换的图片数组
+    ///   - interval: 切换间隔时间,默认2秒
+    ///   - duration: 溶解动画持续时间,默认0.5秒
+    func startImageTransitionAnimation(index:Int = 0, datas: [Any], interval: TimeInterval = 4.0, duration: TimeInterval = 2.0,options: UIView.AnimationOptions = [.transitionCrossDissolve, .curveEaseInOut],setImageHandle:@escaping (Int,Any?)->Void) {
+        guard datas.count > 0 else { return }
+        
+        // 停止已有的动画
+        stopImageTransitionAnimation()
+        
+        // 保存图片数组
+        transitionImages = datas
+        currentImageIndex = index
+        
+        setImageHandle(currentImageIndex,datas.first)
+        
+        // 启动定时器
+        transitionTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { [weak self] _ in
+            guard let self = self else { return }
+            
+            self.currentImageIndex = (self.currentImageIndex + 1) % datas.count
+            
+            UIView.transition(with: self,
+                              duration: duration,
+                              options: options,
+                              animations: {
+                                    setImageHandle(self.currentImageIndex,datas[self.currentImageIndex])
+                              },
+                              completion: nil)
+        }
+    }
+    
+    /// 停止图片循环切换动画
+    func stopImageTransitionAnimation() {
+        transitionTimer?.invalidate()
+        transitionTimer = nil
+        transitionImages = nil
+        currentImageIndex = 0
+    }
+}

+ 15 - 0
TSSmalCoacopods/Classes/Ex/UIView+Ex.swift

@@ -420,3 +420,18 @@ public extension UIView {
         }
     }
 }
+
+
+public extension UIView {
+    /// 移除视图上的所有Layer(保留视图自身的layer)
+    func removeAllSublayers() {
+        layer.sublayers?.forEach { $0.removeFromSuperlayer() }
+    }
+    
+    /// 移除特定类型的所有Layer
+    func removeSublayers<T: CALayer>(ofType layerType: T.Type) {
+        layer.sublayers?
+            .filter { $0.isKind(of: layerType) }
+            .forEach { $0.removeFromSuperlayer() }
+    }
+}

+ 32 - 0
TSSmalCoacopods/Classes/Ex/UIView+Tap.swift

@@ -0,0 +1,32 @@
+//
+//  UIView+Tap.swift
+//  Pods
+//
+//  Created by 100Years on 2025/7/24.
+//
+
+import UIKit
+public extension UIView {
+    private struct AssociatedKeys {
+        static var tapAction = "tapAction"
+    }
+    
+    typealias TapAction = () -> Void
+    
+    /// 添加点击手势(闭包版本)
+    func addTapAction(_ action: @escaping TapAction) {
+        let tap = UITapGestureRecognizer(target: self, action: #selector(handleTSSmalCoaCoPodsTap))
+        tap.cancelsTouchesInView = false
+        self.addGestureRecognizer(tap)
+        self.isUserInteractionEnabled = true
+        
+        // 存储闭包
+        objc_setAssociatedObject(self, &AssociatedKeys.tapAction, action, .OBJC_ASSOCIATION_COPY_NONATOMIC)
+    }
+    
+    @objc private func handleTSSmalCoaCoPodsTap(_ gesture: UITapGestureRecognizer) {
+        if let action = objc_getAssociatedObject(self, &AssociatedKeys.tapAction) as? TapAction {
+            action()
+        }
+    }
+}

+ 12 - 4
TSSmalCoacopods/Classes/GlobalImports/GlobalImports.swift

@@ -137,13 +137,21 @@ public func playVibration() {
 
 public func kPresentModalVC(target:UIViewController,
                      modelVC:UIViewController,
+                            needNewNav:Bool = false,
                        style:UIModalPresentationStyle = .overFullScreen,
              transitionStyle:UIModalTransitionStyle = .coverVertical,
                   completion: (() -> Void)? = nil){
-    let navi = TSBaseNavigationC(rootViewController: modelVC)
-    navi.modalPresentationStyle = style
-    navi.modalTransitionStyle = transitionStyle
-    target.present(navi, animated: true,completion: completion)
+    
+    if needNewNav {
+        let navi = TSBaseNavigationC(rootViewController: modelVC)
+        navi.modalPresentationStyle = style
+        navi.modalTransitionStyle = transitionStyle
+        target.present(navi, animated: true,completion: completion)
+    }else{
+        modelVC.modalPresentationStyle = style
+        modelVC.modalTransitionStyle = transitionStyle
+        target.present(modelVC, animated: true,completion: completion)
+    }
 }
 
 public func kPushVC(target:UIViewController,modelVC:UIViewController){

+ 47 - 7
TSSmalCoacopods/Classes/Tool/TSImageStoreTool.swift

@@ -10,12 +10,12 @@ import Kingfisher
 public class TSImageStoreTool  {
 
     public static func retrieveImageInMemoryCache(urlString: String) -> UIImage? {
-        return ImageCache.default.retrieveImageInMemoryCache(forKey: urlString)
+        return KingfisherManager.shared.cache.retrieveImageInMemoryCache(forKey: urlString)
     }
 
     public static func storeImage(image:UIImage,urlString: String){
         if let url = URL(string: urlString){
-            ImageCache.default.store(image, forKey: url.cacheKey)
+            KingfisherManager.shared.cache.store(image, forKey: url.cacheKey)
         }
     }
 
@@ -26,7 +26,7 @@ public class TSImageStoreTool  {
         }
         
         if let url = URL(string: urlString){
-            ImageCache.default.removeImage(forKey: url.cacheKey)
+             KingfisherManager.shared.cache.removeImage(forKey: url.cacheKey)
         }
     }
     
@@ -49,18 +49,18 @@ public class TSImageStoreTool  {
         let cacheKey = url.cacheKey
         
         // 1. 首先尝试从内存缓存获取
-        if let memoryImage = ImageCache.default.retrieveImageInMemoryCache(forKey: cacheKey) {
+        if let memoryImage =  KingfisherManager.shared.cache.retrieveImageInMemoryCache(forKey: cacheKey) {
             completion(memoryImage)
             return
         }
         
         // 2. 然后尝试从磁盘缓存获取
-        ImageCache.default.retrieveImage(forKey: cacheKey) { result in
+         KingfisherManager.shared.cache.retrieveImage(forKey: cacheKey) { result in
             switch result {
             case .success(let value):
                 if let diskImage = value.image {
                     // 将从磁盘获取的图片存入内存缓存
-                    ImageCache.default.store(diskImage, forKey: cacheKey, toDisk: false)
+                     KingfisherManager.shared.cache.store(diskImage, forKey: cacheKey, toDisk: false)
                     DispatchQueue.main.async {
                         completion(diskImage)
                     }
@@ -105,7 +105,47 @@ public class TSImageStoreTool  {
                     switch result {
                     case .success(let value):
                         // 将下载的图片存入缓存
-                        ImageCache.default.store(value.image, forKey: cacheKey)
+                         KingfisherManager.shared.cache.store(value.image, forKey: cacheKey)
+                        completion(value.image)
+                    case .failure:
+                        completion(nil)
+                    }
+                }
+            }
+        )
+    }
+    
+    
+    
+    /// 从 KF的换从中取图片
+    /// - Parameters:
+    ///   - urlString: url
+    ///   - progressHandler: progressHandler
+    ///   - completion: completion
+    public static func retrieveImage(
+        urlString: String,
+        progressHandler: ((Float) -> Void)? = nil,
+        completion: @escaping (UIImage?) -> Void
+    ) {
+        
+        guard let url = URL(string: urlString) else {
+            completion(nil)
+            return
+        }
+        
+        KingfisherManager.shared.retrieveImage(
+            with: url,
+            options: [],
+            progressBlock: { receivedSize, totalSize in
+                let progress = Float(receivedSize) / Float(totalSize)
+                DispatchQueue.main.async {
+                    progressHandler?(progress)
+                }
+            },
+            completionHandler: { result in
+                DispatchQueue.main.async {
+                    switch result {
+                    case .success(let value):
                         completion(value.image)
                     case .failure:
                         completion(nil)

+ 9 - 2
TSSmalCoacopods/Classes/Tool/TSToastTool.swift

@@ -50,12 +50,17 @@ open class TSToastTool {
             }
             kExecuteOnMainThread {
                 if let containerView = containerView {
-                    SVProgressHUD.setContainerView(containerView)
+                    weak var weakContainer = containerView
+                    SVProgressHUD.setContainerView(weakContainer)
                 }else if let window = Self.getCurrentWindow() {
                     SVProgressHUD.setContainerView(window)
                 }
                 SVProgressHUD.setDefaultMaskType(.none)
                 SVProgressHUD.showInfo(withStatus: text)
+                
+                DispatchQueue.main.asyncAfter(deadline: .now()+duration){
+                    SVProgressHUD.setContainerView(nil)
+                }
             }
         }
     }
@@ -65,7 +70,8 @@ open class TSToastTool {
     public func showLoading(text:String? = nil,containerView:UIView? = WindowHelper.getCurrentWindow()) {
         kExecuteOnMainThread {
             SVProgressHUD.setDefaultMaskType(.clear)
-            SVProgressHUD.setContainerView(containerView)
+            weak var weakContainer = containerView
+            SVProgressHUD.setContainerView(weakContainer)
             SVProgressHUD.show(withStatus: text)
         }
     }
@@ -74,6 +80,7 @@ open class TSToastTool {
     public func hideLoading() {
         kExecuteOnMainThread {
             SVProgressHUD.dismiss()
+            SVProgressHUD.setContainerView(nil)
         }
     }
     

+ 5 - 0
TSSmalCoacopods/Classes/View/UIStackView/TSCustomStackView.swift

@@ -84,6 +84,11 @@ open class TSCustomStackView: UIView {
         }
     }
     
+    // 动态添加子视图的方法
+    public func addArrangedSubview(_ view: UIView) {
+        stackView.addArrangedSubview(view)
+    }
+    
     // 动态添加子视图的方法
     public func addSubviewToStack(_ view: UIView,length:CGFloat? = nil) {
         stackView.addArrangedSubview(view)