TSRandomWallpaperBrowseVC.swift 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  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 imageNamed = isShowVip() ? "vip_icon" : ""
  95. let saveBtn = TSViewTool.createNormalSubmitBtn(title: "Save All".localized,imageNamed: imageNamed) { [weak self] in
  96. guard let self = self else { return }
  97. //判断 vip
  98. if self.dataModel.vip == true,PurchaseManager.default.isVip == false{
  99. TSPurchaseVC.show(target: self) {[weak self] in
  100. guard let self = self else { return }
  101. }
  102. return
  103. }
  104. //保存图片
  105. var imageUrlSting:[String] = [String]()
  106. if let indexArray = self.thumbnailView.collectionView.indexPathsForSelectedItems {
  107. for indexPath in indexArray {
  108. if let item = self.dataModel.items.safeObj(At: indexPath.row),item.imageUrl.contains("http") {
  109. imageUrlSting.append(item.imageUrl)
  110. }
  111. }
  112. }
  113. if imageUrlSting.count == 0 {
  114. return
  115. }
  116. TSToastShared.showLoading()
  117. let group = DispatchGroup()
  118. var images = [UIImage]()
  119. for urlString in imageUrlSting {
  120. group.enter()
  121. TSCommonTool.fetchImageWithCache(from: urlString) { image, error in
  122. if let image = image {
  123. images.append(image)
  124. }
  125. group.leave()
  126. }
  127. }
  128. group.notify(queue: .main) {
  129. PhotoManagerShared.saveImagesToUniqueAlbum(images: images, baseAlbumName: self.dataModel.type) { success, error in
  130. kExecuteOnMainThread {
  131. TSToastShared.hideLoading()
  132. if success {
  133. kSavePhotoSuccesswShared.show(atView: self.view)
  134. } else {
  135. TSToastShared.showToast(text: error?.localizedDescription ?? "Save Failure")
  136. }
  137. }
  138. }
  139. }
  140. }
  141. saveBtn.titleLabel?.font = UIFont.font(size: 14.0)
  142. saveBtn.cornerRadius = 16
  143. return saveBtn
  144. }()
  145. //整个保存 图片的工具栏
  146. lazy var saveImagesToolView: UIView = {
  147. let saveImagesToolView = UIView()
  148. let effctView = TSViewTool.createBlurEffectView(style: .light,backgroundColor: UIColor.fromHex("#000000", alpha: 0.6))
  149. saveImagesToolView.addSubview(effctView)
  150. effctView.snp.makeConstraints { make in
  151. make.edges.equalToSuperview()
  152. }
  153. saveImagesToolView.addSubview(thumbnailView)
  154. thumbnailView.snp.makeConstraints { make in
  155. make.top.equalTo(16)
  156. make.leading.trailing.equalTo(0)
  157. make.height.equalTo(100)
  158. }
  159. saveImagesToolView.addSubview(selecAllView)
  160. selecAllView.snp.makeConstraints { make in
  161. make.leading.equalTo(16)
  162. make.top.equalTo(thumbnailView.snp.bottom).offset(18)
  163. }
  164. saveImagesToolView.addSubview(saveBtn)
  165. saveBtn.snp.makeConstraints { make in
  166. make.trailing.equalTo(-16)
  167. make.top.equalTo(thumbnailView.snp.bottom).offset(12)
  168. make.width.equalTo(110)
  169. make.height.equalTo(32)
  170. }
  171. return saveImagesToolView
  172. }()
  173. //MARK: previewView
  174. lazy var previewView: UIView = {
  175. let previewView = UIView()
  176. previewView.isHidden = true
  177. let imageView = UIImageView.createImageView(imageName:"iPhone_lock_screen_preview")
  178. previewView.addSubview(imageView)
  179. imageView.snp.makeConstraints { make in
  180. make.edges.equalToSuperview()
  181. }
  182. let tap = UITapGestureRecognizer(target: self, action: #selector(onPreviewButton))
  183. previewView.addGestureRecognizer(tap)
  184. return previewView
  185. }()
  186. lazy var collectionView: UICollectionView = {
  187. let layout = UICollectionViewFlowLayout()
  188. layout.scrollDirection = .horizontal // 横向滚动
  189. layout.itemSize = UIScreen.main.bounds.size // 每个 item 的大小
  190. layout.minimumLineSpacing = 0 // item 之间的间隔
  191. layout.minimumInteritemSpacing = 0 // item 之间的间隔
  192. let collectionView = UICollectionView(frame: UIScreen.main.bounds, collectionViewLayout: layout)
  193. collectionView.translatesAutoresizingMaskIntoConstraints = false
  194. collectionView.contentInsetAdjustmentBehavior = .never
  195. collectionView.backgroundColor = UIColor.black
  196. collectionView.register(TSRandomWallpaperBrowseCell.self, forCellWithReuseIdentifier: "Cell")
  197. collectionView.isPagingEnabled = true
  198. collectionView.dataSource = self
  199. collectionView.delegate = self
  200. collectionView.showsVerticalScrollIndicator = false
  201. collectionView.showsHorizontalScrollIndicator = false
  202. return collectionView
  203. }()
  204. override func createView() {
  205. setNavBarViewHidden(true)
  206. view.backgroundColor = .clear
  207. contentView.addSubview(collectionView)
  208. contentView.addSubview(btnsAllView)
  209. contentView.addSubview(previewView)
  210. contentView.addSubview(backBtn)
  211. collectionView.snp.makeConstraints { make in
  212. make.edges.equalToSuperview()
  213. }
  214. btnsAllView.snp.makeConstraints { make in
  215. make.edges.equalToSuperview()
  216. }
  217. previewView.snp.makeConstraints { make in
  218. make.edges.equalToSuperview()
  219. }
  220. backBtn.snp.makeConstraints { make in
  221. make.leading.equalTo(16)
  222. make.top.equalTo(topLineH)
  223. make.width.height.equalTo(44)
  224. }
  225. let pan = UIPanGestureRecognizer(target: self, action: #selector(onPanGesture(_:)))
  226. view.addGestureRecognizer(pan)
  227. }
  228. func isShowVip() -> Bool {
  229. return self.dataModel.vip
  230. }
  231. }
  232. //MARK: 点击操作
  233. extension TSRandomWallpaperBrowseVC{
  234. @objc func onPreviewButton() {
  235. isPreview = !isPreview
  236. }
  237. @objc func onPanGesture(_ pan: UIPanGestureRecognizer) {
  238. let trans = pan.translation(in: self.view)
  239. let velocity = pan.velocity(in: nil)
  240. switch pan.state {
  241. case .began:
  242. if abs(trans.x) > abs(trans.y) {
  243. isPanningDown = false
  244. }
  245. else if trans.y > 0 {
  246. isPanningDown = true
  247. }
  248. case .changed:
  249. switch isPanningDown {
  250. case .none:
  251. if abs(trans.x) > abs(trans.y) {
  252. isPanningDown = false
  253. }
  254. else if trans.y > 0 {
  255. isPanningDown = true
  256. }
  257. case .some(true):
  258. var viewTrans = self.view.transform
  259. viewTrans = viewTrans.translatedBy(x: 0, y: trans.y)
  260. if viewTrans.ty >= 0 {
  261. self.view.transform = viewTrans
  262. }
  263. case .some(false):
  264. let newOffsetX = self.collectionView.contentOffset.x - trans.x
  265. if newOffsetX >= 0 &&
  266. newOffsetX <= (self.collectionView.contentSize.width - self.collectionView.bounds.width) {
  267. self.collectionView.contentOffset.x -= trans.x
  268. }
  269. }
  270. pan.setTranslation(.zero, in: pan.view)
  271. case .ended:
  272. switch isPanningDown {
  273. case .none:
  274. debugPrint("no thing to do ")
  275. self.view.transform = .identity
  276. case .some(true):
  277. if self.view.transform.ty > 80 ||
  278. velocity.y >= 500 {
  279. UIView.animate(withDuration: 0.2) { [weak self] in
  280. self?.view.transform.ty = k_ScreenHeight
  281. } completion: { [weak self] finished in
  282. if finished {
  283. self?.dismiss(animated: false)
  284. }
  285. }
  286. }
  287. else {
  288. self.view.transform = .identity
  289. }
  290. case .some(false):
  291. let velocity = pan.velocity(in: pan.view)
  292. let page: CGFloat
  293. if velocity.x >= 500 {
  294. page = (collectionView.contentOffset.x / collectionView.bounds.width).rounded(.down)
  295. }
  296. else if velocity.x <= 500 {
  297. page = (collectionView.contentOffset.x / collectionView.bounds.width).rounded(.up)
  298. }
  299. else {
  300. page = (collectionView.contentOffset.x / collectionView.bounds.width).rounded()
  301. }
  302. let newOffsetX = page * collectionView.bounds.width
  303. collectionView.setContentOffset(CGPoint(x: newOffsetX, y: 0), animated: true)
  304. }
  305. isPanningDown = nil
  306. case .cancelled, .failed:
  307. self.view.transform = CGAffineTransform.identity
  308. isPanningDown = nil
  309. default:
  310. debugPrint(pan.state)
  311. debugPrint(pan.translation(in: self.view))
  312. }
  313. }
  314. }
  315. //MARK: UICollectionViewDataSource
  316. extension TSRandomWallpaperBrowseVC:UICollectionViewDataSource,UICollectionViewDelegate {
  317. // func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
  318. // resetIndexWithOffset(scrollView)
  319. // }
  320. //
  321. // func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
  322. // resetIndexWithOffset(scrollView)
  323. // }
  324. //
  325. // private func resetIndexWithOffset(_ scrollView: UIScrollView) {
  326. // let item = Int((scrollView.contentOffset.x / scrollView.bounds.width).rounded())
  327. // }
  328. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  329. return dataModel.items.count
  330. }
  331. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  332. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! TSRandomWallpaperBrowseCell
  333. if let wallpaperModel = dataModel.items.safeObj(At: indexPath.item), wallpaperModel.imageUrl.count > 0 {
  334. cell.showImageView.setAsyncImage(urlString: wallpaperModel.imageUrl,placeholder: kWapppaperPlaceholderImage)
  335. }
  336. return cell
  337. }
  338. }
  339. class TSRandomWallpaperBrowseCell : TSBaseCollectionCell {
  340. private let showImageViewW = k_ScreenWidth - 32
  341. lazy var showImageView: UIImageView = {
  342. let imageView = UIImageView()
  343. return imageView
  344. }()
  345. override func creatUI() {
  346. self.backgroundColor = UIColor.clear
  347. self.contentView.backgroundColor = UIColor.clear
  348. bgContentView.addSubview(showImageView)
  349. showImageView.snp.makeConstraints { make in
  350. make.edges.equalToSuperview()
  351. }
  352. }
  353. }