UIImageView+Ex.swift 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. //
  2. // UIImageView+Ex.swift
  3. // TSLiveWallpaper
  4. //
  5. // Created by 100Years on 2024/12/20.
  6. //
  7. import Kingfisher
  8. class TSCustomActivityIndicator: Indicator {
  9. let activityIndicator = UIActivityIndicatorView(style: .medium)
  10. init(color: UIColor) {
  11. activityIndicator.color = color
  12. }
  13. func startAnimatingView() {
  14. activityIndicator.startAnimating()
  15. }
  16. func stopAnimatingView() {
  17. activityIndicator.stopAnimating()
  18. }
  19. var view: IndicatorView {
  20. return activityIndicator
  21. }
  22. }
  23. public extension UIImageView {
  24. /// 创建并配置 UIImageView
  25. /// - Parameters:
  26. /// - imageName: 图片名称
  27. /// - contentMode: 内容模式,默认为 `.scaleAspectFit`
  28. /// - backgroundColor: 背景颜色,默认为透明
  29. /// - Returns: 配置完成的 UIImageView 实例
  30. static public func createImageView(
  31. image:UIImage? = nil,
  32. imageName: String? = nil,
  33. contentMode: UIView.ContentMode = .scaleAspectFit,
  34. backgroundColor: UIColor = .clear,
  35. corner: CGFloat = 0.0) -> UIImageView {
  36. let imageView = UIImageView()
  37. if let image = image{
  38. imageView.image = image
  39. }
  40. if let imageName = imageName ,imageName.count > 0 {
  41. imageView.image = UIImage(named: imageName)
  42. }
  43. imageView.contentMode = contentMode
  44. imageView.backgroundColor = backgroundColor
  45. imageView.cornerRadius = corner
  46. return imageView
  47. }
  48. /// 异步创建并加载图片的 UIImageView
  49. /// - Parameters:
  50. /// - imageName: 本地占位图片名称
  51. /// - urlString: 图片的 URL 字符串
  52. /// - contentMode: 内容模式,默认为 `.scaleAspectFit`
  53. /// - backgroundColor: 背景颜色,默认为透明
  54. /// - showLoading: 是否显示加载动画,默认为 `true`
  55. /// - completion: 图片加载成功后的回调
  56. static public func createAsyncImageView(urlString: String?,
  57. placeholder:UIImage?,
  58. contentMode: UIView.ContentMode = .scaleAspectFit,
  59. adaptiveMode:Bool = false,
  60. backgroundColor: UIColor = .clear,
  61. showLoading: Bool = false,
  62. progressBlock: ((Float)->Void)? = nil,
  63. completion: ((UIImage?) -> Void)? = nil) -> UIImageView {
  64. let imageView = UIImageView()
  65. imageView.setAsyncImage(urlString: urlString,
  66. placeholder:placeholder,
  67. contentMode:contentMode,
  68. adaptiveMode:adaptiveMode,
  69. backgroundColor:backgroundColor,
  70. showLoading:showLoading,
  71. progressBlock:progressBlock,
  72. completion:completion)
  73. return imageView
  74. }
  75. public func setAsyncImage(urlString: String?,
  76. placeholder: UIImage? = nil,
  77. contentMode: UIView.ContentMode = .scaleAspectFit,
  78. adaptiveMode:Bool = false,
  79. backgroundColor: UIColor = .clear,
  80. showLoading: Bool = false,
  81. progressBlock: ((Float)->Void)? = nil,
  82. completion: ((UIImage?) -> Void)? = nil){
  83. let imageView = self
  84. imageView.contentMode = contentMode
  85. imageView.backgroundColor = backgroundColor
  86. imageView.image = placeholder
  87. guard let urlString = urlString else {
  88. completion?(nil)
  89. return
  90. }
  91. if urlString.count == 0 {
  92. completion?(nil)
  93. return
  94. }
  95. if urlString.contains("http") {
  96. guard let url = URL(string: urlString) else {
  97. completion?(nil)
  98. return
  99. }
  100. kf.indicatorType = showLoading ? .custom(indicator: TSCustomActivityIndicator(color: .white)) : .none
  101. imageView.kf.setImage(with: url,
  102. placeholder: placeholder,
  103. options: nil,
  104. progressBlock: { receivedSize, totalSize in
  105. let progress = receivedSize/totalSize
  106. progressBlock?(Float(progress))
  107. }){ result in
  108. if let image = try? result.get().image {
  109. kDelayMainShort {
  110. completion?(image)
  111. }
  112. }else{
  113. completion?(nil)
  114. }
  115. }
  116. }else if urlString.contains("/") {
  117. imageView.image = UIImage(contentsOfFile: urlString.fillCachePath)
  118. completion?(imageView.image)
  119. }else {
  120. if let image = UIImage(named: urlString) {
  121. imageView.image = image
  122. completion?(image)
  123. }
  124. }
  125. }
  126. }
  127. public extension UIImageView {
  128. static public func createRightArrow() -> UIImageView {
  129. let imageView = UIImageView()
  130. imageView.image = UIImage(named: "white_right_arrow")
  131. return imageView
  132. }
  133. /// 根据图片比例自动选择最佳缩放模式
  134. public func adaptiveScale() {
  135. // guard let image = image else { return }
  136. //
  137. // let viewSize = bounds.size
  138. // let imageRatio = image.size.width / image.size.height
  139. // let viewRatio = viewSize.width / viewSize.height
  140. //
  141. // let contentNewMode:UIView.ContentMode = imageRatio > viewRatio ? .scaleAspectFill : .scaleAspectFit
  142. // self.contentMode = contentNewMode
  143. //
  144. // dePrint("UIImageView.adaptiveScale contentMode =\(contentNewMode)")
  145. }
  146. }
  147. public extension UIImageView {
  148. public func setImage(_ image: UIImage?, duration: CFTimeInterval = 0.2, animated: Bool = true) {
  149. if let image = image {
  150. if animated {
  151. UIView.transition(
  152. with: self,
  153. duration: duration,
  154. options: [.transitionCrossDissolve, .curveEaseInOut, .allowUserInteraction]
  155. ) {
  156. self.image = image
  157. }
  158. }else {
  159. self.image = image
  160. }
  161. }
  162. }
  163. }
  164. public extension UIImageView {
  165. static func retrieveImageInMemoryCache(urlString: String) -> UIImage? {
  166. return ImageCache.default.retrieveImageInMemoryCache(forKey: urlString)
  167. }
  168. static func downloadImageWithProgress(
  169. urlString: String,
  170. progressHandler: ((Float) -> Void)? = nil,
  171. completion: @escaping (UIImage?) -> Void
  172. ) {
  173. guard let url = URL(string: urlString) else {
  174. completion(nil)
  175. return
  176. }
  177. KingfisherManager.shared.retrieveImage(
  178. with: url,
  179. options: [],
  180. progressBlock: { receivedSize, totalSize in
  181. let progress = Float(receivedSize) / Float(totalSize)
  182. DispatchQueue.main.async {
  183. progressHandler?(progress) // 回传进度(主线程)
  184. }
  185. },
  186. completionHandler: { result in
  187. DispatchQueue.main.async {
  188. switch result {
  189. case .success(let value):
  190. completion(value.image)
  191. case .failure:
  192. completion(nil)
  193. }
  194. }
  195. }
  196. )
  197. }
  198. }