Browse Source

3.6.7(4)修复bug

100Years 2 tuần trước cách đây
mục cha
commit
92f96f1653
29 tập tin đã thay đổi với 232 bổ sung131 xóa
  1. 2 2
      AIEmoji.xcodeproj/project.pbxproj
  2. BIN
      AIEmoji/Assets.xcassets/PTP/ptp_selected_check.imageset/ptp_selected_check@2x.png
  3. BIN
      AIEmoji/Assets.xcassets/PTP/ptp_selected_check.imageset/ptp_selected_check@3x.png
  4. BIN
      AIEmoji/Assets.xcassets/PTP/style/ptp_style_MonaLisa.imageset/ptp_style_MonaLisa@2x.png
  5. BIN
      AIEmoji/Assets.xcassets/PTP/style/ptp_style_MonaLisa.imageset/ptp_style_MonaLisa@3x.png
  6. 2 4
      AIEmoji/Business/LaunchVC/TSBootPageVC.swift
  7. 1 0
      AIEmoji/Business/TSAILIstVC/TSAIExpandImageVC/View/TSAIExpandChangeView.swift
  8. 1 1
      AIEmoji/Business/TSAILIstVC/TSAIPhotoGeneratorBaseVC/TSAIListPhotoGeneratorBaseVC.swift
  9. 19 11
      AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/TSGennertatorSelectStyleVC.swift
  10. 1 1
      AIEmoji/Business/TSPTPGeneratorVC/TSPTPGeneratorVC/TSPTPGeneratorVC.swift
  11. 57 14
      AIEmoji/Business/TSPurchaseMembershipVC/TSPurchaseVC.swift
  12. 16 24
      AIEmoji/Business/TSSetingVC/SetingVC/View/SettingPurchaseTopView.swift
  13. 0 3
      AIEmoji/Business/TSSetingVC/SetingVC/View/TSSettingListView.swift
  14. 1 1
      AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/TSTTPInputVC.swift
  15. 1 3
      AIEmoji/Business/VIewTool/TSGeneratorloadingView/TSGeneratoringAnimationView.swift
  16. 7 5
      AIEmoji/Common/NetworkManager/TSNetWork/TSNetworkManager.swift
  17. 25 21
      AIEmoji/Common/Purchase/TSPurchaseManager.swift
  18. 39 28
      AIEmoji/Common/View/TSImageComparisonView.swift
  19. 1 1
      AIEmoji/Common/View/TYCycleImageComparisonView.swift
  20. 2 0
      AIEmoji/Info.plist
  21. 6 1
      AIEmoji/de.lproj/Localizable.strings
  22. 6 1
      AIEmoji/en.lproj/Localizable.strings
  23. 6 1
      AIEmoji/es.lproj/Localizable.strings
  24. 6 1
      AIEmoji/ja.lproj/Localizable.strings
  25. 7 2
      AIEmoji/ko.lproj/Localizable.strings
  26. 7 2
      AIEmoji/pt-BR.lproj/Localizable.strings
  27. 7 2
      AIEmoji/pt-PT.lproj/Localizable.strings
  28. 6 1
      AIEmoji/zh-Hans.lproj/Localizable.strings
  29. 6 1
      AIEmoji/zh-Hant.lproj/Localizable.strings

+ 2 - 2
AIEmoji.xcodeproj/project.pbxproj

@@ -2512,7 +2512,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 2;
+				CURRENT_PROJECT_VERSION = 4;
 				DEVELOPMENT_TEAM = 65UD255J84;
 				ENABLE_USER_SCRIPT_SANDBOXING = NO;
 				GENERATE_INFOPLIST_FILE = YES;
@@ -2551,7 +2551,7 @@
 				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 2;
+				CURRENT_PROJECT_VERSION = 4;
 				DEVELOPMENT_TEAM = 65UD255J84;
 				ENABLE_USER_SCRIPT_SANDBOXING = NO;
 				GENERATE_INFOPLIST_FILE = YES;

BIN
AIEmoji/Assets.xcassets/PTP/ptp_selected_check.imageset/ptp_selected_check@2x.png


BIN
AIEmoji/Assets.xcassets/PTP/ptp_selected_check.imageset/ptp_selected_check@3x.png


BIN
AIEmoji/Assets.xcassets/PTP/style/ptp_style_MonaLisa.imageset/ptp_style_MonaLisa@2x.png


BIN
AIEmoji/Assets.xcassets/PTP/style/ptp_style_MonaLisa.imageset/ptp_style_MonaLisa@3x.png


+ 2 - 4
AIEmoji/Business/LaunchVC/TSBootPageVC.swift

@@ -142,10 +142,8 @@ class TSBootPageVC: TSBaseVC {
 //        deepseek.isHidden = !(index == pageIndex)//第二页
         
         if index == 1{
-            kDelayMainShort {
-                self.comparisonView0.stopAnimation()
-                self.comparisonView1.startAnimation(direction: .rightToLeft)
-            }
+            self.comparisonView0.stopAnimation()
+            self.comparisonView1.startAnimation(direction: .rightToLeft)
         }
   
         

+ 1 - 0
AIEmoji/Business/TSAILIstVC/TSAIExpandImageVC/View/TSAIExpandChangeView.swift

@@ -67,6 +67,7 @@ class TSAIExpandChangeView: TSBaseView {
         let bgView = UIView()
         bgView.addGestureRecognizer(UITapGestureRecognizer(target: self, action:#selector(clickAddBgView)))
         bgView.addSubview(upLoadView)
+        bgView.isHidden = true
         upLoadView.snp.makeConstraints { make in
             make.center.equalToSuperview()
         }

+ 1 - 1
AIEmoji/Business/TSAILIstVC/TSAIPhotoGeneratorBaseVC/TSAIListPhotoGeneratorBaseVC.swift

@@ -55,7 +55,7 @@ class TSAIListPhotoGeneratorBaseVC: TSAIPhotoGeneratorBaseVC {
     lazy var generateInView : TSGeneratorView = {
         let generateInView = TSGeneratorView()
         generateInView.isUploadImage = false
-        generateInView.animationView.setText(time: String(format: "~ %d min".localized, 2), info: "It is definitely worth your wait. Just watch it".localized)
+        generateInView.animationView.setText(time: String(format: "~ %d min".localized, 2), info: "Lots of people are creating images right now, so this might take a bit.".localized)
         generateInView.clickErrorBlock = { [weak self] style in
             guard let self = self else { return }
             

+ 19 - 11
AIEmoji/Business/TSPTPGeneratorVC/TSGennertatorSelectStyleVC/TSGennertatorSelectStyleVC.swift

@@ -165,7 +165,7 @@ class TSGennertatorSelectStyleCell: TSBaseCollectionCell {
     override var isSelected: Bool{
         didSet{
             boardImageView.isHidden = isSelected ? false : true
-            checkImageView.isHidden = style == .ptp ? boardImageView.isHidden : true
+            checkView.isHidden = boardImageView.isHidden
             textLabel.textColor = isSelected ? .themeColor : .white.withAlphaComponent(0.8)
         }
     }
@@ -255,13 +255,21 @@ class TSGennertatorSelectStyleCell: TSBaseCollectionCell {
         return imageView
     }()
     
-    lazy var checkImageView: UIImageView = {
+    lazy var checkView: UIView = {
+        
+        let bgView = UIView.creatColor(color: .black.withAlphaComponent(0.4))
+        
         let checkImageView = UIImageView.createImageView(imageName: "ptp_selected_check")
-        checkImageView.isHidden = true
-        return checkImageView
+        bgView.addSubview(checkImageView)
+        checkImageView.snp.makeConstraints{ make in
+            make.center.equalToSuperview()
+            make.width.height.equalTo(32)
+        }
+        
+        bgView.isHidden = true
+        return bgView
     }()
     
-    
     lazy var hotImageView: UIImageView = {
         let hotImageView = UIImageView.createImageView(imageName: "ptp_style_hot")
         hotImageView.isHidden = true
@@ -290,6 +298,11 @@ class TSGennertatorSelectStyleCell: TSBaseCollectionCell {
             make.width.height.equalTo(w-8)
         }
         
+        imageView.addSubview(checkView)
+        checkView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
         imageView.addSubview(hotImageView)
         hotImageView.snp.makeConstraints { make in
             make.leading.equalTo(0.0)
@@ -297,12 +310,7 @@ class TSGennertatorSelectStyleCell: TSBaseCollectionCell {
             make.width.height.equalTo(36)
         }
         
-        imageView.addSubview(checkImageView)
-        checkImageView.snp.makeConstraints { make in
-            make.trailing.equalTo(-1.0)
-            make.top.equalTo(1.0)
-            make.width.height.equalTo(20)
-        }
+
         
         
         bgContentView.addSubview(textLabel)

+ 1 - 1
AIEmoji/Business/TSPTPGeneratorVC/TSPTPGeneratorVC/TSPTPGeneratorVC.swift

@@ -35,7 +35,7 @@ class TSPTPGeneratorVC: TSAIPhotoGeneratorBaseVC {
     lazy var generateInView : TSGeneratorView = {
         let generateInView = TSGeneratorView()
         if generateStyleModel.advance {
-            generateInView.animationView.setText(time: String(format: "~ %d min".localized, 2), info: "It is definitely worth your wait. Just watch it".localized)
+            generateInView.animationView.setText(time: String(format: "~ %d min".localized, 2), info: "Lots of people are creating images right now, so this might take a bit.".localized)
         }else{
             generateInView.animationView.setText(time: String(format: "~ %d seconds".localized, 20), info: "")
         }

+ 57 - 14
AIEmoji/Business/TSPurchaseMembershipVC/TSPurchaseVC.swift

@@ -167,7 +167,12 @@ class TSPurchaseVC: TSBaseVC {
                     TSToastShared.showLoading(text: "Purchasing now".localized,containerView: self.view)
                 case .paySuccess:
                     TSToastShared.hideLoading()
-                    let loadingText = manager.isVip ? "Congratulation you have become VIP".localized : "Finish".localized
+                 
+                    var loadingText = "Finish".localized
+                    if manager.isVip {
+                        loadingText = manager.vipType == .year ? "Congratulations on being VIP of the Year!".localized : "Congratulation you have become VIP".localized
+                    }
+                    
                     TSToastShared.showToast(text:loadingText)
                     if manager.isVip {
                         DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
@@ -288,17 +293,20 @@ struct PurchaseView :View {
     
     var body: some View {
         
+
         let vipType = PurchaseManager.default.vipType
         
         VStack {
             Spacer()
-
+#if DEBUG
+//    let vipType = PremiumPeriod.week
+#endif
             VStack {
                 let text = vipType == .none ? "Get PRO Access".localized : "Super Offer for Yearly Pro".localized
                 Text(text)
-                    .font(.font(name: .PoppinsBlackItalic,size: 26))
+                    .font(.font(name: .PoppinsBoldItalic,size: 26))
                     .foregroundColor(UIColor.white.color)
-                    .frame(height: 26*kDesignScale)
+                    .frame(width: k_ScreenWidth - 32, alignment: .center)
                 
                 if vipType == .none {
                     Spacer().frame(height: 12)
@@ -309,7 +317,7 @@ struct PurchaseView :View {
                         Text("Generation")
                             .foregroundColor(UIColor.white.color)
                         
-                    }.font(.font(name: .PoppinsBlackItalic,size: 26))
+                    }.font(.font(name: .PoppinsBoldItalic,size: 26))
                         .frame(height: 26*kDesignScale)
                 }
             }
@@ -318,19 +326,22 @@ struct PurchaseView :View {
             
             VStack(spacing: 12) {
                 
-                ZStack(alignment: .topTrailing) {
-                    PurchaseItemView(title: "One Year".localized, type: .year, selectedType: $viewModel.selectedType).onTapGesture {
-                        viewModel.selectedType = .year
-                        //playVibration()
-                    }
-                    TSVipRecView()
-                        .offset(x:-30,y:-14)
-                }
-
                 if vipType == .none {
+                    ZStack(alignment: .topTrailing) {
+                        PurchaseItemView(title: "One Year".localized, type: .year, selectedType: $viewModel.selectedType).onTapGesture {
+                            viewModel.selectedType = .year
+                        }
+                        TSVipRecView()
+                            .offset(x:-30,y:-14)
+                    }
+                    
                     PurchaseItemView(title: "One Week".localized, type: .week, selectedType: $viewModel.selectedType).onTapGesture {
                         viewModel.selectedType = .week
                     }
+                }else{
+                    PurchaseItemTypeOneView(title: "One Year".localized, type: .year, selectedType: $viewModel.selectedType).onTapGesture {
+                        viewModel.selectedType = .year
+                    }
                 }
                 
                 Spacer().frame(height: 4)
@@ -436,6 +447,38 @@ struct PurchaseItemView: View {
     }
 }
 
+struct PurchaseItemTypeOneView: View {
+    var title: String
+    var type: PremiumPeriod
+    @Binding var selectedType: PremiumPeriod
+
+    var body: some View {
+        ZStack {
+            Color.white.opacity(0.1)
+            HStack {
+                //左边加个
+                VStack(alignment: .leading, spacing: 8) {
+                    Text(title).font(.font(size: 14,weight: .medium)).foregroundColor(UIColor.white.color)
+                    Text(String(format:"Only %@ per day".localized,"\(PurchaseManager.default.averageDay(for:type) ?? "--")"))
+                        .font(.font(size: 12,weight: .medium))
+                        . foregroundColor(UIColor.white.color).opacity(0.7)
+                }
+
+                Spacer()
+                
+                Text(PurchaseManager.default.price(for: type) ?? "--").font(.font(size: 18,weight: .medium)).foregroundColor(UIColor.mainText.color)
+
+            }.padding(.horizontal)
+        }
+        .frame(height: 74) // 设置高度
+        .cornerRadius(16.0) // 圆角
+        .overlay(
+            RoundedRectangle(cornerRadius: 16)
+                .stroke(Color.hex("#FECB34"), lineWidth: type == selectedType ? 1 : 0) // 边框
+        )
+    }
+}
+
 //推荐选择view
 struct TSVipRecView: View {
     var body: some View {

+ 16 - 24
AIEmoji/Business/TSSetingVC/SetingVC/View/SettingPurchaseTopView.swift

@@ -9,16 +9,21 @@ struct SettingPurchaseTopView: View {
     var eventPublisher: ListEventPublisher
     @Binding var vipType: PremiumPeriod
     var body: some View {
+#if DEBUG
+//        let vipType = PremiumPeriod.week
+#endif
         let topW = k_ScreenWidth-32
         let topH = 134.0    //kGetScaleHeight(originalSize: CGSize(width: 343, height: 130), width: topW)
-        let updateText = vipType == .week ? "Upgrade Yearly Pro".localized : "Update to PRO".localized
+        let updateText = vipType == .week ? "Upgrade Yearly Pro".localized : "Upgrade to PRO".localized
+        let timeString = "Due Date:".localized + " \(PurchaseManager.default.expiredDateString)"
+        let timeText = vipType == .week ? timeString : "Limited Time Discount".localized
         ZStack {
             Image(.settingVipBj).resizable().cornerRadius(16.0)
             if vipType == .year {
                 VStack(alignment: .center) {
                     customGradientText(text: "\(kAppName) pro", font: .font(name: .PoppinsBoldItalic,size: 36))
-                    Spacer().frame(height: 16)
-                    Text("Due Date:".localized + " \(PurchaseManager.default.expiredDateString)")
+                    Spacer().frame(height: 20)//16
+                    Text(timeString)
                         .foregroundColor(.white.opacity(0.6))
                         .font(.font(size: 14,weight: .medium))
                         .frame(height: 14)
@@ -27,9 +32,9 @@ struct SettingPurchaseTopView: View {
                 VStack(){
                     HStack {
                         VStack(alignment: .leading,spacing: 8) {
-                            customGradientText(text: updateText, font: .font(name: .PoppinsBoldItalic,size: 22),colors: [.white]).frame(height: 26)
+                            customGradientText(text: updateText, font: .font(name: .PoppinsBoldItalic,size: 22),colors: [.white]).frame(width: 230.0*kDesignScale,height: 26,alignment: .leading)
                             HStack {
-                                Text("Limited Time Discount".localized)
+                                Text(timeText)
                                     .font(.font(size: 14))
                                     .frame(height: 14)
                                     .foregroundColor(UIColor.white.withAlphaComponent(0.6).color)
@@ -40,12 +45,14 @@ struct SettingPurchaseTopView: View {
                         Spacer()
                  
                         Text("Save-Vip".localized + " 80%")
+                            .lineLimit(1)
                             .foregroundColor(Color.white)
                             .font(.font(size: 12,weight: .semibold))
-                            .frame(width: 82, height: 28, alignment: .center)
+                            .frame(width: 82*kDesignScale, height: 28, alignment: .center)
                             .foregroundColor("#010101".uiColor.color)
                             .background(Color.hex("#E83E3E"))
                             .cornerRadius(4.0)
+                            .minimumScaleFactor(0.5)
                             .rotationEffect(.degrees(15)) // 向右旋转45度
                     }
                     
@@ -66,33 +73,18 @@ struct SettingPurchaseTopView: View {
 
         }.frame(width: topW, height: topH)
     }
-    
-    // 定义一个返回 View 的方法
-    func customText(text:String,fontName:FontName,color:Color) -> some View {
-        let gorgeousColor = color //UIColor.themeColor.color
-        return Text(text)
-            .font(.font(name: fontName,size: 36))
-//            .gradientForeground(
-//                colors: [gorgeousColor,gorgeousColor],
-//                startPoint: UnitPoint.leading,
-//                endPoint: UnitPoint.trailing
-//            )
-//            .shadow(color: gorgeousColor.opacity(0.7), radius: 6, x: 0, y: 0)
-            .foregroundColor(gorgeousColor)
-            .frame(height: 20)
-//            .minimumScaleFactor(0.5) // 最小缩放比例(0.5表示最小可缩放到初始大小的50%)
-    }
-    
+
     func customGradientText(text:String,font:Font,colors:[Color] = [.hex("#FA794F"),.hex("#F8C32A"),.hex("#FEFBF4")]) -> some View {
         return Text(text)
+            .lineLimit(1)
             .font(font)
             .gradientForeground(
                 colors: colors,
                 startPoint: UnitPoint.leading,
                 endPoint: UnitPoint.trailing
             )
+            .minimumScaleFactor(0.5)
 //            .shadow(color: gorgeousColor.opacity(0.7), radius: 6, x: 0, y: 0)
-            .frame(height: 20)
     }
     
     // 定义一个返回 View 的方法

+ 0 - 3
AIEmoji/Business/TSSetingVC/SetingVC/View/TSSettingListView.swift

@@ -16,9 +16,6 @@ struct TSSettingListView: View {
                 Spacer().frame(height: 16)
         
                 SettingPurchaseTopView(eventPublisher: publisher, vipType: $viewModel.vipType)
-                    .onTapGesture {
-                        publisher.enterPurchasePublisher.send(true)
-                    }
                 
                 ForEach(viewModel.settingTypes, id:\.self) { type in
                     Spacer().frame(height: 16)

+ 1 - 1
AIEmoji/Business/TSTextGeneralPictureVC/TSTTPInputVC/TSTTPInputVC.swift

@@ -78,7 +78,7 @@ class TSTTPInputVC: TSBaseVC {
             guard let self = self else { return }
             let vc = TSChatViewController()
             vc.viewModel.uiStyle = .perfectHint
-            vc.inputText = promptTextView.text
+//            vc.inputText = promptTextView.text
             
             vc.textBlock = { [weak self] text ,bool in
                 guard let self = self else { return }

+ 1 - 3
AIEmoji/Business/VIewTool/TSGeneratorloadingView/TSGeneratoringAnimationView.swift

@@ -12,9 +12,7 @@ class TSGeneratoringAnimationView : TSBaseView {
     
     var isShowBackGeneration:Bool = false {
         didSet{
-            UIView.animate(withDuration: 0.3) {
-                self.backgroundGenerateBtn.isHidden = !self.isShowBackGeneration
-            }
+            self.backgroundGenerateBtn.isHidden = !self.isShowBackGeneration
         }
     }
     

+ 7 - 5
AIEmoji/Common/NetworkManager/TSNetWork/TSNetworkManager.swift

@@ -26,11 +26,13 @@ class TSNetworkManager {
     }
     
     lazy var afSession: Session = {
-        let configuration = URLSessionConfiguration.af.default
-        configuration.timeoutIntervalForRequest = 15  // 请求超时时间(秒)
-        configuration.timeoutIntervalForResource = 30 // 资源超时时间(秒)
-        let session = Session(configuration: configuration)
-        return session
+//        let configuration = URLSessionConfiguration.af.default
+//        configuration.timeoutIntervalForRequest = 15  // 请求超时时间(秒)
+//        configuration.timeoutIntervalForResource = 30 // 资源超时时间(秒)
+//        let session = Session(configuration: configuration)
+//        return session
+        
+        return AF
     }()
     lazy var encoder: JSONEncoding = {
         return JSONEncoding(options: .withoutEscapingSlashes)// 关键:禁用斜杠转义

+ 25 - 21
AIEmoji/Common/Purchase/TSPurchaseManager.swift

@@ -208,25 +208,7 @@ extension PurchaseManager {
         return formatter.string(from: product.price)
     }
 
-//    // 平局每周的金额,对于年来说
-//    public func averageWeeklyForYear() -> String? {
-//        guard let product = product(for: .year) else {
-//            return nil
-//        }
-//        
-//        let price = product.price.doubleValue
-//        let calculatePrice = price / 52.0
-//        let originStr = String(format: "%.2f", calculatePrice)
-//        let originPrice = NSDecimalNumber(string: originStr, locale: product.priceLocale)
-//        
-//        let formatter = NumberFormatter()
-//        formatter.formatterBehavior = NumberFormatter.Behavior.behavior10_4
-//        formatter.numberStyle = .currency
-//        formatter.locale = product.priceLocale
-//        return formatter.string(from: originPrice)
-//    }
-    
-    // 平局每周的金额,对于年来说
+    // 平局每周的金额
     public func averageWeekly(for period: PremiumPeriod) -> String? {
         guard let product = product(for: period) else {
             return nil
@@ -235,9 +217,9 @@ extension PurchaseManager {
         var originPrice = product.price
         let price = originPrice.doubleValue
         if period == .year {
-            originPrice = NSDecimalNumber(string: String(format: "%.2f", price / 52.0), locale: product.priceLocale)
+            originPrice = NSDecimalNumber(string: String(format: "%.2f", price / 52.0), locale: nil)
         }else if period == .month {
-            originPrice = NSDecimalNumber(string: String(format: "%.2f", price / 4.0), locale: product.priceLocale)
+            originPrice = NSDecimalNumber(string: String(format: "%.2f", price / 4.0), locale: nil)
         }
         
         let formatter = NumberFormatter()
@@ -248,6 +230,28 @@ extension PurchaseManager {
   
     }
     
+
+    // 平均每天的金额
+    public func averageDay(for period: PremiumPeriod) -> String? {
+        guard let product = product(for: period) else {
+            return nil
+        }
+        
+        var originPrice = product.price
+        let price = originPrice.doubleValue
+        if period == .year {
+            originPrice = NSDecimalNumber(string: String(format: "%.2f", price / 365.0), locale: nil)
+        }else if period == .month {
+            originPrice = NSDecimalNumber(string: String(format: "%.2f", price / 30.0), locale: nil)
+        }
+        
+        let formatter = NumberFormatter()
+        formatter.formatterBehavior = NumberFormatter.Behavior.behavior10_4
+        formatter.numberStyle = .currency
+        formatter.locale = product.priceLocale
+        return formatter.string(from: originPrice)
+  
+    }
 //    public func originalPrice(for period: PremiumPeriod) -> String? {
 //        guard let product = product(for: period) else {
 //            return nil

+ 39 - 28
AIEmoji/Common/View/TSImageComparisonView.swift

@@ -6,6 +6,7 @@
 //
 
 import UIKit
+
 class TSImageComparisonView: UIView {
     // MARK: - 属性
     private let oldImageView = UIImageView()
@@ -16,13 +17,14 @@ class TSImageComparisonView: UIView {
     var duration: TimeInterval = 3.0
     
     var isRunloop:Bool = false //是否循环播放,从右到左,在从左到右
+    private var reverse:Bool = false //动画反转(进度反转)
     
     // 动画方向枚举
      enum AnimationDirection {
          case leftToRight  // 从左到右(默认)
          case rightToLeft  // 从右到左
      }
-    
+    private var maskLayer = CAShapeLayer()
     var direction:AnimationDirection = .leftToRight
     // MARK: - 初始化
     override init(frame: CGRect) {
@@ -68,7 +70,7 @@ class TSImageComparisonView: UIView {
         reset()
     }
     
-    func startAnimation(duration: TimeInterval = 2.0,direction:AnimationDirection = .leftToRight) {
+    func startAnimation(duration: TimeInterval = 1.5,direction:AnimationDirection = .leftToRight) {
 
         reset()
         
@@ -76,6 +78,11 @@ class TSImageComparisonView: UIView {
         self.direction = direction
         lineView.alpha = 1
         
+        startAnimationTime()
+    }
+    
+    
+    private func startAnimationTime(){
         // 启动动画
         animationStartTime = CACurrentMediaTime()
         displayLink = CADisplayLink(target: self, selector: #selector(updateAnimation))
@@ -88,22 +95,34 @@ class TSImageComparisonView: UIView {
     }
     
     func animationComplete() {
-        
-        reset()
-        self.newImageView.layer.mask = nil
-        
         if isRunloop {
-            kDelayOnMainThread(0.3) {
-                self.startAnimation(direction: self.direction)
+            stopAnimation()
+            lineView.alpha = 0.0
+            DispatchQueue.main.asyncAfter(deadline: .now()+0.2){
+                self.reverse = !self.reverse
+                self.lineView.alpha = 1.0
+                self.startAnimationTime()
             }
+        } else {
+            reset()
         }
     }
- 
     func reset() {
         stopAnimation()
         lineView.alpha = 0
         lineView.frame.origin.x = 0
-        
+        self.newImageView.layer.mask = nil
+        reverse = false
+    }
+    
+    func resetNewImageView(){
+        maskLayer.path = UIBezierPath(rect: CGRect(
+            x: 0,
+            y: 0,
+            width: x,
+            height: bounds.height
+        )).cgPath
+        newImageView.layer.mask = maskLayer
     }
     
     // MARK: - 动画更新
@@ -112,7 +131,11 @@ class TSImageComparisonView: UIView {
         
         let elapsed = CACurrentMediaTime() - animationStartTime
         let duration = self.duration
-        let progress = min(CGFloat(elapsed / duration), 1.0)
+        var progress = min(CGFloat(elapsed / duration), 1.0)
+        
+        if reverse { //反转进度
+            progress = 1.0 - progress
+        }
         
         var x = bounds.width * progress - lineView.frame.size.width
         var path = UIBezierPath(rect: CGRect(
@@ -136,26 +159,14 @@ class TSImageComparisonView: UIView {
         lineView.frame.origin.x = x
         
         // 更新新图片显示区域
-        let maskLayer = CAShapeLayer()
         maskLayer.path = path.cgPath
         newImageView.layer.mask = maskLayer
-        
-        
-        if progress >= 1.0 {
+//        dePrint("progress = \(progress)")
+        if progress == ((reverse == true) ? 0.0 : 1.0)  { //因为反转了进度,所以结果也要反转
+//            dePrint("animationComplete")
             animationComplete()
         }
+
     }
-    
-    func resetNewImageView(){
-        var path = UIBezierPath(rect: CGRect(
-            x: 0,
-            y: 0,
-            width: x,
-            height: bounds.height
-        ))
-        
-        let maskLayer = CAShapeLayer()
-        maskLayer.path = path.cgPath
-        newImageView.layer.mask = maskLayer
-    }
+
 }

+ 1 - 1
AIEmoji/Common/View/TYCycleImageComparisonView.swift

@@ -57,7 +57,7 @@ class TYCycleImageComparisonView: TSBaseView {
     lazy var cyclePagerView: TYCyclePagerView = {
         let pagerView = TYCyclePagerView()
         pagerView.isInfiniteLoop = true
-        pagerView.autoScrollInterval = 2.2
+        pagerView.autoScrollInterval = 1.7
         pagerView.delegate = self
         pagerView.dataSource = self
         pagerView.layout.layoutType = TYCyclePagerTransformLayoutType.linear

+ 2 - 0
AIEmoji/Info.plist

@@ -15,6 +15,8 @@
 			</array>
 		</dict>
 	</array>
+	<key>ITSAppUsesNonExemptEncryption</key>
+	<false/>
 	<key>NSAppTransportSecurity</key>
 	<dict>
 		<key>NSAllowsArbitraryLoads</key>

+ 6 - 1
AIEmoji/de.lproj/Localizable.strings

@@ -385,7 +385,7 @@
 "Generation" = "Generation";
 "Upgrade Yearly Pro" = "Upgrade Jährlich Pro";
 "Super Offer for Yearly Pro" = "Superangebot für Yearly Pro";
-"Only %s per day" = "Nur %s pro Tag";
+"Only %@ per day" = "Nur %@ pro Tag";
 "Reselect photos" = "Fotos erneut auswählen";
 "Zack&Morty" = "Rick & Morty";
 "Shin-chan" = "Buntstift Shin-chan";
@@ -394,3 +394,8 @@
 "Your photo may contain copyright infringement, nudity, gore or violence that does not comply with the Health Policy, please replace the photo and try again." = "Ihr Foto enthält möglicherweise Urheberrechtsverletzungen, Nacktheit, blutige Szenen oder Gewalt, die nicht mit den Gesundheitsrichtlinien übereinstimmen. Bitte ersetzen Sie das Foto und versuchen Sie es erneut.";
 "Anime" = "Anime";
 "Chibi Sticker" = "Aufkleber";
+"Lots of people are creating images right now, so this might take a bit." = "Viele Leute erstellen gerade Bilder, es könnte etwas dauern.";
+"Upgrade Yearly Pro" = "Upgrade Jährlich Pro";
+"Congratulations on being VIP of the Year!" = "Herzlichen Glückwunsch zum VIP des Jahres!";
+"Upgrade to PRO" = "Upgrade auf PRO";
+"Upgrade" = "Upgrade";

+ 6 - 1
AIEmoji/en.lproj/Localizable.strings

@@ -382,7 +382,7 @@
 "Generation" = "Generation";
 "Upgrade Yearly Pro" = "Upgrade Yearly Pro";
 "Super Offer for Yearly Pro" = "Super Offer for Yearly Pro";
-"Only %s per day" = "Only %s per day";
+"Only %@ per day" = "Only %@ per day";
 "Reselect photos" = "Reselect photos";
 "Zack&Morty" = "Zack&Morty";
 "Shin-chan" = "Shin-chan";
@@ -391,3 +391,8 @@
 "Your photo may contain copyright infringement, nudity, gore or violence that does not comply with the Health Policy, please replace the photo and try again." = "Your photo may contain copyright infringement, nudity, gore or violence that does not comply with the Health Policy, please replace the photo and try again.";
 "Anime" = "Anime";
 "Chibi Sticker" = "Chibi Sticker";
+"Lots of people are creating images right now, so this might take a bit." = "Lots of people are creating images right now, so this might take a bit.";
+"Upgrade Yearly Pro" = "Upgrade Yearly Pro";
+"Congratulations on being VIP of the Year!" = "Congratulations on being VIP of the Year!";
+"Upgrade to PRO" = "Upgrade to PRO";
+"Upgrade" = "Upgrade";

+ 6 - 1
AIEmoji/es.lproj/Localizable.strings

@@ -382,7 +382,7 @@
 "Generation" = "Generación";
 "Upgrade Yearly Pro" = "Actualizar Yearly Pro";
 "Super Offer for Yearly Pro" = "Super Oferta para Yearly Pro";
-"Only %s per day" = "Sólo %s al día";
+"Only %@ per day" = "Sólo %@ al día";
 "Reselect photos" = "Volver a seleccionar fotos";
 "Zack&Morty" = "Rick & Morty";
 "Shin-chan" = "Crayón Shin-chan";
@@ -391,3 +391,8 @@
 "Your photo may contain copyright infringement, nudity, gore or violence that does not comply with the Health Policy, please replace the photo and try again." = "Es posible que tu foto contenga infracciones de derechos de autor, desnudos, escenas sangrientas o violencia que no se ajusten a la Política Sanitaria; sustituye la foto e inténtalo de nuevo.";
 "Anime" = "Anime";
 "Chibi Sticker" = "Pegatina";
+"Lots of people are creating images right now, so this might take a bit." = "Mucha gente está creando imágenes ahora, puede tardar un poco.";
+"Upgrade Yearly Pro" = "Actualizar Yearly Pro";
+"Congratulations on being VIP of the Year!" = "¡Felicitaciones por ser VIP del año!";
+"Upgrade to PRO" = "Actualízate a PRO";
+"Upgrade" = "Mejora";

+ 6 - 1
AIEmoji/ja.lproj/Localizable.strings

@@ -381,7 +381,7 @@
 "Generation" = "生成";
 "Upgrade Yearly Pro" = "年会費アップグレード";
 "Super Offer for Yearly Pro" = "年会スーパー特典";
-"Only %s per day" = "1日あたり %s のみ";
+"Only %@ per day" = "1日あたり %@ のみ";
 "Reselect photos" = "写真を再選択します";
 "Zack&Morty" = "リック&モーティ";
 "Shin-chan" = "クレヨンしんちゃん";
@@ -390,3 +390,8 @@
 "Your photo may contain copyright infringement, nudity, gore or violence that does not comply with the Health Policy, please replace the photo and try again." = "あなたの写真には、著作権侵害、ヌード、グロ、暴力など、ヘルスポリシーに準拠しないものが含まれている可能性があります。";
 "Anime" = "アニメ";
 "Chibi Sticker" = "ステッカー";
+"Lots of people are creating images right now, so this might take a bit." = "現在多くの人が画像生成中ですので、少し時間がかかる場合があります。";
+"Upgrade Yearly Pro" = "年会費アップグレード";
+"Congratulations on being VIP of the Year!" = "VIP オブ ザ イヤー受賞おめでとうございます!";
+"Upgrade to PRO" = "PRO にアップグレード";
+"Upgrade" = "アップグレード";

+ 7 - 2
AIEmoji/ko.lproj/Localizable.strings

@@ -385,9 +385,9 @@
 "Get PRO Access" = "PRO 액세스 받기";
 "Unlimited" = "제한 없는";
 "Generation" = "세대";
-"Upgrade Yearly Pro" = "연간회원권 업그레이드";
+"Upgrade Yearly Pro" = "연간 프로 업그레이드";
 "Super Offer for Yearly Pro" = "연간회원권 슈퍼할인";
-"Only %s per day" = "하루에 %s 만";
+"Only %@ per day" = "하루에 %@ 만";
 "Reselect photos" = "사진 다시 선택";
 "Zack&Morty" = "릭 앤 모티";
 "Shin-chan" = "크레용 신짱";
@@ -396,3 +396,8 @@
 "Your photo may contain copyright infringement, nudity, gore or violence that does not comply with the Health Policy, please replace the photo and try again." = "사진에 저작권 침해, 나체, 유혈, 폭력 등 운영원칙에 맞지 않는 내용이 포함되어 있을 수 있으니 사진을 교체하고 다시 시도하세요.";
 "Anime" = "애니메이션";
 "Chibi Sticker" = "스티커";
+"Lots of people are creating images right now, so this might take a bit." = "현재 많은 사람들이 이미지를 생성 중이라 시간이 조금 걸릴 수 있습니다.";
+"Upgrade Yearly Pro" = "연간 프로 업그레이드";
+"Congratulations on being VIP of the Year!" = "올해의 VIP가 되신 것을 축하드립니다!";
+"Upgrade to PRO" = "PRO로 업그레이드";
+"Upgrade" = "업그레이드";

+ 7 - 2
AIEmoji/pt-BR.lproj/Localizable.strings

@@ -379,9 +379,9 @@
 "Get PRO Access" = "Obtenha acesso PRO";
 "Unlimited" = "Ilimitado";
 "Generation" = "Geração";
-"Upgrade Yearly Pro" = "Atualização do Yearly Pro";
+"Upgrade Yearly Pro" = "Atualização Pro Anual";
 "Super Offer for Yearly Pro" = "Super oferta para o Yearly Pro";
-"Only %s per day" = "Apenas %s por dia";
+"Only %@ per day" = "Apenas %@ por dia";
 "Reselect photos" = "Selecionar fotos novamente";
 "Zack&Morty" = "Rick & Morty";
 "Shin-chan" = "Crayon Shin-chan";
@@ -390,3 +390,8 @@
 "Your photo may contain copyright infringement, nudity, gore or violence that does not comply with the Health Policy, please replace the photo and try again." = "Sua foto pode conter violação de direitos autorais, nudez, sangue ou violência que não estejam em conformidade com a Política de Saúde.";
 "Anime" = "Anime";
 "Chibi Sticker" = "Adesivo";
+"Lots of people are creating images right now, so this might take a bit." = "Muita gente criando imagens agora, pode demorar um pouco.";
+"Upgrade Yearly Pro" = "Atualização Pro Anual";
+"Congratulations on being VIP of the Year!" = "Parabéns por ser VIP do Ano!";
+"Upgrade to PRO" = "Atualize para PRO";
+"Upgrade" = "Atualizar";

+ 7 - 2
AIEmoji/pt-PT.lproj/Localizable.strings

@@ -379,9 +379,9 @@
 "Get PRO Access" = "Obtenha acesso PRO";
 "Unlimited" = "Ilimitado";
 "Generation" = "Geração";
-"Upgrade Yearly Pro" = "Atualização do Yearly Pro";
+"Upgrade Yearly Pro" = "Atualização Pro Anual";
 "Super Offer for Yearly Pro" = "Super oferta para o Yearly Pro";
-"Only %s per day" = "Apenas %s por dia";
+"Only %@ per day" = "Apenas %@ por dia";
 "Reselect photos" = "Selecionar fotos novamente";
 "Zack&Morty" = "Rick & Morty";
 "Shin-chan" = "Crayon Shin-chan";
@@ -390,3 +390,8 @@
 "Your photo may contain copyright infringement, nudity, gore or violence that does not comply with the Health Policy, please replace the photo and try again." = "Sua foto pode conter violação de direitos autorais, nudez, sangue ou violência que não estejam em conformidade com a Política de Saúde.";
 "Anime" = "Anime";
 "Chibi Sticker" = "Adesivo";
+"Lots of people are creating images right now, so this might take a bit." = "Muita gente criando imagens agora, pode demorar um pouco.";
+"Upgrade Yearly Pro" = "Atualização Pro Anual";
+"Congratulations on being VIP of the Year!" = "Parabéns por ser VIP do Ano!";
+"Upgrade to PRO" = "Atualize para PRO";
+"Upgrade" = "Atualizar";

+ 6 - 1
AIEmoji/zh-Hans.lproj/Localizable.strings

@@ -383,7 +383,7 @@
 "Generation" = "生成";
 "Upgrade Yearly Pro" = "升级年度会员";
 "Super Offer for Yearly Pro" = "年度会员超级优惠";
-"Only %s per day" = "每日仅需 %s";
+"Only %@ per day" = "每日仅需 %@";
 "Reselect photos" = "重新选择照片";
 "Zack&Morty" = "瑞克和莫蒂";
 "Shin-chan" = "蜡笔小新";
@@ -392,3 +392,8 @@
 "Your photo may contain copyright infringement, nudity, gore or violence that does not comply with the Health Policy, please replace the photo and try again." = "你的照片可能含有不符合健康政策的侵权、裸露、血腥或暴力内容,请更换照片并重试。";
 "Anime" = "动漫";
 "Chibi Sticker" = "Q版贴纸";
+"Lots of people are creating images right now, so this might take a bit." = "现在很多人都正在生成图像,所以可能需要一点时间。";
+"Upgrade Yearly Pro" = "升级年度会员";
+"Congratulations on being VIP of the Year!" = "恭喜你成为年度 VIP!";
+"Upgrade to PRO" = "升级成为会员";
+"Upgrade" = "升级";

+ 6 - 1
AIEmoji/zh-Hant.lproj/Localizable.strings

@@ -373,7 +373,7 @@
 "Generation" = "產生";
 "Upgrade Yearly Pro" = "升級年度會員";
 "Super Offer for Yearly Pro" = "年度會員超級優惠";
-"Only %s per day" = "每日僅需 %s";
+"Only %@ per day" = "每日僅需 %@";
 "Reselect photos" = "重新選擇照片";
 "Zack&Morty" = "瑞克與莫蒂";
 "Shin-chan" = "蠟筆小新";
@@ -382,3 +382,8 @@
 "Your photo may contain copyright infringement, nudity, gore or violence that does not comply with the Health Policy, please replace the photo and try again." = "您的照片可能包含侵犯版權、裸露、血腥或暴力等不符合健康政策的內容,請更換照片並重試。";
 "Anime" = "動漫";
 "Chibi Sticker" = "Q版貼紙";
+"Lots of people are creating images right now, so this might take a bit." = "現在很多人都正在生成影像,所以可能需要一點時間。";
+"Upgrade Yearly Pro" = "升級年度會員";
+"Congratulations on being VIP of the Year!" = "恭喜你成為年度 VIP!";
+"Upgrade to PRO" = "陞級成為會員";
+"Upgrade" = "升級";