From: liangzhenying <867174124@qq.com> Date: Wed, 11 Mar 2026 10:23:05 +0000 (+0800) Subject: 改了字幕UI X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=ac5766cb52ba13f697580ab66d021416377837bd;p=mirrors%2FShenYin.git 改了字幕UI --- diff --git a/ShenYin/ShenYin.xcodeproj/project.pbxproj b/ShenYin/ShenYin.xcodeproj/project.pbxproj index c39b7e8..23cb084 100644 --- a/ShenYin/ShenYin.xcodeproj/project.pbxproj +++ b/ShenYin/ShenYin.xcodeproj/project.pbxproj @@ -126,6 +126,7 @@ Cache/LanuageCache.swift, Cache/RecordCache.swift, Cache/RecordDetailModel.swift, + Cache/SubTitleCache.swift, Cache/TipsCache.swift, Cache/UserCache.swift, Cache/UserInfo.swift, @@ -538,10 +539,9 @@ Sdk/JoySdk/VC/JoyTctyVC.swift, Sdk/JoySdk/VC/JoyXclyVC.swift, Sdk/JoySdk/VC/ModeVC.swift, - UI/Home/SubTitle/LanguagePickerView1.swift, UI/Home/SubTitle/PiPManager.swift, - UI/Home/SubTitle/PipPicker.swift, - UI/Home/SubTitle/PipSetView.swift, + UI/Home/SubTitle/SubTitleSetCell.swift, + UI/Home/SubTitle/SubTitleSetVC.swift, UI/Home/SubTitle/SubTitleVC.swift, ); target = 3FD1DFE32F0E00BF00A62733 /* playboy */; diff --git a/ShenYin/ShenYin/Assets.xcassets/home/home_subtitle.imageset/Contents.json b/ShenYin/ShenYin/Assets.xcassets/home/home_subtitle.imageset/Contents.json new file mode 100644 index 0000000..55fecaf --- /dev/null +++ b/ShenYin/ShenYin/Assets.xcassets/home/home_subtitle.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "实时双语字幕@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "实时双语字幕@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/ShenYin/ShenYin/Assets.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@2x.png" "b/ShenYin/ShenYin/Assets.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@2x.png" new file mode 100644 index 0000000..73782fe Binary files /dev/null and "b/ShenYin/ShenYin/Assets.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@2x.png" differ diff --git "a/ShenYin/ShenYin/Assets.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@3x.png" "b/ShenYin/ShenYin/Assets.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@3x.png" new file mode 100644 index 0000000..2a1bef9 Binary files /dev/null and "b/ShenYin/ShenYin/Assets.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@3x.png" differ diff --git a/ShenYin/ShenYin/Assets.xcassets/home/set_right.imageset/Contents.json b/ShenYin/ShenYin/Assets.xcassets/home/set_right.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/ShenYin/ShenYin/Assets.xcassets/home/set_right.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ShenYin/ShenYin/Assets.xcassets/home/set_right.imageset/Frame@2x.png b/ShenYin/ShenYin/Assets.xcassets/home/set_right.imageset/Frame@2x.png new file mode 100644 index 0000000..d551ce0 Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/home/set_right.imageset/Frame@2x.png differ diff --git a/ShenYin/ShenYin/Assets.xcassets/home/set_right.imageset/Frame@3x.png b/ShenYin/ShenYin/Assets.xcassets/home/set_right.imageset/Frame@3x.png new file mode 100644 index 0000000..5077710 Binary files /dev/null and b/ShenYin/ShenYin/Assets.xcassets/home/set_right.imageset/Frame@3x.png differ diff --git a/ShenYin/ShenYin/Cache/SubTitleCache.swift b/ShenYin/ShenYin/Cache/SubTitleCache.swift new file mode 100644 index 0000000..d2ede5d --- /dev/null +++ b/ShenYin/ShenYin/Cache/SubTitleCache.swift @@ -0,0 +1,97 @@ +// +// SubTitleCache.swift +// ShenYin +// +// Created by liangshi on 2026/3/11. +// +import HandyJSON + +enum SubTitleShowType:Int,HandyJSONEnum{ + /// 双语 + case all = 0 + /// 源语言 + case from = 1 + /// 目标语言 + case to = 2 + var title:String{ + switch self { + case .all: + return "双语".l10n + case .from: + return "原文".l10n + case .to: + return "译文".l10n + } + } +} +enum SubTitleSFontType:Int,HandyJSONEnum{ + case min = 12 + case stand = 14 + case big = 18 + var title:String{ + switch self { + case .min: + return "小".l10n + case .stand: + return "标准".l10n + case .big: + return "大".l10n + } + } + var font:UIFont{ + return .regular(CGFloat(self.rawValue)) + } +} + + +class SubTitleCacheModel:NSObject,HandyJSON,NSCoding { + var lan_form:CCAiLanguage = .english + var lan_to:CCAiLanguage = .chinse + var fontType:SubTitleSFontType = .stand + var showType:SubTitleShowType = .all + required public override init() { } + + func encode(with aCoder: NSCoder) { + aCoder.encode(lan_form.rawValue, forKey: "lan_form") + aCoder.encode(lan_to.rawValue, forKey: "lan_to") + aCoder.encode(fontType.rawValue, forKey: "fontType") + aCoder.encode(showType.rawValue, forKey: "showType") + } + + required init?(coder aDecoder: NSCoder) { + let lanFormString = aDecoder.decodeObject(forKey: "lan_form") as? String ?? "english" + let lanToString = aDecoder.decodeObject(forKey: "lan_to") as? String ?? "chinse" + let fontTypeValue = aDecoder.decodeInteger(forKey: "fontType") + let showTypeValue = aDecoder.decodeInteger(forKey: "showType") + + lan_form = CCAiLanguage(rawValue: lanFormString) ?? .english + lan_to = CCAiLanguage(rawValue: lanToString) ?? .chinse + fontType = SubTitleSFontType(rawValue: fontTypeValue) ?? .stand + showType = SubTitleShowType(rawValue: showTypeValue) ?? .all + } +} + + + +class SubTitleCache { + static let shared = SubTitleCache() + private let userDefaults = UserDefaults.standard + private let key = "SubTitleCache" + + func save(_ model: SubTitleCacheModel) { + let encoder = NSKeyedArchiver.archivedData(withRootObject: model) + userDefaults.set(encoder, forKey: key) + userDefaults.synchronize() + } + + func get() -> SubTitleCacheModel { + if let data = userDefaults.data(forKey: key), + let model = NSKeyedUnarchiver.unarchiveObject(with: data) as? SubTitleCacheModel { + return model + } + else{ + let model = SubTitleCacheModel() + return model + } + } +} diff --git a/ShenYin/ShenYin/Cache/UserModel.swift b/ShenYin/ShenYin/Cache/UserModel.swift index 6b599d8..cbe75b3 100644 --- a/ShenYin/ShenYin/Cache/UserModel.swift +++ b/ShenYin/ShenYin/Cache/UserModel.swift @@ -44,9 +44,7 @@ extension UserModel{ func tokenIsValid(finished: ((Bool) -> Void)? = nil){ HttpClient.request(CommomApi.token) { [weak self](model:UserInfoRoot,res) in guard let self = self else{return} -// if model.isSuccess{ - //测试上架暂时绕开苹果审核,不用强制绑定手机号码 - if model.isSuccess || model.code == 50022{ + if model.isSuccess { self.info = model.data self.info = model.data UserCache.shared.save(self.info) diff --git a/ShenYin/ShenYin/Sdk/JoySdk/VC/AiFunctionVC.swift b/ShenYin/ShenYin/Sdk/JoySdk/VC/AiFunctionVC.swift index 4f7d3a3..cc8e189 100644 --- a/ShenYin/ShenYin/Sdk/JoySdk/VC/AiFunctionVC.swift +++ b/ShenYin/ShenYin/Sdk/JoySdk/VC/AiFunctionVC.swift @@ -27,15 +27,18 @@ class AiFunctionVC:BaseVC{ override func setupViews() { navBar.title = device.productName - navBar.backgroundColor = .color(.bgColor) - view.backgroundColor = .color(.bgColor) + navBar.backgroundColor = .white + view.backgroundColor = .white view.addSubview(bgView) bgView.addSubviews([headerView,functionView,bottomView]) - headerView.bottonView.yc.addTap(target: self, action: #selector(chatAction)) + headerView.do { v in + v.chatView.yc.addTap(target: self, action: #selector(chatAction)) + v.subTitleView.yc.addTap(target: self, action: #selector(subTitleAction)) + } headerView.icon.imageView.kf.setImage(with: device.image.yc.asUrl) } @@ -77,7 +80,16 @@ class AiFunctionVC:BaseVC{ } @objc func chatAction(){ if CCBleManager.shared.isConected(mac: device.mac){ - CCPage.gotoChat() +// CCPage.gotoChat() + } + } + @objc func subTitleAction(){ + if #available(iOS 15.0, *) { +// if CCBleManager.shared.isConected(mac: device.mac){ + App.shared.goToPage(SubTitleVC()) +// } + } else { + // Fallback on earlier versions } } } diff --git a/ShenYin/ShenYin/Sdk/JoySdk/VC/HomeDeviceVC.swift b/ShenYin/ShenYin/Sdk/JoySdk/VC/HomeDeviceVC.swift index 62016ba..8da90ee 100644 --- a/ShenYin/ShenYin/Sdk/JoySdk/VC/HomeDeviceVC.swift +++ b/ShenYin/ShenYin/Sdk/JoySdk/VC/HomeDeviceVC.swift @@ -174,13 +174,6 @@ extension HomeDeviceVC:UICollectionViewDataSource,UICollectionViewDelegate,UICol func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let model = DeviceVM.shared.dataList[indexPath.row] App.shared.goToPage(AiFunctionVC(device: model)) - -// if #available(iOS 15.0, *) { -// App.shared.goToPage(SubTitleVC()) -// } else { -// // Fallback on earlier versions -// } - } func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView{ let header = HomeHeadInfoView.header(with: collectionView, indexPath: indexPath) diff --git a/ShenYin/ShenYin/Sdk/LogManager.swift b/ShenYin/ShenYin/Sdk/LogManager.swift index f61e054..8735333 100644 --- a/ShenYin/ShenYin/Sdk/LogManager.swift +++ b/ShenYin/ShenYin/Sdk/LogManager.swift @@ -9,7 +9,7 @@ import Foundation /// 日记管理 class Logger { - static var isDebug: Bool = false + static var isDebug: Bool = true fileprivate static let shared = Logger() private var fileHandle:FileHandle? diff --git a/ShenYin/ShenYin/UI/Home/HistoryRecord/SelecteCell.swift b/ShenYin/ShenYin/UI/Home/HistoryRecord/SelecteCell.swift index e32f48d..ba78c2c 100644 --- a/ShenYin/ShenYin/UI/Home/HistoryRecord/SelecteCell.swift +++ b/ShenYin/ShenYin/UI/Home/HistoryRecord/SelecteCell.swift @@ -23,16 +23,6 @@ enum FontType:Int{ var font:UIFont{ return .regular(CGFloat(self.rawValue)) } -// var value:Int{ -// switch self { -// case .min: -// return 10 -// case .stand: -// return 14 -// case .big: -// return 18 -// } -// } } enum ShareType:Int{ diff --git a/ShenYin/ShenYin/UI/Home/Root/HomeBottomView.swift b/ShenYin/ShenYin/UI/Home/Root/HomeBottomView.swift index 54f5d0f..3095ed0 100644 --- a/ShenYin/ShenYin/UI/Home/Root/HomeBottomView.swift +++ b/ShenYin/ShenYin/UI/Home/Root/HomeBottomView.swift @@ -16,7 +16,7 @@ class HomeBottomView: BaseView { bottonView.addSubviews([titleLabel,valueLabel,tipsIcon,arrowIcon]) // backgroundColor = .red bottonView.do { v in - v.backgroundColor = .color(.cellBg) + v.backgroundColor = .rgb(0xfafafa) v.yc.setCornerRadius(22) } tipsIcon.do { v in diff --git a/ShenYin/ShenYin/UI/Home/Root/HomeFunctionView.swift b/ShenYin/ShenYin/UI/Home/Root/HomeFunctionView.swift index e79e7de..6b32cec 100644 --- a/ShenYin/ShenYin/UI/Home/Root/HomeFunctionView.swift +++ b/ShenYin/ShenYin/UI/Home/Root/HomeFunctionView.swift @@ -131,7 +131,7 @@ fileprivate class HomeCell: BaseView { addSubview(bgView) bgView.addSubviews([titleLabel,icon,valueLabel,arrowIcon]) bgView.do { v in - v.backgroundColor = .color(.cellBg) + v.backgroundColor = .rgb(0xfafafa) v.yc.setCornerRadius(22) } icon.do { v in diff --git a/ShenYin/ShenYin/UI/Home/Root/HomeHeadView.swift b/ShenYin/ShenYin/UI/Home/Root/HomeHeadView.swift index 5cc8ffc..9068bad 100644 --- a/ShenYin/ShenYin/UI/Home/Root/HomeHeadView.swift +++ b/ShenYin/ShenYin/UI/Home/Root/HomeHeadView.swift @@ -6,72 +6,104 @@ // - class HomeHeadView: BaseView { let icon = CurrentDeviceView() - let bottonView = UIView() - let tipsIcon = UIImageView() - let titleLabel = UILabel() - let valueLabel = UILabel() - let arrowIcon = UIImageView() + let chatView = ItemView() + let subTitleView = ItemView() override func setupViews() { - addSubviews([icon,bottonView]) - bottonView.addSubviews([titleLabel,valueLabel,tipsIcon,arrowIcon]) - icon.do { v in -// v.backgroundColor = .lightGray - } - bottonView.do { v in - v.backgroundColor = .color(.cellBg) - v.yc.setCornerRadius(22) - } - tipsIcon.do { v in - v.image = UIImage(named: "home_chat") - } - titleLabel.do { (v) in - v.textColor = .color(.first) - v.font = .bold(18) - v.text = "AI" + "智能对话".l10n + addSubviews([icon,chatView,subTitleView]) + + chatView.do { v in + v.titleLabel.text = "AI" + "智能对话".l10n + v.valueLabel.text = "AI" + "伙伴,随叫随到".l10n + v.tipsIcon.image = UIImage(named: "home_chat") } - valueLabel.do { (v) in - v.textColor = .rgb(0x8d8d8d) - v.font = .regular(14) - v.text = "AI" + "伙伴,随叫随到".l10n + subTitleView.do { v in + v.titleLabel.text = "字幕翻译".l10n + v.valueLabel.text = "看视频,实时字幕翻译".l10n + v.tipsIcon.image = UIImage(named: "home_subtitle") } - arrowIcon.image = UIImage(named: "arrow_2") } - override func setupLayout() { icon.snp.makeConstraints { make in make.top.width.left.equalToSuperview() } - bottonView.snp.makeConstraints { make in - make.left.right.equalToSuperview().inset(15) - make.top.equalTo(icon.snp.bottom).offset(20) - make.bottom.equalToSuperview() - make.height.equalTo(116) - } - titleLabel.snp.makeConstraints { make in - make.left.equalToSuperview().inset(15) - make.top.equalTo(35) - } - valueLabel.snp.makeConstraints { make in - make.left.equalTo(titleLabel) - make.top.equalTo(65) + if true { + chatView.snp.remakeConstraints { make in + make.left.right.equalToSuperview().inset(15) + make.top.equalTo(icon.snp.bottom).offset(20) + make.height.equalTo(116) + } + subTitleView.snp.remakeConstraints { make in + make.left.right.equalToSuperview().inset(15) + make.top.equalTo(chatView.snp.bottom).offset(10) + make.bottom.equalToSuperview() + make.height.equalTo(chatView) + } + subTitleView.isHidden = false } - arrowIcon.snp.makeConstraints { make in - make.width.equalTo(7) - make.height.equalTo(13) - make.centerY.equalTo(valueLabel) - make.left.equalTo(valueLabel.snp.right).offset(2) + else{ + chatView.snp.remakeConstraints { make in + make.left.right.equalToSuperview().inset(15) + make.top.equalTo(icon.snp.bottom).offset(20) + make.height.equalTo(116) + make.bottom.equalToSuperview() + } + subTitleView.isHidden = true } - tipsIcon.snp.makeConstraints { make in - make.size.equalTo(50) - make.right.equalToSuperview().inset(24) - make.top.equalToSuperview().inset(33) + } + + class ItemView: BaseView { + let bottonView = UIView() + let tipsIcon = UIImageView() + let titleLabel = UILabel() + let valueLabel = UILabel() + let arrowIcon = UIImageView() + + override func setupViews() { + addSubviews([titleLabel,valueLabel,tipsIcon,arrowIcon]) + + backgroundColor = .rgb(0xfafafa) + yc.setCornerRadius(22) + + titleLabel.do { (v) in + v.textColor = .color(.first) + v.font = .bold(18) + + } + valueLabel.do { (v) in + v.textColor = .rgb(0x8d8d8d) + v.font = .regular(14) + } + arrowIcon.image = UIImage(named: "arrow_2") } + override func setupLayout() { + titleLabel.snp.makeConstraints { make in + make.left.equalToSuperview().inset(15) + make.top.equalTo(35) + } + valueLabel.snp.makeConstraints { make in + make.left.equalTo(titleLabel) + make.top.equalTo(65) + } + arrowIcon.snp.makeConstraints { make in + make.width.equalTo(7) + make.height.equalTo(13) + make.centerY.equalTo(valueLabel) + make.left.equalTo(valueLabel.snp.right).offset(2) + } + tipsIcon.snp.makeConstraints { make in + make.size.equalTo(50) + make.right.equalToSuperview().inset(24) + make.top.equalToSuperview().inset(33) + } + + } } } + + diff --git a/ShenYin/ShenYin/UI/Home/SubTitle/LanguagePickerView1.swift b/ShenYin/ShenYin/UI/Home/SubTitle/LanguagePickerView1.swift deleted file mode 100644 index 636af0b..0000000 --- a/ShenYin/ShenYin/UI/Home/SubTitle/LanguagePickerView1.swift +++ /dev/null @@ -1,306 +0,0 @@ -// -// Untitled.swift -// ShenYin -// -// Created by liangshi on 2026/3/5. -// - -import UIKit -import JoyGemAI -@available(iOS 15.0, *) -// MARK: - 数据模型 -struct LanguageModel { - - let code: String - let name: String - let nativeName: String - - static let chinese = LanguageModel(code: kJoyGemAILocalizationZH, name: "Chinese", nativeName: "中文") - static let english = LanguageModel(code: kJoyGemAILocalizationEN, name: "English", nativeName: "英语") - static let japanese = LanguageModel(code: kJoyGemAILocalizationJA, name: "Japanese", nativeName: "日本語") - static let korean = LanguageModel(code: kJoyGemAILocalizationKO, name: "Korean", nativeName: "韩语") - static let french = LanguageModel(code: kJoyGemAILocalizationFR, name: "French", nativeName: "法语") - static let spanish = LanguageModel(code: kJoyGemAILocalizationES, name: "Spanish", nativeName: "西班牙语") - static let portuguese = LanguageModel(code: kJoyGemAILocalizationPT, name: "Portuguese", nativeName: "葡萄牙语") - static let indonesia = LanguageModel(code: kJoyGemAILocalizationID, name: "Indonesia", nativeName: "印尼语") - static let russian_ori = LanguageModel(code: kJoyGemAILocalizationRU_Original, name: "Russian", nativeName: "俄语") - static let russian_tar = LanguageModel(code: kJoyGemAILocalizationRU_Target, name: "Russian", nativeName: "俄语") - static let malay = LanguageModel(code: kJoyGemAILocalizationMS, name: "Malay", nativeName: "马来语") - static let german = LanguageModel(code: kJoyGemAILocalizationDE, name: "German", nativeName: "德语") - static let filipino = LanguageModel(code: kJoyGemAILocalizationFIL, name: "Filipino", nativeName: "菲律宾语") - static let thai = LanguageModel(code: kJoyGemAILocalizationTH, name: "Thai", nativeName: "泰语") - static let arabic = LanguageModel(code: kJoyGemAILocalizationAR, name: "Arabic", nativeName: "阿拉伯语") - static let vietnamese = LanguageModel(code: kJoyGemAILocalizationVI, name: "Vietnamese", nativeName: "越南语") -} - -// 语言选择器的委托协议 -@available(iOS 15.0, *) -protocol LanguagePickerView1Delegate: AnyObject { - - func languagePickerView(_ pickerView: LanguagePickerView1, - didSelectSourceLanguage source: LanguageModel, - targetLanguage target: LanguageModel) - - func languagePickerViewDidTapSwap(_ pickerView: LanguagePickerView1) -} -@available(iOS 15.0, *) -class LanguagePickerView1: UIView { - - // MARK: - UI 组件 - private let sourcePickerView = UIPickerView() - private let targetPickerView = UIPickerView() - private let swapButton = UIButton(type: .system) - private let sourceLabel = UILabel() - private let targetLabel = UILabel() - - // MARK: - 属性 - weak var delegate: LanguagePickerView1Delegate? - - var selectedSourceLanguage: LanguageModel? { - didSet { updateSelection() } - } - - var selectedTargetLanguage: LanguageModel? { - didSet { updateSelection() } - } - - var languages: [LanguageModel] = [ - .chinese, .english, .japanese,.korean,.french,.spanish,.portuguese,.indonesia,.russian_ori,.malay,.german,.filipino,.thai,.arabic,.vietnamese - ] - - // MARK: - 初始化 - override init(frame: CGRect) { - super.init(frame: frame) - setupUI() - setupDefaults() - } - - required init?(coder: NSCoder) { - super.init(coder: coder) - setupUI() - setupDefaults() - } - - // MARK: - UI 设置 - private func setupUI() { - backgroundColor = .systemBackground - - setupLabels() - setupPickerViews() - setupSwapButton() - setupConstraints() - } - - private func setupLabels() { - sourceLabel.text = "源语言" - sourceLabel.font = UIFont.boldSystemFont(ofSize: 16) - sourceLabel.textAlignment = .center - addSubview(sourceLabel) - - targetLabel.text = "目标语言" - targetLabel.font = UIFont.boldSystemFont(ofSize: 16) - targetLabel.textAlignment = .center - addSubview(targetLabel) - } - - private func setupPickerViews() { - // 源语言选择器 - sourcePickerView.translatesAutoresizingMaskIntoConstraints = false - sourcePickerView.dataSource = self - sourcePickerView.delegate = self - sourcePickerView.tag = 0 - addSubview(sourcePickerView) - - // 目标语言选择器 - targetPickerView.translatesAutoresizingMaskIntoConstraints = false - targetPickerView.dataSource = self - targetPickerView.delegate = self - targetPickerView.tag = 1 - addSubview(targetPickerView) - } - - private func setupSwapButton() { - swapButton.translatesAutoresizingMaskIntoConstraints = false - swapButton.setImage(UIImage(systemName: "arrow.left.arrow.right"), for: .normal) - swapButton.tintColor = .systemBlue - swapButton.backgroundColor = .systemGray6 - swapButton.layer.cornerRadius = 20 - swapButton.addTarget(self, action: #selector(swapButtonTapped), for: .touchUpInside) - addSubview(swapButton) - } - - private func setupConstraints() { - sourceLabel.snp.makeConstraints { make in - make.top.equalToSuperview().offset(8) - make.leading.equalToSuperview().offset(20) - make.trailing.equalTo(swapButton.snp.leading).offset(-20) - make.height.equalTo(20) - } - - targetLabel.snp.makeConstraints { make in - make.top.equalToSuperview().offset(8) - make.trailing.equalToSuperview().offset(-20) - make.leading.equalTo(swapButton.snp.trailing).offset(20) - make.height.equalTo(20) - } - - sourcePickerView.snp.makeConstraints { make in - make.top.equalTo(sourceLabel.snp.bottom).offset(8) - make.leading.equalToSuperview().offset(20) - make.trailing.equalTo(swapButton.snp.leading).offset(-20) - make.bottom.equalToSuperview().offset(-8) - } - - targetPickerView.snp.makeConstraints { make in - make.top.equalTo(targetLabel.snp.bottom).offset(8) - make.trailing.equalToSuperview().offset(-20) - make.leading.equalTo(swapButton.snp.trailing).offset(20) - make.bottom.equalToSuperview().offset(-8) - } - - swapButton.snp.makeConstraints { make in - make.centerX.equalToSuperview() - make.centerY.equalTo(sourcePickerView.snp.centerY) - make.height.equalTo(40) - make.width.equalTo(40) - } - } - - private func setupDefaults() { - // 设置默认选择 - if let chineseIndex = languages.firstIndex(where: { $0.code == "zh" }) { - sourcePickerView.selectRow(chineseIndex, inComponent: 0, animated: false) - selectedSourceLanguage = languages[chineseIndex] - } - - if let englishIndex = languages.firstIndex(where: { $0.code == "en" }) { - targetPickerView.selectRow(englishIndex, inComponent: 0, animated: false) - selectedTargetLanguage = languages[englishIndex] - } - } - - // MARK: - 公共方法 - func setLanguages(source: LanguageModel, target: LanguageModel) { - if let sourceIndex = languages.firstIndex(where: { $0.code == source.code }) { - sourcePickerView.selectRow(sourceIndex, inComponent: 0, animated: true) - selectedSourceLanguage = source - } - - if let targetIndex = languages.firstIndex(where: { $0.code == target.code }) { - targetPickerView.selectRow(targetIndex, inComponent: 0, animated: true) - selectedTargetLanguage = target - } - } - - func getSelectedLanguages() -> (source: LanguageModel?, target: LanguageModel?) { - return (selectedSourceLanguage, selectedTargetLanguage) - } - - // MARK: - 私有方法 - private func updateSelection() { - // 可以在这里添加选择更新后的逻辑 - print("源语言: \(selectedSourceLanguage?.nativeName ?? "无")") - print("目标语言: \(selectedTargetLanguage?.nativeName ?? "无")") - - // 通知委托 - if let source = selectedSourceLanguage, let target = selectedTargetLanguage { - delegate?.languagePickerView(self, didSelectSourceLanguage: source, targetLanguage: target) - } - } - - @objc private func swapButtonTapped() { - guard let source = selectedSourceLanguage, - let target = selectedTargetLanguage else { return } - - // 交换语言 - setLanguages(source: target, target: source) - - // 通知委托 - delegate?.languagePickerViewDidTapSwap(self) - } -} - -// MARK: - UIPickerView DataSource & Delegate -@available(iOS 15.0, *) -extension LanguagePickerView1: UIPickerViewDataSource, UIPickerViewDelegate { - - func numberOfComponents(in pickerView: UIPickerView) -> Int { - return 1 - } - - func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { - return languages.count - } - - func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { - let language = languages[row] - return "\(language.nativeName) (\(language.name))" - } - - func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { - let selectedLanguage = languages[row] - - if pickerView.tag == 0 { - selectedSourceLanguage = selectedLanguage - } else { - selectedTargetLanguage = selectedLanguage - } - - // 防止选择相同的语言 - validateSelection() - } - - func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat { - return 44.0 - } - - func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView { - let language = languages[row] - - let containerView = UIView() - containerView.backgroundColor = .clear - - let stackView = UIStackView() - stackView.axis = .vertical - stackView.alignment = .center - stackView.spacing = 2 - stackView.translatesAutoresizingMaskIntoConstraints = false - - let nativeLabel = UILabel() - nativeLabel.text = language.nativeName - nativeLabel.font = UIFont.systemFont(ofSize: 16, weight: .medium) - nativeLabel.textAlignment = .center - nativeLabel.textColor = .label - - let nameLabel = UILabel() - nameLabel.text = language.name - nameLabel.font = UIFont.systemFont(ofSize: 12, weight: .regular) - nameLabel.textColor = .secondaryLabel - nameLabel.textAlignment = .center - - stackView.addArrangedSubview(nativeLabel) - stackView.addArrangedSubview(nameLabel) - containerView.addSubview(stackView) - - NSLayoutConstraint.activate([ - stackView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor), - stackView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), - stackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 8), - stackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -8) - ]) - - return containerView - } - - private func validateSelection() { - guard let source = selectedSourceLanguage, - let target = selectedTargetLanguage, - source.code == target.code else { return } - - // 如果选择了相同的语言,自动调整目标语言 - if let alternativeIndex = languages.firstIndex(where: { $0.code != source.code }) { - targetPickerView.selectRow(alternativeIndex, inComponent: 0, animated: true) - selectedTargetLanguage = languages[alternativeIndex] - } - } -} diff --git a/ShenYin/ShenYin/UI/Home/SubTitle/PiPManager.swift b/ShenYin/ShenYin/UI/Home/SubTitle/PiPManager.swift index 99aabad..5f7b0c5 100644 --- a/ShenYin/ShenYin/UI/Home/SubTitle/PiPManager.swift +++ b/ShenYin/ShenYin/UI/Home/SubTitle/PiPManager.swift @@ -118,7 +118,6 @@ extension PiPManager: AVPictureInPictureControllerDelegate { // 画中画内容视图控制器 @available(iOS 15.0, *) class DesktopLyricsContentVC : AVPictureInPictureVideoCallViewController { - let setView = PipSetView() var textView = UITextView() var translateTextView = UITextView() @@ -128,37 +127,54 @@ class DesktopLyricsContentVC : AVPictureInPictureVideoCallViewController { setupLayout() } func setupViews(){ - view.addSubviews([setView,textView,translateTextView]) + view.addSubviews([textView,translateTextView]) + view.backgroundColor = .clear textView.do { v in - v.textColor = UIColor.white - v.text = "原文" + v.textColor = UIColor.blue + v.text = "原文".l10n v.font = UIFont.boldSystemFont(ofSize: 14) - v.backgroundColor = UIColor.gray + v.backgroundColor = .clear } translateTextView.do { v in v.textColor = UIColor.orange - v.text = "翻译" + v.text = "译文".l10n v.font = UIFont.boldSystemFont(ofSize: 14) - v.backgroundColor = UIColor.gray + v.backgroundColor = .clear } } func setupLayout(){ - setView.snp.makeConstraints { make in - make.left.right.equalToSuperview() - make.height.equalTo(34) - make.top.equalToSuperview() - } - textView.snp.makeConstraints { make in - make.top.equalToSuperview().inset(40) - make.leading.trailing.equalToSuperview() - make.bottom.equalTo(view.snp.centerY) + let cache = SubTitleCache.shared.get() + + if cache.showType == .all { + textView.snp.makeConstraints { make in + make.top.equalToSuperview().inset(40) + make.leading.trailing.equalToSuperview() + make.bottom.equalTo(view.snp.centerY) + } + translateTextView.snp.makeConstraints { make in + make.leading.trailing.equalToSuperview() + make.top.equalTo(textView.snp.bottom) + make.height.equalTo(textView.snp.height) + } + textView.isHidden = false + translateTextView.isHidden = false } - translateTextView.snp.makeConstraints { make in - make.leading.trailing.equalToSuperview() - make.top.equalTo(textView.snp.bottom) - make.height.equalTo(textView.snp.height) + else if cache.showType == .from { + textView.snp.makeConstraints { make in + make.top.bottom.equalToSuperview().inset(40) + make.leading.trailing.equalToSuperview() + } + textView.isHidden = false + translateTextView.isHidden = true + } else { + translateTextView.snp.makeConstraints { make in + make.top.bottom.equalToSuperview().inset(40) + make.leading.trailing.equalToSuperview() + } + textView.isHidden = true + translateTextView.isHidden = false } } diff --git a/ShenYin/ShenYin/UI/Home/SubTitle/PipPicker.swift b/ShenYin/ShenYin/UI/Home/SubTitle/PipPicker.swift deleted file mode 100644 index 872364a..0000000 --- a/ShenYin/ShenYin/UI/Home/SubTitle/PipPicker.swift +++ /dev/null @@ -1,164 +0,0 @@ -// -// Untitled.swift -// ShenYin -// -// Created by liangshi on 2026/3/6. -// - -import UIKit -class PipPicker: BaseView { - private let btn = UIButton(type: .custom) - private let tableView = UITableView(frame: .zero, style: .plain) - var list:[String] = [] - - var selectedIndex = 0{ - didSet{ - tableView.reloadData() - } - } - var didSelected: ((Int,String)->Void)? - private var title:String = "" - - init(list:[String]) { - super.init(frame: .zero) - } - - @MainActor required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func setupViews() { - addSubviews([btn,tableView]) - - btn.do { v in - v.setImage(UIImage(named: "close_icon"), for: .normal) - v.addTarget(self, action: #selector(closeAction), for: .touchUpInside) - } - tableView.do { v in - v.backgroundColor = .color(.cellBg) - v.delegate = self - v.dataSource = self - v.rowHeight = 52 - v.separatorStyle = .none - v.register(CustomButton.SelectCell.self, forCellReuseIdentifier: CustomButton.SelectCell.reuseID) - } - } - override func setupLayout() { - super.setupLayout() - btn.snp.makeConstraints { (m) in - m.bottom.equalToSuperview() - m.right.equalToSuperview() - m.size.equalTo(60) - } - tableView.snp.makeConstraints { make in - make.left.right.bottom.equalToSuperview() - make.top.equalToSuperview().inset(10) - } - } - @objc func closeAction(){ - - } -} -extension PipPicker:UITableViewDelegate,UITableViewDataSource { - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return list.count - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = CustomButton.SelectCell.cell(withTableView: tableView, indexPath: indexPath) - cell.titleLabel.text = list[indexPath.row] - cell.selectedIcon.isHidden = selectedIndex != indexPath.row - return cell - } - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - selectedIndex = indexPath.row - tableView.reloadData() - didSelected?(selectedIndex,list[selectedIndex]) - } -} - -fileprivate extension CustomButton { - class SelectCell: BaseTableViewCell { - let bgView = UIView() - let titleLabel = UILabel() - let selectedIcon = UIImageView() - let line = UIView() - - var fontType:FontType = .min{ - didSet{ - titleLabel.text = fontType.title - } - } - - var shareType:ShareType = .document{ - didSet{ - titleLabel.text = shareType.title - } - } - - var enable:Bool = true{ - didSet{ - if enable{ - titleLabel.textColor = .color(.first) - } - else{ - titleLabel.textColor = .color(.secondary) - } - } - } - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - override func setupViews() { - contentView.addSubview(bgView) - bgView.addSubviews([titleLabel,selectedIcon,line]) - - backgroundColor = .color(.bgColor) - contentView.backgroundColor = .clear - selectionStyle = .none - bgView.do { v in - v.backgroundColor = .color(.cellBg) - } - titleLabel.do { (v) in - v.textColor = .color(.first) - v.font = .bold(14) - v.textAlignment = .left - } - - selectedIcon.image = UIImage(named: "cell_selected") - line.do { v in - v.backgroundColor = .color(.separateLine) - } - } - - override func setupLayout() { - bgView.snp.makeConstraints { (m) in - m.left.right.equalToSuperview() - m.top.equalToSuperview() - m.bottom.equalToSuperview() - } - selectedIcon.snp.makeConstraints { (m) in - m.width.equalTo(21) - m.height.equalTo(16) - m.right.equalToSuperview().inset(21) - m.centerY.equalToSuperview() - } - titleLabel.snp.makeConstraints { (m) in - m.centerY.equalToSuperview() - m.left.equalToSuperview().offset(24) - m.height.equalToSuperview() - } - line.snp.makeConstraints { make in - make.left.right.equalToSuperview().inset(18) - make.bottom.equalToSuperview() - make.height.equalTo(0.4) - } - } - } - -} - diff --git a/ShenYin/ShenYin/UI/Home/SubTitle/PipSetView.swift b/ShenYin/ShenYin/UI/Home/SubTitle/PipSetView.swift deleted file mode 100644 index 8d66cd3..0000000 --- a/ShenYin/ShenYin/UI/Home/SubTitle/PipSetView.swift +++ /dev/null @@ -1,77 +0,0 @@ -// -// PipSetView.swift -// ShenYin -// -// Created by liangshi on 2026/3/6. -// - -class PipSetView: BaseView { - let setBtn = UIButton(type: .custom) - let closeBtn = UIButton(type: .custom) - let languageItem = UIButton(type: .custom) - let dispalyItem = UIButton(type: .custom) - - override func setupViews() { - addSubviews([setBtn,languageItem,dispalyItem,closeBtn]) - - setBtn.do { v in - v.setImage(UIImage(named: "pip_set"), for: .normal) - v.addTarget(self, action: #selector(setBtnAction), for: .touchUpInside) - } - closeBtn.do { v in - v.setImage(UIImage(named: "pip_close"), for: .normal) - v.addTarget(self, action: #selector(closeAction), for: .touchUpInside) - } - languageItem.do { v in - v.setTitle("", for: .normal) - v.addTarget(self, action: #selector(languageAction), for: .touchUpInside) - v.yc.setCornerRadius(12) - v.backgroundColor = .red - } - dispalyItem.do { v in - v.setTitle("", for: .normal) - v.addTarget(self, action: #selector(displayAction), for: .touchUpInside) - v.yc.setCornerRadius(12) - v.backgroundColor = .red - } - } - override func setupLayout() { - setBtn.snp.makeConstraints { make in - make.size.equalTo(24) - make.left.equalToSuperview().inset(16) - make.top.equalToSuperview().inset(10) - } - closeBtn.snp.makeConstraints { make in - make.size.equalTo(24) - make.right.equalToSuperview().inset(16) - make.centerY.equalTo(setBtn) - } - languageItem.snp.makeConstraints { make in - make.height.equalTo(24) - make.left.equalTo(setBtn.snp.right).offset(4) - make.centerY.equalTo(setBtn) - make.width.equalTo(57) - } - dispalyItem.snp.makeConstraints { make in - make.height.equalTo(24) - make.left.equalTo(languageItem.snp.right).offset(4) - make.centerY.equalTo(setBtn) - make.width.equalTo(57) - } - } - @objc func setBtnAction(){ - Logger.debug("setBtnAction") - } - @objc func languageAction(){ - Logger.debug("languageAction") - } - @objc func displayAction(){ - Logger.debug("displayAction") - let view = PipPicker(list: ["只显示原文","只显译文","原文 & 译文"]) - superview?.addSubview(view) - } - @objc func closeAction(){ - Logger.debug("closeAction") - - } -} diff --git a/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleSetCell.swift b/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleSetCell.swift new file mode 100644 index 0000000..7a52794 --- /dev/null +++ b/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleSetCell.swift @@ -0,0 +1,113 @@ +// +// SubTitleSetCell.swift +// ShenYin +// +// Created by liangshi on 2026/3/11. +// + +public enum SubTitleSetCellType: Int { + case language + case showType + case font + + var title:String{ + switch self { + case .language: + return "语言".l10n + case .showType: + return "字幕展示内容".l10n + case .font: + return "字号大小".l10n + } + } +} + + +class SubTitleSetCell: BaseTableViewCell { + let bgView = UIView() + let titleLabel = UILabel() + let nextIcon = UIImageView() + let valueLabel = UILabel() + let line = UIView() + + var type:SubTitleSetCellType = .language{ + didSet{ + titleLabel.text = type.title + let model = SubTitleCache.shared.get() + if type == .language { + valueLabel.text = model.lan_form.title + "-" + model.lan_to.title + } + else if type == .showType { + valueLabel.text = model.showType.title + } + else if type == .font { + valueLabel.text = model.fontType.title + } + } + } + + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + override func setupViews() { + contentView.addSubview(bgView) + bgView.addSubviews([titleLabel,nextIcon,valueLabel,line]) + + backgroundColor = .color(.bgColor) + contentView.backgroundColor = .clear + selectionStyle = .none + bgView.do { v in + v.backgroundColor = .color(.cellBg) + } + titleLabel.do { (v) in + + v.textColor = .color(.first) + v.font = .bold(14) + v.textAlignment = .left + } + valueLabel.do { v in + v.textColor = .color(.secondary) + v.font = .regular(14) + v.textAlignment = .right + } + line.do { v in + v.backgroundColor = .color(.separateLine) + } + nextIcon.image = UIImage(named: "arrow_next") + } + + override func setupLayout() { + bgView.snp.makeConstraints { (m) in + m.left.right.equalToSuperview().inset(18) + m.top.equalToSuperview() + m.bottom.equalToSuperview() + } + titleLabel.snp.makeConstraints { (m) in + m.centerY.equalToSuperview() + m.left.equalToSuperview().offset(16) + m.height.equalToSuperview() + } + nextIcon.snp.makeConstraints { (m) in + m.width.equalTo(8) + m.height.equalTo(12) + m.right.equalToSuperview().inset(15) + m.centerY.equalToSuperview() + } + valueLabel.snp.makeConstraints { (m) in + m.centerY.equalToSuperview() + m.right.equalToSuperview().inset(38) + m.height.equalToSuperview() + m.left.equalToSuperview().inset(90) + } + line.snp.makeConstraints { make in + make.left.right.equalToSuperview().inset(18) + make.bottom.equalToSuperview() + make.height.equalTo(0.4) + } + } +} diff --git a/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleSetVC.swift b/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleSetVC.swift new file mode 100644 index 0000000..d35a33c --- /dev/null +++ b/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleSetVC.swift @@ -0,0 +1,118 @@ +// +// SubTitleSetVC.swift +// ShenYin +// +// Created by liangshi on 2026/3/11. +// + +import UIKit +class SubTitleSetVC: BaseVC{ + let tableView = UITableView(frame: .zero, style: .plain) + var list:[SubTitleSetCellType] = [.language,.showType,.font] + let imgPicker = ImagePickerManager() + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + override func setupViews() { + self.navBar.title = "设置".l10n + tableView.do { v in + v.backgroundColor = .color(.bgColor) + v.delegate = self + v.dataSource = self + v.rowHeight = 52 + v.sectionHeaderHeight = 52 + v.separatorStyle = .none + v.register(SubTitleSetCell.self, forCellReuseIdentifier: SubTitleSetCell.reuseID) + } + view.addSubview(tableView) + } + override func setupLayout() { + tableView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.top.equalTo(kNavBtm) + } + } + +} + +extension SubTitleSetVC:UITableViewDelegate,UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return list.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = SubTitleSetCell.cell(withTableView: tableView, indexPath: indexPath) + cell.type = list[indexPath.row] + let rect = CGRect(x: 0, y: 0, width: kScreenWid - 36, height: 52) + if indexPath.row == 0 { + cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.topLeft,.topRight], cornerRadii: CGSize(width: 12, height: 12)) + } + else if indexPath.row == list.count - 1{ + cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.bottomLeft,.bottomRight], cornerRadii: CGSize(width: 12, height: 12)) + } + else{ + cell.bgView.yc.setCorners(withRoundedRect: rect, roundingCorners: [.allCorners], cornerRadii: CGSize(width: 0, height: 0)) + } + return cell + } + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let data = list[indexPath.row] + switch data { + case .language: + languageAction() + case .showType: + showTypeAction() + case .font: + fontAction() + } + } +} + +extension SubTitleSetVC{ + func languageAction(){ + let cache = SubTitleCache.shared.get() + let v = LanguagePickerView(languages: CCAiLanguage.all,isLeft: true,left: cache.lan_form,right: cache.lan_to) + v.selectedIndex = v.list.firstIndex(where: {$0.title == cache.lan_form.title}) ?? 0 + v.show() + v.didSelected = {[weak self] (index,value) in + guard let self = self else { return } + if index == 0 { + cache.lan_form = value + } + else{ + cache.lan_to = value + } + + SubTitleCache.shared.save(cache) + tableView.reloadData() + } + } + @objc func showTypeAction(){ + let cache = SubTitleCache.shared.get() + let list:[SubTitleShowType] = [.all,.from,.to] + let picker = CustomPicker(title: "字幕展示内容".l10n, list: list.map{$0.title}) + picker.selectedIndex = list.firstIndex(where: {cache.showType.title == $0.title})! + picker.show() + picker.didSelected = {[weak self] (index,value) in + guard let self = self else { return } + cache.showType = list.first(where: {$0.title == value})! + SubTitleCache.shared.save(cache) + tableView.reloadData() + } + } + @objc func fontAction(){ + let cache = SubTitleCache.shared.get() + let list:[SubTitleSFontType] = [.min,.stand,.big] + let picker = CustomPicker(title: "字体大小".l10n, list: list.map{$0.title}) + picker.selectedIndex = list.firstIndex(where: {cache.fontType.title == $0.title})! + picker.show() + picker.didSelected = {[weak self] (index,value) in + guard let self = self else { return } + cache.fontType = list.first(where: {$0.title == value})! + SubTitleCache.shared.save(cache) + tableView.reloadData() + } + } +} diff --git a/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleVC.swift b/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleVC.swift index 915eed2..159bcc7 100644 --- a/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleVC.swift +++ b/ShenYin/ShenYin/UI/Home/SubTitle/SubTitleVC.swift @@ -11,14 +11,9 @@ import AVKit import JoyGemAI import SVProgressHUD @available(iOS 15.0, *) -class SubTitleVC: UIViewController { - - lazy var languagePickerView : LanguagePickerView1 = { - let pickerView = LanguagePickerView1() - pickerView.delegate = self - return pickerView - }() - +class SubTitleVC: BaseVC { + let languageItem = LanguageSelectItem() + let toolBar = RecordBar() var startButton : UIButton! var stopButton : UIButton! @@ -26,77 +21,74 @@ class SubTitleVC: UIViewController { //画中画载体 - internal var customView : UIView = UIView() + internal var sourceView : UIView = UIView() override func viewDidLoad() { super.viewDidLoad() + } + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + let cache = SubTitleCache.shared.get() + languageItem.leftLabel.language = cache.lan_form + languageItem.rightLabel.language = cache.lan_to + } + override func setupViews() { view.backgroundColor = UIColor.white - title = "字幕翻译" - - self.navigationController?.navigationBar.tintColor = UIColor.black - do { - try AVAudioSession.sharedInstance().setCategory(.playback) - try AVAudioSession.sharedInstance().setActive(true) - } catch { - print(error) - } - - view.addSubview(languagePickerView) - languagePickerView.snp.makeConstraints { make in - make.top.equalTo(view.safeAreaLayoutGuide.snp.top) - make.leading.trailing.equalToSuperview() - make.height.equalTo(100) + sourceView.backgroundColor = .clear + navBar.do { v in + v.backgroundColor = .white + v.addSubview(languageItem) + v.rightView.isHidden = false + v.rightView.setImage(UIImage(named: "set_right"), for: .normal) } - // 或者设置特定语言 - languagePickerView.setLanguages( - source: LanguageModel.chinese, - target: LanguageModel.english - ) + view.addSubviews([sourceView,toolBar]) - view.addSubview(customView) - customView.snp.makeConstraints { make in - make.top.equalTo(languagePickerView.snp.bottom).offset(20) - make.height.equalTo(40) + toolBar.do { v in + v.delegate = self + v.leftItem.isHidden = true + v.rightItem.isHidden = true + } + languageItem.do { v in + v.languageChange = {[weak self] (from,to) in + guard let self = self else { return } + let cache = SubTitleCache.shared.get() + cache.lan_form = from + cache.lan_to = to + SubTitleCache.shared.save(cache) + } + } + } + override func setupLayout() { + languageItem.snp.makeConstraints { make in + make.left.right.equalToSuperview().inset(80) + make.centerX.equalToSuperview() + make.bottom.equalToSuperview().offset(5) + } + toolBar.snp.makeConstraints { make in + make.width.centerX.equalToSuperview() + make.height.equalTo(120) + make.bottom.equalToSuperview() + } + sourceView.snp.makeConstraints { make in + make.top.equalTo(kNavBtm + 20) + make.height.equalTo(200) make.centerX.equalToSuperview() make.width.equalTo(200) } - - startButton = UIButton(type: .system) - startButton.setTitle("开始", for: .normal) - startButton.backgroundColor = UIColor.systemGray6 - startButton.setTitleColor(UIColor.darkText, for: .normal) - startButton.addTarget(self, action: #selector(startRecord), for: .touchUpInside) - - stopButton = UIButton(type: .system) - stopButton.setTitle("结束", for: .normal) - stopButton.backgroundColor = UIColor.systemGray6 - stopButton.setTitleColor(UIColor.darkText, for: .normal) - stopButton.addTarget(self, action: #selector(endRecord), for: .touchUpInside) - - let stackView = UIStackView(arrangedSubviews: [startButton, stopButton]) - stackView.axis = .horizontal - stackView.distribution = .fillEqually - stackView.alignment = .center - stackView.spacing = 16 - - view.addSubview(stackView) - stackView.snp.makeConstraints { make in - make.height.equalTo(60) - make.leading.equalToSuperview().offset(20) - make.trailing.equalToSuperview().offset(-20) - make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom).offset(-20) + } + + override func setupData() { + do { + try AVAudioSession.sharedInstance().setCategory(.playback) + try AVAudioSession.sharedInstance().setActive(true) + } catch { + print(error) } - // Do any additional setup after loading the view. JoyGemSubtitleManager.shared().delegate = self - - setupPiPManager() - } - - private func setupPiPManager() { // 初始化画中画管理器 - pipManager.setupPictureInPicture(sourceView: self.customView) + pipManager.setupPictureInPicture(sourceView: self.sourceView) // 监听画中画状态变化 NotificationCenter.default.addObserver( @@ -106,24 +98,11 @@ class SubTitleVC: UIViewController { object: nil ) } - - @objc func startRecord() { - JoyGemSubtitleManager.shared().start() - - guard AVPictureInPictureController.isPictureInPictureSupported() else { - print("设备不支持画中画") - return - } - - pipManager.startPictureInPicture() - } - - @objc func endRecord() { - JoyGemSubtitleManager.shared().stop() - - pipManager.stopPictureInPicture() + override func navRightViewTapped() { + let vc = SubTitleSetVC() + App.shared.goToPage(vc) } - + @objc private func pipStateChanged(_ notification: Notification) { if let userInfo = notification.userInfo, let isActive = userInfo["isActive"] as? Bool { @@ -132,21 +111,29 @@ class SubTitleVC: UIViewController { } } -// 实现委托方法 @available(iOS 15.0, *) -extension SubTitleVC: LanguagePickerView1Delegate { - - func languagePickerView(_ pickerView: LanguagePickerView1, - didSelectSourceLanguage source: LanguageModel, - targetLanguage target: LanguageModel) { - print("语言选择更新: \(source.nativeName) -> \(target.nativeName)") - // 更新你的翻译逻辑等 - JoyGemSubtitleManager.shared().originalLanguage = source.code - JoyGemSubtitleManager.shared().targetLanguage = target.code +extension SubTitleVC:RecordBarDelegate{ + func recordBarLanguageChange(_ bar: RecordBar) { + } - - func languagePickerViewDidTapSwap(_ pickerView: LanguagePickerView1) { - print("交换了语言") + func recordBar(_ bar: RecordBar, stateChange state: RecordBarSate) { + if state == .start { + JoyGemSubtitleManager.shared().originalLanguage = languageItem.leftLabel.language.value + JoyGemSubtitleManager.shared().targetLanguage = languageItem.rightLabel.language.value + JoyGemSubtitleManager.shared().start() + + guard AVPictureInPictureController.isPictureInPictureSupported() else { + print("设备不支持画中画") + return + } + + pipManager.startPictureInPicture() + } + else if state == .stop{ + JoyGemSubtitleManager.shared().stop() + + pipManager.stopPictureInPicture() + } } } diff --git a/ShenYin/ShenYin/UI/common/pop/LanguagePicker/LanguageSelectItem.swift b/ShenYin/ShenYin/UI/common/pop/LanguagePicker/LanguageSelectItem.swift index 2029b27..19aa902 100644 --- a/ShenYin/ShenYin/UI/common/pop/LanguagePicker/LanguageSelectItem.swift +++ b/ShenYin/ShenYin/UI/common/pop/LanguagePicker/LanguageSelectItem.swift @@ -10,6 +10,7 @@ class LanguageSelectItem: BaseView { let leftLabel = LanguageItem() let rightLabel = LanguageItem() let switcIcon = UIImageView() + var languageChange:((_ from:CCAiLanguage,_ to:CCAiLanguage)->Void)? override func setupViews() { addSubviews([bottonView]) @@ -61,6 +62,9 @@ class LanguageSelectItem: BaseView { let text2 = rightLabel.language leftLabel.language = text2 rightLabel.language = text1 + AiLanguageCache.save(type: .text_left, lan: leftLabel.language) + AiLanguageCache.save(type: .text_right, lan: rightLabel.language) + languageChange?(leftLabel.language,rightLabel.language) } @objc func leftAction(){ let v = LanguagePickerView(languages: CCAiLanguage.all,isLeft: true,left: leftLabel.language,right: rightLabel.language) @@ -76,6 +80,7 @@ class LanguageSelectItem: BaseView { } AiLanguageCache.save(type: .text_left, lan: leftLabel.language) AiLanguageCache.save(type: .text_right, lan: rightLabel.language) + languageChange?(leftLabel.language,rightLabel.language) } } @objc func rightAction(){ @@ -92,6 +97,7 @@ class LanguageSelectItem: BaseView { } AiLanguageCache.save(type: .text_left, lan: leftLabel.language) AiLanguageCache.save(type: .text_right, lan: rightLabel.language) + languageChange?(leftLabel.language,rightLabel.language) } } diff --git a/ShenYin/ShenYin/lan/CCAiSupportLanguage.swift b/ShenYin/ShenYin/lan/CCAiSupportLanguage.swift index 20848b0..f9f610e 100644 --- a/ShenYin/ShenYin/lan/CCAiSupportLanguage.swift +++ b/ShenYin/ShenYin/lan/CCAiSupportLanguage.swift @@ -6,8 +6,8 @@ // import Foundation - -enum CCAiLanguage:String{ +import HandyJSON +enum CCAiLanguage:String,HandyJSONEnum{ case chinse = "chinse" case english = "english" case japanese = "japanese" diff --git a/ShenYin/ShenYin/lan/chinese.swift b/ShenYin/ShenYin/lan/chinese.swift index 26c0210..7f29f2e 100644 --- a/ShenYin/ShenYin/lan/chinese.swift +++ b/ShenYin/ShenYin/lan/chinese.swift @@ -560,5 +560,7 @@ let chineseMap:[String:String] = "眼镜" : "", "录音结束后提示重命名":"", "关闭后自动命名并保存":"", + "字幕翻译":"", + "看视频,实时字幕翻译":"", ] diff --git a/ShenYin/ShenYin/playboy.xcassets/home/home_subtitle.imageset/Contents.json b/ShenYin/ShenYin/playboy.xcassets/home/home_subtitle.imageset/Contents.json new file mode 100644 index 0000000..55fecaf --- /dev/null +++ b/ShenYin/ShenYin/playboy.xcassets/home/home_subtitle.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "实时双语字幕@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "实时双语字幕@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git "a/ShenYin/ShenYin/playboy.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@2x.png" "b/ShenYin/ShenYin/playboy.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@2x.png" new file mode 100644 index 0000000..73782fe Binary files /dev/null and "b/ShenYin/ShenYin/playboy.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@2x.png" differ diff --git "a/ShenYin/ShenYin/playboy.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@3x.png" "b/ShenYin/ShenYin/playboy.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@3x.png" new file mode 100644 index 0000000..2a1bef9 Binary files /dev/null and "b/ShenYin/ShenYin/playboy.xcassets/home/home_subtitle.imageset/\345\256\236\346\227\266\345\217\214\350\257\255\345\255\227\345\271\225@3x.png" differ diff --git "a/document/\346\200\247\350\203\275\344\274\230\345\214\226.txt" "b/document/\346\200\247\350\203\275\344\274\230\345\214\226.txt" new file mode 100644 index 0000000..3751488 --- /dev/null +++ "b/document/\346\200\247\350\203\275\344\274\230\345\214\226.txt" @@ -0,0 +1,5 @@ +我项目中接入StarburstSdk.framework,在oc_StarburstSdk和code两个不同的项目中,代码一样的,但是调用StarburstSdk.framework接口消耗的资源差别很大。code的消耗cpu长期保持在5%左右,而oc_StarburstSdk消耗cpu长期保持在75%以上。两个项目的代码是一样的。我猜测是项目buildSetting的哪些配置不一样引起的,你帮我对比分析看是哪个设置可能影响到 + +code项目中有个StarburstSdk的target,该target生成StarburstSdk.framework,在code项目中运行的时候,消耗的cpu稳定在5%左右,但是将生成的framework嵌入到oc_StarburstSdk项目后,oc_StarburstSdk项目运行消耗的cpu稳定在75%,帮我分析code中的StarburstSdk的settings如何设置才能让生成的framework在其他项目中高效运行 + +http://vjs.zencdn.net/v/oceans.mp4 \ No newline at end of file