|
@@ -5,9 +5,7 @@
|
|
|
// Created by 100Years on 2025/4/7.
|
|
|
//
|
|
|
|
|
|
-//import IQKeyboardManagerSwift
|
|
|
import PhotosUI
|
|
|
-import MXParallaxHeader
|
|
|
class TSPTPInputVC: TSBaseVC {
|
|
|
|
|
|
lazy var viewModel: TSPTPInputVM = {
|
|
@@ -61,7 +59,7 @@ class TSPTPInputVC: TSBaseVC {
|
|
|
//###################################### cusStackView ######################################
|
|
|
lazy var cusStackView: TSCustomStackView = {
|
|
|
let cusStackView = TSCustomStackView(axis: .vertical,spacing: 0)
|
|
|
- cusStackView.scrollView.isScrollEnabled = false
|
|
|
+ cusStackView.scrollView.isScrollEnabled = true
|
|
|
return cusStackView
|
|
|
}()
|
|
|
|
|
@@ -88,7 +86,6 @@ class TSPTPInputVC: TSBaseVC {
|
|
|
|
|
|
|
|
|
func pickSinglePhoto() {
|
|
|
-// photoPickerManager.pickSinglePhoto(maxBitSize: kUploadImageMaxBit10Size) { [weak self] image, errorString in
|
|
|
photoPickerManager.pickCustomSinglePhoto() { [weak self] image, errorString in
|
|
|
guard let self = self else { return }
|
|
|
if let errorString = errorString {
|
|
@@ -179,13 +176,14 @@ class TSPTPInputVC: TSBaseVC {
|
|
|
return promptTextView
|
|
|
}()
|
|
|
//###################################### 集合视图 ######################################
|
|
|
+ private var collectionViewObserver: CollectionViewObserver!
|
|
|
let collectionViewBtootm:CGFloat = 80
|
|
|
lazy var collectionComponent: TSCollectionViewComponent = {
|
|
|
let layout = UICollectionViewFlowLayout()
|
|
|
let cp = TSCollectionViewComponent(frame: CGRect.zero, layout: layout, attributes: [:])
|
|
|
cp.collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: collectionViewBtootm, right: 0)
|
|
|
-
|
|
|
-
|
|
|
+ cp.collectionView.isScrollEnabled = false
|
|
|
+
|
|
|
// 禁用自动 contentInset 调整
|
|
|
if #available(iOS 11.0, *) {
|
|
|
cp.collectionView.contentInsetAdjustmentBehavior = .never
|
|
@@ -233,25 +231,24 @@ class TSPTPInputVC: TSBaseVC {
|
|
|
submitBtn.isEnabled = false
|
|
|
return submitBtn
|
|
|
}()
|
|
|
+
|
|
|
+
|
|
|
override func createView() {
|
|
|
|
|
|
+ let tapGesture = UITapGestureRecognizer(target: self, action: #selector(clickView))
|
|
|
+ tapGesture.cancelsTouchesInView = false
|
|
|
+ view.addGestureRecognizer(tapGesture)
|
|
|
+
|
|
|
navBarContentView.addSubview(navBarView)
|
|
|
navBarView.snp.makeConstraints { make in
|
|
|
make.edges.equalToSuperview()
|
|
|
}
|
|
|
-
|
|
|
- contentView.addSubview(collectionComponent.collectionView)
|
|
|
- collectionComponent.collectionView.snp.makeConstraints { make in
|
|
|
+
|
|
|
+ contentView.addSubview(cusStackView)
|
|
|
+ cusStackView.snp.makeConstraints { make in
|
|
|
make.edges.equalToSuperview()
|
|
|
}
|
|
|
-
|
|
|
- let tapGesture = UITapGestureRecognizer(target: self, action: #selector(clickView))
|
|
|
- tapGesture.cancelsTouchesInView = false
|
|
|
- view.addGestureRecognizer(tapGesture)
|
|
|
|
|
|
- collectionComponent.clear()
|
|
|
- collectionComponent.reloadView(with:viewModel.colDataArray)
|
|
|
-
|
|
|
contentView.addSubview(submitBtn)
|
|
|
submitBtn.snp.makeConstraints { make in
|
|
|
make.bottom.equalTo(-16)
|
|
@@ -261,21 +258,15 @@ class TSPTPInputVC: TSBaseVC {
|
|
|
}
|
|
|
|
|
|
setUpCusStackView()
|
|
|
-
|
|
|
- setHeaderCusStackView()
|
|
|
- kDelayMainShort {
|
|
|
- self.setHeaderCusStackView()
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
- func setHeaderCusStackView(){
|
|
|
- self.collectionComponent.collectionView.parallaxHeader.view = self.cusStackView
|
|
|
- self.collectionComponent.collectionView.parallaxHeader.height = self.cusStackViewH
|
|
|
- self.collectionComponent.collectionView.parallaxHeader.mode = .bottom
|
|
|
- self.collectionComponent.collectionView.parallaxHeader.minimumHeight = 0
|
|
|
- }
|
|
|
+
|
|
|
|
|
|
override func dealThings() {
|
|
|
+
|
|
|
+ collectionComponent.clear()
|
|
|
+ collectionComponent.reloadView(with:viewModel.colDataArray)
|
|
|
+
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(vipInfoChanged), name: .kPurchaseDidChanged, object: nil)
|
|
|
updateVipView()
|
|
|
TSAIListHintBaseVC.userDefaultsKey = "isFirstUploadImagePTP"
|
|
@@ -284,48 +275,26 @@ class TSPTPInputVC: TSBaseVC {
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
|
|
|
|
|
|
- // collectionViewObserverHandle()
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-// private var collectionViewObserver: CollectionViewObserver!
|
|
|
-// func collectionViewObserverHandle(){
|
|
|
-// collectionViewObserver = CollectionViewObserver(collectionView: collectionComponent.collectionView)
|
|
|
-//
|
|
|
-// collectionViewObserver.onContentSizeChange = { size in
|
|
|
-// print("collectionViewObserver 内容大小变化: \(size)")
|
|
|
-// }
|
|
|
-//
|
|
|
-// collectionViewObserver.onContentInsetChange = { inset in
|
|
|
-// print("collectionViewObserver 内边距变化: \(inset)")
|
|
|
-// }
|
|
|
-//
|
|
|
-// collectionViewObserver.onContentOffsetChange = { offset in
|
|
|
-// print("collectionViewObserver 偏移量变化: \(offset)")
|
|
|
+// kDelayMainShort {
|
|
|
+// let contentSize = self.collectionComponent.collectionView.collectionViewLayout.collectionViewContentSize
|
|
|
+// self.collectionComponent.collectionView.snp.updateConstraints { make in
|
|
|
+// make.height.equalTo(contentSize.height)
|
|
|
+// }
|
|
|
// }
|
|
|
-//
|
|
|
-// }
|
|
|
-//
|
|
|
-//
|
|
|
-// func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
|
|
-// print("contentOffset 变化: \(scrollView.contentOffset)")
|
|
|
-// // 实时监听偏移量变化
|
|
|
-// }
|
|
|
-}
|
|
|
-
|
|
|
-extension TSPTPInputVC {
|
|
|
-
|
|
|
- var cusStackViewH:CGFloat{
|
|
|
- get {
|
|
|
- if cusStackView.viewH > 0{
|
|
|
- dePrint("collectionViewObserver cusStackView.viewH == \(cusStackView.viewH)")
|
|
|
- return cusStackView.viewH
|
|
|
+
|
|
|
+ collectionViewObserver = CollectionViewObserver(collectionView: collectionComponent.collectionView)
|
|
|
+ collectionViewObserver.onContentSizeChange = {[weak self] size in
|
|
|
+ guard let self = self else { return }
|
|
|
+ print("collectionViewObserver 内容大小变化: \(size)")
|
|
|
+ self.collectionComponent.collectionView.snp.updateConstraints { make in
|
|
|
+ make.height.equalTo(size.height)
|
|
|
}
|
|
|
- return 454
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+}
|
|
|
|
|
|
+extension TSPTPInputVC {
|
|
|
+
|
|
|
func presentModalHintVC(){
|
|
|
hintBaseVC = TSAIListHintBaseVC(config: .defaultConfig) { [weak self] image in
|
|
|
guard let self = self else { return }
|
|
@@ -380,15 +349,16 @@ extension TSPTPInputVC {
|
|
|
|
|
|
promptTextView.isHidden = !viewModel.selectedPTPStyleModel.input
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
- override func viewDidLayoutSubviews() {
|
|
|
- super.viewDidLayoutSubviews()
|
|
|
+ cusStackView.addSubviewToStack(collectionComponent.collectionView)
|
|
|
+ collectionComponent.collectionView.snp.makeConstraints { make in
|
|
|
+ make.height.equalTo(0)
|
|
|
+ make.width.equalTo(k_ScreenWidth)
|
|
|
+ }
|
|
|
+
|
|
|
+ cusStackView.addSpacing(length: collectionViewBtootm)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
extension TSPTPInputVC: UITextViewDelegate{
|
|
|
// 实现 UITextViewDelegate 协议方法,控制 return 键行为
|
|
|
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
|
@@ -473,75 +443,42 @@ extension TSPTPInputVC {
|
|
|
}
|
|
|
|
|
|
extension TSPTPInputVC {
|
|
|
- // MARK: - 键盘弹出时滚动到 TextView
|
|
|
- @objc func keyboardWillShow(_ notification: Notification) {
|
|
|
- guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
|
|
|
- let textView = customTextView
|
|
|
- guard let scrollView = collectionComponent.collectionView else { return }
|
|
|
- // 1. 计算键盘高度(减去安全区域)
|
|
|
- let keyboardHeight = keyboardFrame.height - view.safeAreaInsets.bottom
|
|
|
- dePrint("keyboardHeight = \(keyboardHeight )")
|
|
|
- // 2. 直接获取 TextView 在 ScrollView 中的位置
|
|
|
- let textViewFrame = scrollView.convert(textView.frame, from: textView.superview)
|
|
|
- dePrint("textViewFrame = \(textViewFrame)")
|
|
|
- // 3. 计算需要滚动的距离(TextView 底部 - (屏幕高度 - 键盘高度))
|
|
|
- var scrollDistance = textViewFrame.maxY - (scrollView.bounds.height - keyboardHeight)
|
|
|
- dePrint("scrollDistance = \(scrollDistance)")
|
|
|
- // 4. 如果需要滚动,调整 contentOffset
|
|
|
- var y = scrollDistance
|
|
|
- scrollView.setContentOffset(CGPoint(x: 0, y: y),animated: true)
|
|
|
- }
|
|
|
+ @objc func keyboardWillShow(_ notification: Notification) {
|
|
|
+ guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
|
|
|
+ let textView = customTextView
|
|
|
+// guard let scrollView = cusStackView.scrollView else { return }
|
|
|
+ let scrollView = cusStackView.scrollView
|
|
|
+ // 1. 计算键盘高度(减去安全区域)
|
|
|
+ let keyboardHeight = keyboardFrame.height - view.safeAreaInsets.bottom
|
|
|
+// dePrint("keyboardHeight = \(keyboardHeight )")
|
|
|
+ // 2. 直接获取 TextView 在 ScrollView 中的位置
|
|
|
+ let textViewFrame = scrollView.convert(textView.frame, from: textView.superview)
|
|
|
+// dePrint("textViewFrame = \(textViewFrame)")
|
|
|
+ // 3. 计算需要滚动的距离(TextView 底部 - (屏幕高度 - 键盘高度))
|
|
|
+ var scrollDistance = textViewFrame.maxY - (scrollView.bounds.height - keyboardHeight)
|
|
|
+// dePrint("scrollDistance = \(scrollDistance)")
|
|
|
+ // 4. 如果需要滚动,调整 contentOffset
|
|
|
+ var y = scrollDistance
|
|
|
+ scrollView.setContentOffset(CGPoint(x: 0, y: y),animated: true)
|
|
|
+ }
|
|
|
|
|
|
// MARK: - 键盘隐藏时恢复
|
|
|
@objc private func keyboardWillHide(_ notification: Notification) {
|
|
|
- self.collectionComponent.collectionView.contentOffset = CGPoint(x: 0, y: -cusStackViewH)
|
|
|
+ cusStackView.scrollView.contentOffset = CGPoint(x: 0, y: 0)
|
|
|
}
|
|
|
}
|
|
|
extension TSPTPInputVC {
|
|
|
|
|
|
func updateTextFiledView () {
|
|
|
if viewModel.selectedPTPStyleModel.input {
|
|
|
- cusStackView.showWithDrawerAnimation(view: promptTextView, viewHeight: promptTextViewH) { [weak self] in
|
|
|
- self?.updateViewCusStackViewH()
|
|
|
- }
|
|
|
+ promptTextView.isHidden = false
|
|
|
}else{
|
|
|
- cusStackView.hideWithDrawerAnimation(view: promptTextView, viewHeight: promptTextViewH) { [weak self] in
|
|
|
- self?.updateViewCusStackViewH()
|
|
|
- }
|
|
|
+ promptTextView.isHidden = true
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- func updateViewCusStackViewH() {
|
|
|
-
|
|
|
- self.collectionComponent.collectionView.parallaxHeader.updateHeaderHeight(height: self.cusStackViewH)
|
|
|
|
|
|
-// self.collectionComponent.collectionView.parallaxHeader.height = self.cusStackViewH
|
|
|
-//
|
|
|
-// let newHeight = self.cusStackViewH
|
|
|
-// let headerView = self.collectionComponent.collectionView.parallaxHeader.view!
|
|
|
-// for constraint in headerView.constraints {
|
|
|
-// if constraint.firstAttribute == .height &&
|
|
|
-// constraint.firstItem as? UIView == headerView &&
|
|
|
-// constraint.secondItem == nil {
|
|
|
-// constraint.constant = newHeight
|
|
|
-// break
|
|
|
-// }
|
|
|
-// }
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-extension MXParallaxHeader {
|
|
|
- func updateHeaderHeight(height:CGFloat){
|
|
|
- self.height = height
|
|
|
- let headerView = view!
|
|
|
- for constraint in headerView.constraints {
|
|
|
- if constraint.firstAttribute == .height &&
|
|
|
- constraint.firstItem as? UIView == headerView &&
|
|
|
- constraint.secondItem == nil {
|
|
|
- constraint.constant = height
|
|
|
- break
|
|
|
- }
|
|
|
+ UIView.animate(withDuration: 0.3) {
|
|
|
+ self.cusStackView.layoutIfNeeded()
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|