TSRandomWallpaperBrowseVC.swift 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. //
  2. // TSRandomWallpaperBrowseVC.swift
  3. // TSLiveWallpaper
  4. //
  5. // Created by 100Years on 2024/12/24.
  6. //
  7. private let topLineH = k_Height_statusBar()
  8. class TSRandomWallpaperBrowseVC: TSBaseVC {
  9. private var isPanningDown: Bool?
  10. lazy var isPreview = false {
  11. didSet {
  12. self.previewView.isHidden = !isPreview
  13. self.btnsAllView.isHidden = isPreview
  14. }
  15. }
  16. var dataModel:TSRandomWallpaperDataItemModel
  17. init(dataModel: TSRandomWallpaperDataItemModel) {
  18. self.dataModel = dataModel
  19. super.init()
  20. }
  21. @MainActor required init?(coder: NSCoder) {
  22. fatalError("init(coder:) has not been implemented")
  23. }
  24. lazy var backBtn: UIButton = {
  25. return UIButton.createButton(image: UIImage(named: "navi_back_white"),backgroundColor: UIColor.fromHex("#111111", alpha: 0.2),corner: 16.0) { [weak self] in
  26. self?.pop()
  27. }
  28. }()
  29. //MARK: btnsAllView
  30. lazy var btnsAllView: UIView = {
  31. let btnsAllView = UIView()
  32. //版权信息按钮
  33. let copyrightBtn = UIButton.createButton(image: UIImage(named: "info_white"),backgroundColor: UIColor.fromHex("#111111", alpha: 0.2),corner: 16.0) { [weak self] in
  34. guard let self = self else { return }
  35. navigationController?.pushViewController(TSRandomWallpaperCopyrightVC(), animated: true)
  36. }
  37. btnsAllView.addSubview(copyrightBtn)
  38. copyrightBtn.snp.makeConstraints { make in
  39. make.width.height.equalTo(44)
  40. make.trailing.equalTo(-16)
  41. make.top.equalTo(topLineH)
  42. }
  43. btnsAllView.addSubview(saveImagesToolView)
  44. saveImagesToolView.snp.makeConstraints { make in
  45. make.bottom.leading.trailing.equalTo(0)
  46. make.height.equalTo(k_Height_StatusBar+168)
  47. }
  48. //教程按钮
  49. let tutorialsBtn = UIButton.createButton(image: UIImage(named: "random_tutorials"),backgroundColor: UIColor.fromHex("#000000", alpha: 0.5),corner: 19.0) { [weak self] in
  50. guard let self = self else { return }
  51. navigationController?.pushViewController(TSRandomWallpaperTutorialsVC(), animated: true)
  52. }
  53. btnsAllView.addSubview(tutorialsBtn)
  54. tutorialsBtn.snp.makeConstraints { make in
  55. make.centerX.equalToSuperview().offset(-20-39.0)
  56. make.bottom.equalTo(saveImagesToolView.snp.top).offset(-20)
  57. make.width.height.equalTo(58)
  58. }
  59. //预览按钮
  60. let previewBtn = UIButton.createButton(image: UIImage(named: "random_preview"),backgroundColor: UIColor.fromHex("#000000", alpha: 0.5),corner: 19.0) { [weak self] in
  61. guard let self = self else { return }
  62. self.isPreview = !self.isPreview
  63. }
  64. btnsAllView.addSubview(previewBtn)
  65. previewBtn.snp.makeConstraints { make in
  66. make.centerX.equalToSuperview().offset(20+39.0)
  67. make.bottom.equalTo(saveImagesToolView.snp.top).offset(-20)
  68. make.width.height.equalTo(58)
  69. }
  70. return btnsAllView
  71. }()
  72. //缩略图view
  73. lazy var thumbnailView: TSRandomWallpaperBrowseSelectView = {
  74. let thumbnailView = TSRandomWallpaperBrowseSelectView()
  75. thumbnailView.items = dataModel.items
  76. thumbnailView.selectedCallBack = { [weak self] selectedArray in
  77. guard let self = self else { return }
  78. selecAllView.isSelected = selectedArray.count == 0 ? false : true
  79. selecAllView.selectNumLabel.text = "(\(selectedArray.count)/\(self.dataModel.items.count))"
  80. saveBtn.isEnabled = selecAllView.isSelected
  81. }
  82. return thumbnailView
  83. }()
  84. lazy var selecAllView: TSRandomWallpaperSelecAllView = {
  85. let selecAllView = TSRandomWallpaperSelecAllView()
  86. selecAllView.selectNumLabel.text = "(\(self.dataModel.items.count)/\(self.dataModel.items.count))"
  87. selecAllView.clickCallBack = { [weak self] in
  88. guard let self = self else { return }
  89. self.thumbnailView.clickSelectHandle()
  90. }
  91. return selecAllView
  92. }()
  93. lazy var saveBtn: UIButton = {
  94. let saveBtn = TSViewTool.createNormalSubmitBtn(title: "Save All".localized) { [weak self] in
  95. guard let self = self else { return }
  96. var imageUrlSting:[String] = [String]()
  97. if let indexArray = self.thumbnailView.collectionView.indexPathsForSelectedItems {
  98. for indexPath in indexArray {
  99. if let item = self.dataModel.items.safeObj(At: indexPath.row),item.imageUrl.contains("http") {
  100. imageUrlSting.append(item.imageUrl)
  101. }
  102. }
  103. }
  104. if imageUrlSting.count == 0 {
  105. return
  106. }
  107. TSToastShared.showLoading(in: self.view)
  108. let group = DispatchGroup()
  109. var images = [UIImage]()
  110. for urlString in imageUrlSting {
  111. group.enter()
  112. TSCommonTool.fetchImageWithCache(from: urlString) { image, error in
  113. if let image = image {
  114. images.append(image)
  115. }
  116. group.leave()
  117. }
  118. }
  119. group.notify(queue: .main) {
  120. PhotoManagerShared.saveImagesToUniqueAlbum(images: images, baseAlbumName: self.dataModel.type) { success, error in
  121. kExecuteOnMainThread {
  122. TSToastShared.hideLoading()
  123. if success {
  124. kSavePhotoSuccesswShared.show(atView: self.view)
  125. } else {
  126. TSToastShared.showToast(message: error?.localizedDescription ?? "Save Failure")
  127. }
  128. }
  129. }
  130. }
  131. }
  132. saveBtn.titleLabel?.font = UIFont.font(size: 14.0)
  133. saveBtn.cornerRadius = 16
  134. return saveBtn
  135. }()
  136. //整个保存 图片的工具栏
  137. lazy var saveImagesToolView: UIView = {
  138. let saveImagesToolView = UIView()
  139. let effctView = TSViewTool.createBlurEffectView(style: .light,backgroundColor: UIColor.fromHex("#000000", alpha: 0.6))
  140. saveImagesToolView.addSubview(effctView)
  141. effctView.snp.makeConstraints { make in
  142. make.edges.equalToSuperview()
  143. }
  144. saveImagesToolView.addSubview(thumbnailView)
  145. thumbnailView.snp.makeConstraints { make in
  146. make.top.equalTo(16)
  147. make.leading.trailing.equalTo(0)
  148. make.height.equalTo(100)
  149. }
  150. saveImagesToolView.addSubview(selecAllView)
  151. selecAllView.snp.makeConstraints { make in
  152. make.leading.equalTo(16)
  153. make.top.equalTo(thumbnailView.snp.bottom).offset(18)
  154. }
  155. saveImagesToolView.addSubview(saveBtn)
  156. saveBtn.snp.makeConstraints { make in
  157. make.trailing.equalTo(-16)
  158. make.top.equalTo(thumbnailView.snp.bottom).offset(12)
  159. make.width.equalTo(110)
  160. make.height.equalTo(32)
  161. }
  162. return saveImagesToolView
  163. }()
  164. //MARK: previewView
  165. lazy var previewView: UIView = {
  166. let previewView = UIView()
  167. previewView.isHidden = true
  168. let imageView = UIImageView.createImageView(imageName:"iPhone_lock_screen_preview")
  169. previewView.addSubview(imageView)
  170. imageView.snp.makeConstraints { make in
  171. make.edges.equalToSuperview()
  172. }
  173. let tap = UITapGestureRecognizer(target: self, action: #selector(onPreviewButton))
  174. previewView.addGestureRecognizer(tap)
  175. return previewView
  176. }()
  177. lazy var collectionView: UICollectionView = {
  178. let layout = UICollectionViewFlowLayout()
  179. layout.scrollDirection = .horizontal // 横向滚动
  180. layout.itemSize = UIScreen.main.bounds.size // 每个 item 的大小
  181. layout.minimumLineSpacing = 0 // item 之间的间隔
  182. layout.minimumInteritemSpacing = 0 // item 之间的间隔
  183. let collectionView = UICollectionView(frame: UIScreen.main.bounds, collectionViewLayout: layout)
  184. collectionView.translatesAutoresizingMaskIntoConstraints = false
  185. collectionView.contentInsetAdjustmentBehavior = .never
  186. collectionView.backgroundColor = UIColor.black
  187. collectionView.register(TSRandomWallpaperBrowseCell.self, forCellWithReuseIdentifier: "Cell")
  188. collectionView.isPagingEnabled = true
  189. collectionView.dataSource = self
  190. collectionView.delegate = self
  191. collectionView.showsVerticalScrollIndicator = false
  192. collectionView.showsHorizontalScrollIndicator = false
  193. return collectionView
  194. }()
  195. override func createView() {
  196. setNavBarViewHidden(true)
  197. view.backgroundColor = .clear
  198. contentView.addSubview(collectionView)
  199. contentView.addSubview(btnsAllView)
  200. contentView.addSubview(previewView)
  201. contentView.addSubview(backBtn)
  202. collectionView.snp.makeConstraints { make in
  203. make.edges.equalToSuperview()
  204. }
  205. btnsAllView.snp.makeConstraints { make in
  206. make.edges.equalToSuperview()
  207. }
  208. previewView.snp.makeConstraints { make in
  209. make.edges.equalToSuperview()
  210. }
  211. backBtn.snp.makeConstraints { make in
  212. make.leading.equalTo(16)
  213. make.top.equalTo(topLineH)
  214. make.width.height.equalTo(44)
  215. }
  216. let pan = UIPanGestureRecognizer(target: self, action: #selector(onPanGesture(_:)))
  217. view.addGestureRecognizer(pan)
  218. }
  219. }
  220. //MARK: 点击操作
  221. extension TSRandomWallpaperBrowseVC{
  222. @objc func onPreviewButton() {
  223. isPreview = !isPreview
  224. }
  225. @objc func onPanGesture(_ pan: UIPanGestureRecognizer) {
  226. let trans = pan.translation(in: self.view)
  227. let velocity = pan.velocity(in: nil)
  228. switch pan.state {
  229. case .began:
  230. if abs(trans.x) > abs(trans.y) {
  231. isPanningDown = false
  232. }
  233. else if trans.y > 0 {
  234. isPanningDown = true
  235. }
  236. case .changed:
  237. switch isPanningDown {
  238. case .none:
  239. if abs(trans.x) > abs(trans.y) {
  240. isPanningDown = false
  241. }
  242. else if trans.y > 0 {
  243. isPanningDown = true
  244. }
  245. case .some(true):
  246. var viewTrans = self.view.transform
  247. viewTrans = viewTrans.translatedBy(x: 0, y: trans.y)
  248. if viewTrans.ty >= 0 {
  249. self.view.transform = viewTrans
  250. }
  251. case .some(false):
  252. let newOffsetX = self.collectionView.contentOffset.x - trans.x
  253. if newOffsetX >= 0 &&
  254. newOffsetX <= (self.collectionView.contentSize.width - self.collectionView.bounds.width) {
  255. self.collectionView.contentOffset.x -= trans.x
  256. }
  257. }
  258. pan.setTranslation(.zero, in: pan.view)
  259. case .ended:
  260. switch isPanningDown {
  261. case .none:
  262. debugPrint("no thing to do ")
  263. self.view.transform = .identity
  264. case .some(true):
  265. if self.view.transform.ty > 80 ||
  266. velocity.y >= 500 {
  267. UIView.animate(withDuration: 0.2) { [weak self] in
  268. self?.view.transform.ty = k_ScreenHeight
  269. } completion: { [weak self] finished in
  270. if finished {
  271. self?.dismiss(animated: false)
  272. }
  273. }
  274. }
  275. else {
  276. self.view.transform = .identity
  277. }
  278. case .some(false):
  279. let velocity = pan.velocity(in: pan.view)
  280. let page: CGFloat
  281. if velocity.x >= 500 {
  282. page = (collectionView.contentOffset.x / collectionView.bounds.width).rounded(.down)
  283. }
  284. else if velocity.x <= 500 {
  285. page = (collectionView.contentOffset.x / collectionView.bounds.width).rounded(.up)
  286. }
  287. else {
  288. page = (collectionView.contentOffset.x / collectionView.bounds.width).rounded()
  289. }
  290. let newOffsetX = page * collectionView.bounds.width
  291. collectionView.setContentOffset(CGPoint(x: newOffsetX, y: 0), animated: true)
  292. }
  293. isPanningDown = nil
  294. case .cancelled, .failed:
  295. self.view.transform = CGAffineTransform.identity
  296. isPanningDown = nil
  297. default:
  298. debugPrint(pan.state)
  299. debugPrint(pan.translation(in: self.view))
  300. }
  301. }
  302. }
  303. //MARK: UICollectionViewDataSource
  304. extension TSRandomWallpaperBrowseVC:UICollectionViewDataSource,UICollectionViewDelegate {
  305. // func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
  306. // resetIndexWithOffset(scrollView)
  307. // }
  308. //
  309. // func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
  310. // resetIndexWithOffset(scrollView)
  311. // }
  312. //
  313. // private func resetIndexWithOffset(_ scrollView: UIScrollView) {
  314. // let item = Int((scrollView.contentOffset.x / scrollView.bounds.width).rounded())
  315. // }
  316. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  317. return dataModel.items.count
  318. }
  319. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  320. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! TSRandomWallpaperBrowseCell
  321. if let wallpaperModel = dataModel.items.safeObj(At: indexPath.item), wallpaperModel.imageUrl.count > 0 {
  322. cell.showImageView.setAsyncImage(urlString: wallpaperModel.imageUrl,placeholder: kWapppaperPlaceholderImage)
  323. }
  324. return cell
  325. }
  326. }
  327. class TSRandomWallpaperBrowseCell : TSBaseCollectionCell {
  328. private let showImageViewW = k_ScreenWidth - 32
  329. lazy var showImageView: UIImageView = {
  330. let imageView = UIImageView()
  331. return imageView
  332. }()
  333. override func creatUI() {
  334. self.backgroundColor = UIColor.clear
  335. self.contentView.backgroundColor = UIColor.clear
  336. bgContentView.addSubview(showImageView)
  337. showImageView.snp.makeConstraints { make in
  338. make.edges.equalToSuperview()
  339. }
  340. }
  341. }