|
@@ -0,0 +1,630 @@
|
|
|
+//
|
|
|
+// TSPTPInputVC.swift
|
|
|
+// AIEmoji
|
|
|
+//
|
|
|
+// Created by 100Years on 2025/4/7.
|
|
|
+//
|
|
|
+
|
|
|
+//import IQKeyboardManagerSwift
|
|
|
+
|
|
|
+class TSPTPInputVC: TSBaseVC {
|
|
|
+
|
|
|
+ lazy var viewModel: TSPTPInputVM = {
|
|
|
+ let viewModel = TSPTPInputVM()
|
|
|
+ viewModel.isCanGennerateBlock = { [weak self] isCan in
|
|
|
+ guard let self = self else { return }
|
|
|
+ submitBtn.isEnabled = isCan
|
|
|
+ }
|
|
|
+ return viewModel
|
|
|
+ }()
|
|
|
+
|
|
|
+ lazy var photoPickerManager: TSPhotoPickerManager = {
|
|
|
+ let photoPickerManager = TSPhotoPickerManager(viewController: self)
|
|
|
+ return photoPickerManager
|
|
|
+ }()
|
|
|
+
|
|
|
+ //###################################### 导航栏 view ######################################
|
|
|
+
|
|
|
+ lazy var vipBtn: UIButton = {
|
|
|
+ let vipBtn = UIButton.createButton(image: UIImage(named: "nav_vip")) { [weak self] in
|
|
|
+ guard let self = self else { return }
|
|
|
+ TSPurchaseVC.show(target: self) {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return vipBtn
|
|
|
+ }()
|
|
|
+
|
|
|
+
|
|
|
+ lazy var navBarView: TSBaseNavContentBarView = {
|
|
|
+ let navBarView = TSBaseNavContentBarView()
|
|
|
+
|
|
|
+ let titleImageView = UIImageView.createImageView(imageName: "nav_title_pic",contentMode: .scaleToFill)
|
|
|
+ navBarView.barView.addSubview(titleImageView)
|
|
|
+ titleImageView.snp.makeConstraints { make in
|
|
|
+ make.centerY.equalToSuperview()
|
|
|
+ make.left.equalTo(16)
|
|
|
+ }
|
|
|
+
|
|
|
+ let keyboardBtn = UIButton.createButton(image: UIImage(named: "keyboard")) { [weak self] in
|
|
|
+ guard let self = self else { return }
|
|
|
+ kPresentModalVC(target: self, modelVC: TSWallpaperVC())
|
|
|
+ }
|
|
|
+ navBarView.barView.addSubview(keyboardBtn)
|
|
|
+ keyboardBtn.snp.makeConstraints { make in
|
|
|
+ make.centerY.equalToSuperview()
|
|
|
+ make.trailing.equalTo(-16)
|
|
|
+ make.width.height.equalTo(24)
|
|
|
+ }
|
|
|
+
|
|
|
+ navBarView.barView.addSubview(vipBtn)
|
|
|
+ vipBtn.snp.makeConstraints { make in
|
|
|
+ make.centerY.equalToSuperview()
|
|
|
+ make.trailing.equalTo(-60)
|
|
|
+ make.width.height.equalTo(24)
|
|
|
+ }
|
|
|
+
|
|
|
+ return navBarView
|
|
|
+ }()
|
|
|
+
|
|
|
+ //###################################### cusStackView ######################################
|
|
|
+ lazy var cusStackView: TSCustomStackView = {
|
|
|
+ let cusStackView = TSCustomStackView(axis: .vertical,spacing: 0)
|
|
|
+ cusStackView.scrollView.isScrollEnabled = false
|
|
|
+ return cusStackView
|
|
|
+ }()
|
|
|
+
|
|
|
+ //###################################### 入口 view ######################################
|
|
|
+
|
|
|
+ let bannerY:CGFloat = 17
|
|
|
+ let bannerW:CGFloat = 166*kDesignScale
|
|
|
+ let bannerH:CGFloat = 117*kDesignScale
|
|
|
+ lazy var textToPhotoBannerBtn: UIButton = {
|
|
|
+ let textToPhotoBannerBtn = UIButton.createButton(backgroundImage: UIImage(named: "textToPhoto_banner"))
|
|
|
+ textToPhotoBannerBtn.addTarget(self, action: #selector(clickTextToPhoto), for: .touchUpInside)
|
|
|
+ textToPhotoBannerBtn.frame = CGRect(x: 16, y: bannerY, width: bannerW, height: bannerH)
|
|
|
+
|
|
|
+ let label = UILabel.createLabel(text: "Text ➡️ Photo".localized,font: .font(name:.PoppinsBlackItalic,size: 16),textColor: .white)
|
|
|
+ textToPhotoBannerBtn.addSubview(label)
|
|
|
+ label.snp.makeConstraints { make in
|
|
|
+ make.top.equalTo(12)
|
|
|
+ make.leading.equalTo(8)
|
|
|
+ make.height.equalTo(24)
|
|
|
+ }
|
|
|
+
|
|
|
+ let button = UIButton.createButton(title:"Try Now".localized,backgroundColor:.white,font: .font(size: 11),titleColor: "#ED69AA".uiColor,corner: 9)
|
|
|
+ button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 6, bottom: 0, right: 6)
|
|
|
+ textToPhotoBannerBtn.addSubview(button)
|
|
|
+ button.snp.makeConstraints { make in
|
|
|
+ make.top.equalTo(44)
|
|
|
+ make.leading.equalTo(8)
|
|
|
+ make.height.equalTo(18)
|
|
|
+ }
|
|
|
+
|
|
|
+ return textToPhotoBannerBtn
|
|
|
+ }()
|
|
|
+
|
|
|
+ lazy var textToEmojiBannerBtn: UIButton = {
|
|
|
+ let textToEmojiBannerBtn = UIButton.createButton(backgroundImage: UIImage(named: "textToEmoji_banner"))
|
|
|
+ textToEmojiBannerBtn.addTarget(self, action: #selector(clickTextToEmoji), for: .touchUpInside)
|
|
|
+ let x = textToPhotoBannerBtn.x + textToPhotoBannerBtn.width + 11.0
|
|
|
+ textToEmojiBannerBtn.frame = CGRect(x: x, y: bannerY, width: bannerW, height: bannerH)
|
|
|
+
|
|
|
+ let color:UIColor = "#7855D6".uiColor
|
|
|
+ let label = UILabel.createLabel(text: "Text ➡️ Emoji".localized,font: .font(name:.PoppinsBlackItalic,size: 16),textColor: color)
|
|
|
+ textToEmojiBannerBtn.addSubview(label)
|
|
|
+ label.snp.makeConstraints { make in
|
|
|
+ make.top.equalTo(12)
|
|
|
+ make.leading.equalTo(8)
|
|
|
+ make.height.equalTo(24)
|
|
|
+ }
|
|
|
+
|
|
|
+ let button = UIButton.createButton(title:"Try Now".localized,backgroundColor:color,font: .font(size: 11),titleColor: "#D0D5FF".uiColor,corner: 9)
|
|
|
+ button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 6, bottom: 0, right: 6)
|
|
|
+ textToEmojiBannerBtn.addSubview(button)
|
|
|
+ button.snp.makeConstraints { make in
|
|
|
+ make.top.equalTo(44)
|
|
|
+ make.leading.equalTo(8)
|
|
|
+ make.height.equalTo(18)
|
|
|
+ }
|
|
|
+
|
|
|
+ return textToEmojiBannerBtn
|
|
|
+ }()
|
|
|
+
|
|
|
+
|
|
|
+ lazy var entranceView: UIView = {
|
|
|
+ let entranceView = UIView()
|
|
|
+ entranceView.addSubview(textToPhotoBannerBtn)
|
|
|
+ entranceView.addSubview(textToEmojiBannerBtn)
|
|
|
+ return entranceView
|
|
|
+ }()
|
|
|
+
|
|
|
+ //###################################### 上传图片 ######################################
|
|
|
+ lazy var uploadView: TSPTPUploadView = {
|
|
|
+ let uploadView = TSPTPUploadView()
|
|
|
+ uploadView.clickHandel = { [weak self] index in
|
|
|
+ guard let self = self else { return }
|
|
|
+
|
|
|
+ if index == 0 {//删除
|
|
|
+ viewModel.upLoadImage = nil
|
|
|
+ uploadView.upLoadImage = nil
|
|
|
+ }else{//添加
|
|
|
+
|
|
|
+ if UserDefaults.standard.string(forKey: "isFirstUploadImagePTP") == nil {
|
|
|
+ UserDefaults.standard.set("1", forKey: "isFirstUploadImagePTP")
|
|
|
+ UserDefaults.standard.synchronize()
|
|
|
+ presentModalHintVC()
|
|
|
+ }else {
|
|
|
+ pickSinglePhoto()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return uploadView
|
|
|
+ }()
|
|
|
+
|
|
|
+
|
|
|
+ func pickSinglePhoto() {
|
|
|
+ photoPickerManager.pickSinglePhoto { [weak self] image,phAsset in
|
|
|
+ guard let self = self else { return }
|
|
|
+
|
|
|
+ let maxSize = 10 * 1024 * 1024
|
|
|
+
|
|
|
+ if let image = image,let phAsset = phAsset {
|
|
|
+ // 方法2:异步获取详细大小(不阻塞主线程)
|
|
|
+ TSPhotoSizeHelper.getImageFileSizeAsync(asset: phAsset) {[weak self] size in
|
|
|
+ guard let self = self else { return }
|
|
|
+
|
|
|
+ let mbSize = Double(size) / (1024 * 1024)
|
|
|
+ print("精确大小: \(mbSize) MB,size = \(size)")
|
|
|
+ if size > maxSize {
|
|
|
+ TSToastShared.showToast(text: "Photo must be smaller than 10MB.".localized)
|
|
|
+ }else{
|
|
|
+ viewModel.upLoadImage = image
|
|
|
+ uploadView.upLoadImage = image
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else if let image = image {
|
|
|
+ if image.isLargerThan(byteSize: maxSize) {
|
|
|
+ TSToastShared.showToast(text: "Photo must be smaller than 10MB.".localized)
|
|
|
+ }else{
|
|
|
+ viewModel.upLoadImage = image
|
|
|
+ uploadView.upLoadImage = image
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //###################################### 选择风格 ######################################
|
|
|
+ lazy var selectStyleView: TSPTPSelectStyleView = {
|
|
|
+ let selectStyleView = TSPTPSelectStyleView()
|
|
|
+ selectStyleView.currentIndexPath = IndexPath(item: viewModel.selectedStyleIndex, section: 0)
|
|
|
+ selectStyleView.dataArray = viewModel.ptpStyleModels
|
|
|
+ selectStyleView.clickHandle = { [weak self] model in
|
|
|
+ guard let self = self else { return }
|
|
|
+ viewModel.selectedPTPStyleModel = model
|
|
|
+ updateVipView()
|
|
|
+ updateTextFiledView()
|
|
|
+ }
|
|
|
+ return selectStyleView
|
|
|
+ }()
|
|
|
+
|
|
|
+
|
|
|
+ //###################################### 输入框 ######################################
|
|
|
+ private let maxLength = 200 // 最大长度限制
|
|
|
+ lazy var customTextView: UITextField = {
|
|
|
+ let customTextView = UITextField()
|
|
|
+ customTextView.placeholder = "Please describe your photo".localized
|
|
|
+ customTextView.font = .font(size: 14)
|
|
|
+ customTextView.textColor = .white
|
|
|
+ customTextView.delegate = self
|
|
|
+ customTextView.returnKeyType = .send
|
|
|
+// customTextView.iq.distanceFromKeyboard = 0
|
|
|
+
|
|
|
+ customTextView.attributedPlaceholder = NSAttributedString(
|
|
|
+ string: "Please describe your photo".localized,
|
|
|
+ attributes: [
|
|
|
+ .foregroundColor: UIColor.white.withAlphaComponent(0.4),
|
|
|
+ .font: UIFont.font(size: 14)
|
|
|
+ ]
|
|
|
+ )
|
|
|
+
|
|
|
+ return customTextView
|
|
|
+ }()
|
|
|
+
|
|
|
+ lazy var clearBtn: UIButton = {
|
|
|
+ let clearBtn = UIButton.createButton(
|
|
|
+ image: UIImage(named: "clear_text")
|
|
|
+ )
|
|
|
+ { [weak self] in
|
|
|
+ guard let self = self else { return }
|
|
|
+ customTextView.text = ""
|
|
|
+ }
|
|
|
+ clearBtn.isHidden = true
|
|
|
+ return clearBtn
|
|
|
+ }()
|
|
|
+
|
|
|
+ var promptTextViewH:CGFloat = 84.0
|
|
|
+ lazy var promptTextView:UIView = {
|
|
|
+ let promptTextView = UIView()
|
|
|
+ //promptTextView.backgroundColor = "#333333".uiColor
|
|
|
+ promptTextView.clipsToBounds = true
|
|
|
+ let bgView = UIView()
|
|
|
+ bgView.backgroundColor = "#333333".uiColor
|
|
|
+ bgView.cornerRadius = 16.0
|
|
|
+ promptTextView.addSubview(bgView)
|
|
|
+ bgView.snp.makeConstraints { make in
|
|
|
+ make.edges.equalTo(UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16))
|
|
|
+ }
|
|
|
+
|
|
|
+ bgView.addSubview(customTextView)
|
|
|
+ bgView.addSubview(clearBtn)
|
|
|
+
|
|
|
+ customTextView.snp.makeConstraints { make in
|
|
|
+ make.top.bottom.equalTo(0)
|
|
|
+ make.leading.equalTo(12.0)
|
|
|
+ make.trailing.equalTo(-32)
|
|
|
+ }
|
|
|
+
|
|
|
+ clearBtn.snp.makeConstraints { make in
|
|
|
+ make.centerY.equalToSuperview()
|
|
|
+ make.width.height.equalTo(16.0)
|
|
|
+ make.trailing.equalTo(-12)
|
|
|
+ }
|
|
|
+
|
|
|
+ return promptTextView
|
|
|
+ }()
|
|
|
+ //###################################### 集合视图 ######################################
|
|
|
+ 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.sectionActionHandler = { [weak self] cellCp, indexPath in
|
|
|
+ guard let self = self else { return }
|
|
|
+ if let cmd = cellCp as? String, cmd == "delete" {
|
|
|
+ showCustomAlert(message: "Are you sure to delete".localized, deleteHandler: {
|
|
|
+ self.viewModel.removeAllHistoryList()
|
|
|
+ self.collectionComponent.clear()
|
|
|
+ self.collectionComponent.reloadView(with: self.viewModel.colDataArray)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ cp.itemDidSelectedHandler = { [weak self] (object, indexPath) in
|
|
|
+ guard let self = self else { return }
|
|
|
+ if indexPath.section == 0{
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if let sections = viewModel.colDataArray.safeObj(At: indexPath.section) as? TSGenmojiCoLSectionModel{
|
|
|
+ var dataModelArray:[TSGenmojiModel] = []
|
|
|
+ for itemModel in sections.items {
|
|
|
+ dataModelArray.append(itemModel.dataModel)
|
|
|
+ }
|
|
|
+
|
|
|
+ let browseVC = TSAIPhotoBrowseVC()
|
|
|
+ browseVC.dataModelArray = dataModelArray
|
|
|
+ browseVC.currentIndex = indexPath.item
|
|
|
+ kPresentModalVC(target: self, modelVC: browseVC,transitionStyle: .crossDissolve)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return cp
|
|
|
+ }()
|
|
|
+
|
|
|
+ //###################################### 按钮 ######################################
|
|
|
+ lazy var submitBtn: UIButton = {
|
|
|
+ let submitBtn = kCreateNormalSubmitBtn(title: getVipText()) { [weak self] in
|
|
|
+ guard let self = self else { return }
|
|
|
+ generateImage()
|
|
|
+ }
|
|
|
+ submitBtn.cornerRadius = 24.0
|
|
|
+ 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
|
|
|
+ make.edges.equalToSuperview()
|
|
|
+ }
|
|
|
+
|
|
|
+ collectionComponent.clear()
|
|
|
+ collectionComponent.reloadView(with:viewModel.colDataArray)
|
|
|
+
|
|
|
+ contentView.addSubview(submitBtn)
|
|
|
+ submitBtn.snp.makeConstraints { make in
|
|
|
+ make.bottom.equalTo(-k_Height_safeAreaInsetsBottom())
|
|
|
+ make.leading.equalTo(16)
|
|
|
+ make.trailing.equalTo(-16)
|
|
|
+ make.height.equalTo(48)
|
|
|
+ }
|
|
|
+
|
|
|
+ setUpCusStackView()
|
|
|
+
|
|
|
+ upDateCusStackViewH()
|
|
|
+ kDelayMainShort {
|
|
|
+ self.upDateCusStackViewH()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override func dealThings() {
|
|
|
+ NotificationCenter.default.addObserver(self, selector: #selector(vipInfoChanged), name: .kPurchaseDidChanged, object: nil)
|
|
|
+ updateVipView()
|
|
|
+
|
|
|
+// // 监听键盘事件
|
|
|
+// NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
|
|
|
+// NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
|
|
|
+ }
|
|
|
+//
|
|
|
+// override func viewWillAppear(_ animated: Bool) {
|
|
|
+// super.viewWillAppear(animated)
|
|
|
+// IQKeyboardManager.shared.isEnabled = false
|
|
|
+// }
|
|
|
+// override func viewWillDisappear(_ animated: Bool) {
|
|
|
+// super.viewWillDisappear(animated)
|
|
|
+//
|
|
|
+// IQKeyboardManager.shared.isEnabled = true
|
|
|
+// }
|
|
|
+}
|
|
|
+
|
|
|
+extension TSPTPInputVC {
|
|
|
+
|
|
|
+ var cusStackViewH:CGFloat{
|
|
|
+ get {
|
|
|
+ if cusStackView.viewH > 0{
|
|
|
+ return cusStackView.viewH
|
|
|
+ }
|
|
|
+ return 551+bannerH+bannerY
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func upDateCusStackViewH(){
|
|
|
+ self.collectionComponent.collectionView.contentInset = UIEdgeInsets(top: cusStackViewH, left: 0, bottom: collectionViewBtootm, right: 0)
|
|
|
+ cusStackView.snp.remakeConstraints { make in
|
|
|
+ make.top.equalTo(-cusStackViewH)
|
|
|
+ make.leading.trailing.equalTo(0)
|
|
|
+ make.height.equalTo(cusStackViewH)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func presentModalHintVC(){
|
|
|
+ let vc = TSPTPImageHintVC()
|
|
|
+ vc.clickUpImageHandle = { [weak self] in
|
|
|
+ guard let self = self else { return }
|
|
|
+ pickSinglePhoto()
|
|
|
+ }
|
|
|
+ kPresentModalVC(target: self, modelVC: vc,transitionStyle: .crossDissolve)
|
|
|
+ }
|
|
|
+ func setUpCusStackView(){
|
|
|
+
|
|
|
+ collectionComponent.collectionView.addSubview(cusStackView)
|
|
|
+
|
|
|
+ cusStackView.addSubviewToStack(entranceView)
|
|
|
+ entranceView.snp.makeConstraints { make in
|
|
|
+ make.height.equalTo(bannerH+bannerY)
|
|
|
+ make.width.equalTo(k_ScreenWidth)
|
|
|
+ }
|
|
|
+
|
|
|
+ let uploadPhotoTitleView = TSTitleView.creatTitleView(title: "Upload Photo".localized, subTitle: "(Size ≤ 10MB)".localized)
|
|
|
+ cusStackView.addSubviewToStack(uploadPhotoTitleView)
|
|
|
+ uploadPhotoTitleView.snp.makeConstraints { make in
|
|
|
+ make.height.equalTo(uploadPhotoTitleView.viewH)
|
|
|
+ make.width.equalTo(k_ScreenWidth)
|
|
|
+ }
|
|
|
+
|
|
|
+ let hintBtn = TSUIExpandedTouchButton()
|
|
|
+ hintBtn.setUpButton(image: UIImage(named: "ptp_hint")){ [weak self] in
|
|
|
+ guard let self = self else { return }
|
|
|
+ presentModalHintVC()
|
|
|
+ }
|
|
|
+ uploadPhotoTitleView.addSubview(hintBtn)
|
|
|
+ hintBtn.snp.makeConstraints { make in
|
|
|
+ make.centerY.equalToSuperview()
|
|
|
+ make.trailing.equalTo(-16)
|
|
|
+ make.width.height.equalTo(16)
|
|
|
+ }
|
|
|
+
|
|
|
+ cusStackView.addSubviewToStack(uploadView)
|
|
|
+ uploadView.snp.makeConstraints { make in
|
|
|
+ make.height.equalTo(uploadView.viewH)
|
|
|
+ make.width.equalTo(k_ScreenWidth)
|
|
|
+ }
|
|
|
+
|
|
|
+ let selectStyleTitleView = TSTitleView.creatTitleView(title: "Select Style".localized)
|
|
|
+ cusStackView.addSubviewToStack(selectStyleTitleView)
|
|
|
+ selectStyleTitleView.snp.makeConstraints { make in
|
|
|
+ make.height.equalTo(selectStyleTitleView.viewH)
|
|
|
+ make.width.equalTo(k_ScreenWidth)
|
|
|
+ }
|
|
|
+
|
|
|
+ cusStackView.addSubviewToStack(selectStyleView)
|
|
|
+ selectStyleView.snp.makeConstraints { make in
|
|
|
+ make.height.equalTo(selectStyleView.viewH)
|
|
|
+ make.width.equalTo(k_ScreenWidth)
|
|
|
+ }
|
|
|
+
|
|
|
+// cusStackView.addSubviewToStack(promptTextView)
|
|
|
+// promptTextView.snp.makeConstraints { make in
|
|
|
+// make.height.equalTo(promptTextViewH)
|
|
|
+// make.width.equalTo(k_ScreenWidth)
|
|
|
+// }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+extension TSPTPInputVC: UITextFieldDelegate{
|
|
|
+ // MARK: - UITextFieldDelegate
|
|
|
+ func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
|
|
+ if textField.returnKeyType == .send {
|
|
|
+ textField.resignFirstResponder() // 可选:收起键盘
|
|
|
+
|
|
|
+ // 触发发送逻辑
|
|
|
+
|
|
|
+
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
|
|
|
+ // 获取当前文本
|
|
|
+ guard let currentText = textField.text else {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ clearBtn.isHidden = currentText.count <= 0
|
|
|
+
|
|
|
+ // 计算新文本
|
|
|
+ let newText = (currentText as NSString).replacingCharacters(in: range, with: string)
|
|
|
+
|
|
|
+ // 如果新文本长度 > maxLength,截断并返回 false
|
|
|
+ if newText.count > maxLength {
|
|
|
+ textField.text = String(newText.prefix(maxLength))
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ func textFieldDidBeginEditing(_ textField: UITextField) {
|
|
|
+ print("输入框开始编辑 - 被点击了")
|
|
|
+ // 在这里可以通知控制器滚动到合适位置
|
|
|
+
|
|
|
+// DispatchQueue.main.async {
|
|
|
+// let rect = self.promptTextView.convert(self.promptTextView.bounds, to: self.collectionComponent.collectionView)
|
|
|
+// self.collectionComponent.collectionView.scrollRectToVisible(rect, animated: true)
|
|
|
+// }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+extension TSPTPInputVC {
|
|
|
+
|
|
|
+ @objc func vipInfoChanged() {
|
|
|
+ kExecuteOnMainThread {
|
|
|
+ self.updateVipView()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ func updateVipView() {
|
|
|
+ kExecuteOnMainThread {
|
|
|
+ self.vipBtn.isHidden = PurchaseManager.default.isVip
|
|
|
+
|
|
|
+ var showVip = kPurchaseDefault.generateVipShow(type: .picToPic)
|
|
|
+ if showVip == false {
|
|
|
+ showVip = self.viewModel.selectedPTPStyleModel?.isVip ?? false
|
|
|
+ }
|
|
|
+
|
|
|
+ kSetBtnVipIcon(btn: self.submitBtn, show: showVip)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func getVipText()->String{
|
|
|
+ return "Generate".localized
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ func updateTextFiledView () {
|
|
|
+// promptTextView.snp.updateConstraints { make in
|
|
|
+// make.height.equalTo(viewModel.selectedPTPStyleModel?.style == "No Style" ? promptTextViewH : 0 )
|
|
|
+// }
|
|
|
+ }
|
|
|
+}
|
|
|
+extension TSPTPInputVC {
|
|
|
+
|
|
|
+ @objc func clickTextToPhoto() {
|
|
|
+ kPushVC(target: self, modelVC: TSTextGeneralPictureVC())
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func clickTextToEmoji() {
|
|
|
+ kPushVC(target: self, modelVC: TSGenmojiVC())
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func clickView() {
|
|
|
+ view.endEditing(true)
|
|
|
+ }
|
|
|
+
|
|
|
+ func generateImage() {
|
|
|
+
|
|
|
+ var isVip = kPurchaseDefault.freeNumAvailable(type: .picToPic) == false
|
|
|
+ if viewModel.selectedPTPStyleModel?.isVip == true {
|
|
|
+ isVip = true
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断 vip
|
|
|
+ if kJudgeVip(externalBool: isVip, vc: self) { [weak self] in
|
|
|
+ guard let self = self else { return }
|
|
|
+ }{ return }
|
|
|
+
|
|
|
+
|
|
|
+ guard let selectedPTPStyleModel = viewModel.selectedPTPStyleModel else { return }
|
|
|
+ guard let upLoadImage = viewModel.upLoadImage else { return }
|
|
|
+
|
|
|
+ let gennerateVC = TSPTPGeneratorVC(prompt: viewModel.prompt,promptSort: selectedPTPStyleModel.imageText , imageUrl: "",upLoadImage: upLoadImage,style: selectedPTPStyleModel.style) { [weak self] model in
|
|
|
+ guard let self = self else { return }
|
|
|
+ if viewModel.saveModel(model:model) {
|
|
|
+ collectionComponent.clear()
|
|
|
+ collectionComponent.reloadView(with:viewModel.colDataArray)
|
|
|
+ }else{
|
|
|
+ collectionComponent.reloadData()
|
|
|
+ }
|
|
|
+
|
|
|
+ updateVipView()
|
|
|
+ }
|
|
|
+
|
|
|
+ kPresentModalVC(target: self, modelVC: gennerateVC,transitionStyle: .crossDissolve)
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+extension TSPTPInputVC {
|
|
|
+
|
|
|
+ @objc func keyboardWillShow(_ notification: Notification) {
|
|
|
+
|
|
|
+ guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
|
|
|
+ let animationDuration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+// dePrint("keyboardWillShow contentInset IQKeyboardManager=\(IQKeyboardManager.shared.isEnabled)")
|
|
|
+
|
|
|
+ let keyboardHeight = keyboardFrame.height
|
|
|
+ let contentInset = UIEdgeInsets(top:cusStackViewH, left: 0, bottom: keyboardHeight, right: 0)
|
|
|
+ dePrint("keyboardWillShow contentInset=\(contentInset)")
|
|
|
+// UIView.animate(withDuration: animationDuration) {
|
|
|
+ self.collectionComponent.collectionView.contentInset = contentInset
|
|
|
+ self.collectionComponent.collectionView.scrollIndicatorInsets = contentInset
|
|
|
+// }
|
|
|
+
|
|
|
+// kDelayMainShort {
|
|
|
+// self.collectionComponent.collectionView.scrollToLastItem(animated: false)
|
|
|
+// }
|
|
|
+ }
|
|
|
+
|
|
|
+ @objc func keyboardWillHide(_ notification: Notification) {
|
|
|
+ guard let animationDuration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval else {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ let contentInset = UIEdgeInsets(top: cusStackViewH, left: 0, bottom: collectionViewBtootm, right: 0)
|
|
|
+ dePrint("keyboardWillHide contentInset=\(contentInset)")
|
|
|
+// UIView.animate(withDuration: animationDuration) {
|
|
|
+ self.collectionComponent.collectionView.contentInset = contentInset
|
|
|
+ self.collectionComponent.collectionView.scrollIndicatorInsets = contentInset
|
|
|
+// }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|