ZLInputTextViewController.swift 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. //
  2. // ZLInputTextViewController.swift
  3. // ZLPhotoBrowser
  4. //
  5. // Created by long on 2020/10/30.
  6. //
  7. // Copyright (c) 2020 Long Zhang <495181165@qq.com>
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining a copy
  10. // of this software and associated documentation files (the "Software"), to deal
  11. // in the Software without restriction, including without limitation the rights
  12. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. // copies of the Software, and to permit persons to whom the Software is
  14. // furnished to do so, subject to the following conditions:
  15. //
  16. // The above copyright notice and this permission notice shall be included in
  17. // all copies or substantial portions of the Software.
  18. //
  19. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. // THE SOFTWARE.
  26. import UIKit
  27. class ZLInputTextViewController: UIViewController {
  28. static let collectionViewHeight: CGFloat = 50
  29. let image: UIImage?
  30. var text: String
  31. var cancelBtn: UIButton!
  32. var doneBtn: UIButton!
  33. var textView: UITextView!
  34. var collectionView: UICollectionView!
  35. var currentTextColor: UIColor
  36. /// text, textColor, bgColor
  37. var endInput: ( (String, UIColor, UIColor) -> Void )?
  38. override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
  39. return .portrait
  40. }
  41. override var prefersStatusBarHidden: Bool {
  42. return true
  43. }
  44. deinit {
  45. zl_debugPrint("ZLInputTextViewController deinit")
  46. }
  47. init(image: UIImage?, text: String? = nil, textColor: UIColor? = nil, bgColor: UIColor? = nil) {
  48. self.image = image
  49. self.text = text ?? ""
  50. if let _ = textColor {
  51. self.currentTextColor = textColor!
  52. } else {
  53. if !ZLPhotoConfiguration.default().textStickerTextColors.contains(ZLPhotoConfiguration.default().textStickerDefaultTextColor) {
  54. self.currentTextColor = ZLPhotoConfiguration.default().textStickerTextColors.first!
  55. } else {
  56. self.currentTextColor = ZLPhotoConfiguration.default().textStickerDefaultTextColor
  57. }
  58. }
  59. super.init(nibName: nil, bundle: nil)
  60. }
  61. required init?(coder: NSCoder) {
  62. fatalError("init(coder:) has not been implemented")
  63. }
  64. override func viewDidLoad() {
  65. super.viewDidLoad()
  66. self.setupUI()
  67. NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIApplication.keyboardWillShowNotification, object: nil)
  68. }
  69. override func viewWillAppear(_ animated: Bool) {
  70. super.viewWillAppear(animated)
  71. self.textView.becomeFirstResponder()
  72. }
  73. override func viewDidLayoutSubviews() {
  74. super.viewDidLayoutSubviews()
  75. var insets = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
  76. if #available(iOS 11.0, *) {
  77. insets = self.view.safeAreaInsets
  78. }
  79. let btnY = insets.top + 20
  80. let cancelBtnW = localLanguageTextValue(.cancel).boundingRect(font: ZLLayout.bottomToolTitleFont, limitSize: CGSize(width: .greatestFiniteMagnitude, height: ZLLayout.bottomToolBtnH)).width + 20
  81. self.cancelBtn.frame = CGRect(x: 15, y: btnY, width: cancelBtnW, height: ZLLayout.bottomToolBtnH)
  82. let doneBtnW = localLanguageTextValue(.done).boundingRect(font: ZLLayout.bottomToolTitleFont, limitSize: CGSize(width: .greatestFiniteMagnitude, height: ZLLayout.bottomToolBtnH)).width + 20
  83. self.doneBtn.frame = CGRect(x: view.bounds.width - 20 - doneBtnW, y: btnY, width: doneBtnW, height: ZLLayout.bottomToolBtnH)
  84. self.textView.frame = CGRect(x: 20, y: cancelBtn.frame.maxY + 20, width: view.bounds.width - 40, height: 150)
  85. if let index = ZLPhotoConfiguration.default().textStickerTextColors.firstIndex(where: { $0 == self.currentTextColor}) {
  86. self.collectionView.scrollToItem(at: IndexPath(row: index, section: 0), at: .centeredHorizontally, animated: false)
  87. }
  88. }
  89. func setupUI() {
  90. self.view.backgroundColor = .black
  91. let bgImageView = UIImageView(image: image?.blurImage(level: 4))
  92. bgImageView.frame = self.view.bounds
  93. bgImageView.contentMode = .scaleAspectFit
  94. self.view.addSubview(bgImageView)
  95. let coverView = UIView(frame: bgImageView.bounds)
  96. coverView.backgroundColor = .black
  97. coverView.alpha = 0.4
  98. bgImageView.addSubview(coverView)
  99. self.cancelBtn = UIButton(type: .custom)
  100. self.cancelBtn.setTitle(localLanguageTextValue(.cancel), for: .normal)
  101. self.cancelBtn.titleLabel?.font = ZLLayout.bottomToolTitleFont
  102. self.cancelBtn.addTarget(self, action: #selector(cancelBtnClick), for: .touchUpInside)
  103. view.addSubview(self.cancelBtn)
  104. self.doneBtn = UIButton(type: .custom)
  105. self.doneBtn.setTitle(localLanguageTextValue(.done), for: .normal)
  106. self.doneBtn.titleLabel?.font = ZLLayout.bottomToolTitleFont
  107. self.doneBtn.addTarget(self, action: #selector(doneBtnClick), for: .touchUpInside)
  108. view.addSubview(self.doneBtn)
  109. self.textView = UITextView(frame: .zero)
  110. self.textView.keyboardAppearance = .dark
  111. self.textView.returnKeyType = .done
  112. self.textView.delegate = self
  113. self.textView.backgroundColor = .clear
  114. self.textView.tintColor = .bottomToolViewBtnNormalBgColor
  115. self.textView.textColor = self.currentTextColor
  116. self.textView.text = self.text
  117. self.textView.font = UIFont.boldSystemFont(ofSize: ZLTextStickerView.fontSize)
  118. view.addSubview(self.textView)
  119. let layout = UICollectionViewFlowLayout()
  120. layout.itemSize = CGSize(width: 30, height: 30)
  121. layout.minimumLineSpacing = 15
  122. layout.minimumInteritemSpacing = 15
  123. layout.scrollDirection = .horizontal
  124. layout.sectionInset = UIEdgeInsets(top: 10, left: 30, bottom: 10, right: 30)
  125. self.collectionView = UICollectionView(frame: CGRect(x: 0, y: self.view.frame.height - ZLInputTextViewController.collectionViewHeight, width: self.view.frame.width, height: ZLInputTextViewController.collectionViewHeight), collectionViewLayout: layout)
  126. self.collectionView.backgroundColor = .clear
  127. self.collectionView.delegate = self
  128. self.collectionView.dataSource = self
  129. self.collectionView.showsHorizontalScrollIndicator = false
  130. self.view.addSubview(self.collectionView)
  131. ZLDrawColorCell.zl_register(self.collectionView)
  132. }
  133. @objc func cancelBtnClick() {
  134. self.dismiss(animated: true, completion: nil)
  135. }
  136. @objc func doneBtnClick() {
  137. self.endInput?(self.textView.text, self.currentTextColor, .clear)
  138. self.dismiss(animated: true, completion: nil)
  139. }
  140. @objc func keyboardWillShow(_ notify: Notification) {
  141. let rect = notify.userInfo?[UIApplication.keyboardFrameEndUserInfoKey] as? CGRect
  142. let keyboardH = rect?.height ?? 366
  143. let duration: TimeInterval = notify.userInfo?[UIApplication.keyboardAnimationDurationUserInfoKey] as? TimeInterval ?? 0.25
  144. UIView.animate(withDuration: max(duration, 0.25)) {
  145. self.collectionView.frame = CGRect(x: 0, y: self.view.frame.height - keyboardH - ZLInputTextViewController.collectionViewHeight, width: self.view.frame.width, height: ZLInputTextViewController.collectionViewHeight)
  146. }
  147. }
  148. }
  149. extension ZLInputTextViewController: UICollectionViewDelegate, UICollectionViewDataSource {
  150. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  151. return ZLPhotoConfiguration.default().textStickerTextColors.count
  152. }
  153. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  154. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ZLDrawColorCell.zl_identifier(), for: indexPath) as! ZLDrawColorCell
  155. let c = ZLPhotoConfiguration.default().textStickerTextColors[indexPath.row]
  156. cell.color = c
  157. if c == self.currentTextColor {
  158. cell.bgWhiteView.layer.transform = CATransform3DMakeScale(1.2, 1.2, 1)
  159. } else {
  160. cell.bgWhiteView.layer.transform = CATransform3DIdentity
  161. }
  162. return cell
  163. }
  164. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  165. self.currentTextColor = ZLPhotoConfiguration.default().textStickerTextColors[indexPath.row]
  166. self.textView.textColor = self.currentTextColor
  167. collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
  168. collectionView.reloadData()
  169. }
  170. }
  171. extension ZLInputTextViewController: UITextViewDelegate {
  172. func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
  173. if text == "\n" {
  174. self.doneBtnClick()
  175. return false
  176. }
  177. return true
  178. }
  179. }