|  | @@ -0,0 +1,278 @@
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//  BFVoiceSettingView.swift
 | 
	
		
			
				|  |  | +//  BFRecordScreenKit
 | 
	
		
			
				|  |  | +//
 | 
	
		
			
				|  |  | +//  Created by ak on 2022/2/15.
 | 
	
		
			
				|  |  | +//  功能:发音人设置面板
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import Foundation
 | 
	
		
			
				|  |  | +import BFCommonKit
 | 
	
		
			
				|  |  | +import BFUIKit
 | 
	
		
			
				|  |  | +import BFMediaKit
 | 
	
		
			
				|  |  | +import UIKit
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// 操作动作类型
 | 
	
		
			
				|  |  | +public enum VoiceSettingActionType: Int {
 | 
	
		
			
				|  |  | +    case voiceSettingActionCancel = 1 // 取消
 | 
	
		
			
				|  |  | +    case voiceSettingActionDelete = 2 // 删除
 | 
	
		
			
				|  |  | +    case VoiceSettingActionConfirm = 3 // 确认
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class BFVoiceSettingView: UIView {
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    let itemSize = CGSize(width: adapterWidth(width: 52) + 9, height: 40)
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    //操作板背景
 | 
	
		
			
				|  |  | +    let backView = UIButton()
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    //保存所有发音人
 | 
	
		
			
				|  |  | +    public var voices: Dictionary = Dictionary<String, [PQVoiceModel]>.init(){
 | 
	
		
			
				|  |  | +        didSet {
 | 
	
		
			
				|  |  | +            voicesCollectView.reloadData()
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    //所有分类
 | 
	
		
			
				|  |  | +    public var categorys: Array = Array<BFVoiceCategoryModel>.init(){
 | 
	
		
			
				|  |  | +        didSet {
 | 
	
		
			
				|  |  | +            BFLog(message: "发音人分类数: \(categorys.count)")
 | 
	
		
			
				|  |  | +            curretnCategory = categorys.first
 | 
	
		
			
				|  |  | +            catagaryCollectView.reloadData()
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    //操作回调
 | 
	
		
			
				|  |  | +    public var voiceSettingCallBack: ((_ actionType: VoiceSettingActionType,_ selectVoice:PQVoiceModel?) -> Void)?
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    //当前选择的分类
 | 
	
		
			
				|  |  | +    var curretnCategory:BFVoiceCategoryModel?
 | 
	
		
			
				|  |  | +    //当前选择的发音人
 | 
	
		
			
				|  |  | +    var selectVoice:PQVoiceModel?
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    // 分类列表
 | 
	
		
			
				|  |  | +    lazy var catagaryCollectView: UICollectionView = {
 | 
	
		
			
				|  |  | +        let layout = UICollectionViewFlowLayout()
 | 
	
		
			
				|  |  | +        layout.scrollDirection = .horizontal
 | 
	
		
			
				|  |  | +        layout.itemSize = itemSize
 | 
	
		
			
				|  |  | +        layout.minimumLineSpacing = 10
 | 
	
		
			
				|  |  | +        layout.sectionInset = UIEdgeInsets.zero
 | 
	
		
			
				|  |  | +        layout.minimumInteritemSpacing = 0
 | 
	
		
			
				|  |  | +        let collectView = UICollectionView(frame: CGRect(x: 60, y: 0, width: cScreenWidth, height: 40), collectionViewLayout: layout)
 | 
	
		
			
				|  |  | +        collectView.isPagingEnabled = false
 | 
	
		
			
				|  |  | +        collectView.showsHorizontalScrollIndicator = false
 | 
	
		
			
				|  |  | +        collectView.showsVerticalScrollIndicator = false
 | 
	
		
			
				|  |  | +        collectView.register(BFVoiceCategoryCell.self, forCellWithReuseIdentifier: "BFVoiceCategoryCell")
 | 
	
		
			
				|  |  | +        collectView.backgroundColor = UIColor.clear
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        collectView.delegate = self
 | 
	
		
			
				|  |  | +        collectView.dataSource = self
 | 
	
		
			
				|  |  | +        if #available(iOS 11.0, *) {
 | 
	
		
			
				|  |  | +            collectView.contentInsetAdjustmentBehavior = .never
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            // Fallback on earlier versions
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        collectView.backgroundColor = .clear
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return collectView
 | 
	
		
			
				|  |  | +    }()
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    // 所有发音人列表
 | 
	
		
			
				|  |  | +    lazy var voicesCollectView: UICollectionView = {
 | 
	
		
			
				|  |  | +        let layout = UICollectionViewFlowLayout()
 | 
	
		
			
				|  |  | +        layout.scrollDirection = .vertical
 | 
	
		
			
				|  |  | +        layout.itemSize = CGSize(width: adapterWidth(width:60) , height: 78)
 | 
	
		
			
				|  |  | +        //每行最小边距
 | 
	
		
			
				|  |  | +        layout.minimumLineSpacing = 10
 | 
	
		
			
				|  |  | +        //每列最小边距
 | 
	
		
			
				|  |  | +        layout.minimumInteritemSpacing = 0
 | 
	
		
			
				|  |  | +        layout.sectionInset = UIEdgeInsets.zero
 | 
	
		
			
				|  |  | +     
 | 
	
		
			
				|  |  | +        let collectView = UICollectionView(frame: CGRect(x: 0, y: 98, width: cScreenWidth, height: 242 - cSafeAreaHeight), collectionViewLayout: layout)
 | 
	
		
			
				|  |  | +        collectView.isPagingEnabled = false
 | 
	
		
			
				|  |  | +        collectView.showsHorizontalScrollIndicator = false
 | 
	
		
			
				|  |  | +        collectView.showsVerticalScrollIndicator = false
 | 
	
		
			
				|  |  | +        collectView.register(PQVoiceCell.self, forCellWithReuseIdentifier: "PQVoiceCell")
 | 
	
		
			
				|  |  | +        collectView.backgroundColor = UIColor.clear
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        collectView.delegate = self
 | 
	
		
			
				|  |  | +        collectView.dataSource = self
 | 
	
		
			
				|  |  | +        if #available(iOS 11.0, *) {
 | 
	
		
			
				|  |  | +            collectView.contentInsetAdjustmentBehavior = .never
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            // Fallback on earlier versions
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return collectView
 | 
	
		
			
				|  |  | +    }()
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    required init?(coder _: NSCoder) {
 | 
	
		
			
				|  |  | +        fatalError("init(coder:) has not been implemented")
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    override func layoutSubviews() {
 | 
	
		
			
				|  |  | +        super.layoutSubviews()
 | 
	
		
			
				|  |  | +        self.backView.addCorner(roundingCorners: [.topLeft, .topRight], corner: 10)
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    override init(frame: CGRect) {
 | 
	
		
			
				|  |  | +        super.init(frame: frame)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        backgroundColor = UIColor.clear
 | 
	
		
			
				|  |  | +        let view = UIView.init(frame: frame)
 | 
	
		
			
				|  |  | +        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(hidden)))
 | 
	
		
			
				|  |  | +        addSubview(view)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        backView.backgroundColor = UIColor.hexColor(hexadecimal: "#121212")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        addSubview(backView)
 | 
	
		
			
				|  |  | +        backView.snp.makeConstraints { make in
 | 
	
		
			
				|  |  | +            make.right.equalTo(self.snp.right)
 | 
	
		
			
				|  |  | +            make.bottom.equalTo(self.snp.bottom)
 | 
	
		
			
				|  |  | +            make.width.equalTo(cScreenWidth)
 | 
	
		
			
				|  |  | +            make.height.equalTo(340)
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        backView.setNeedsUpdateConstraints()
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        //取消
 | 
	
		
			
				|  |  | +        let cancelBtn = UIButton()
 | 
	
		
			
				|  |  | +        cancelBtn.backgroundColor = .clear
 | 
	
		
			
				|  |  | +        cancelBtn.setTitle("取消", for: .normal)
 | 
	
		
			
				|  |  | +        cancelBtn.setTitleColor(.white, for: .normal)
 | 
	
		
			
				|  |  | +        cancelBtn.titleLabel?.font = UIFont.boldSystemFont(ofSize: 17)
 | 
	
		
			
				|  |  | +        cancelBtn.addTarget(self, action: #selector(cancelAction), for: .touchUpInside)
 | 
	
		
			
				|  |  | +        backView.addSubview(cancelBtn)
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        cancelBtn.snp.makeConstraints { make in
 | 
	
		
			
				|  |  | +            make.left.equalToSuperview().offset(18)
 | 
	
		
			
				|  |  | +            make.width.equalTo(35)
 | 
	
		
			
				|  |  | +            make.height.equalTo(24)
 | 
	
		
			
				|  |  | +            make.top.equalToSuperview().offset(18)
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        //确认
 | 
	
		
			
				|  |  | +        let okBtn = UIButton()
 | 
	
		
			
				|  |  | +        okBtn.backgroundColor = .clear
 | 
	
		
			
				|  |  | +        okBtn.setTitle("确认", for: .normal)
 | 
	
		
			
				|  |  | +        okBtn.setTitleColor(UIColor.hexColor(hexadecimal: "#389AFF"), for: .normal)
 | 
	
		
			
				|  |  | +        okBtn.titleLabel?.font = UIFont.systemFont(ofSize: 17)
 | 
	
		
			
				|  |  | +        okBtn.addTarget(self, action: #selector(okBtnAction), for: .touchUpInside)
 | 
	
		
			
				|  |  | +        backView.addSubview(okBtn)
 | 
	
		
			
				|  |  | +        okBtn.snp.makeConstraints { make in
 | 
	
		
			
				|  |  | +            make.right.equalToSuperview().offset(-18)
 | 
	
		
			
				|  |  | +            make.width.equalTo(35)
 | 
	
		
			
				|  |  | +            make.height.equalTo(24)
 | 
	
		
			
				|  |  | +            make.top.equalToSuperview().offset(18)
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        //删除发音设置
 | 
	
		
			
				|  |  | +        let catagaryBackView = UIView.init()
 | 
	
		
			
				|  |  | +        catagaryBackView.backgroundColor = UIColor.hexColor(hexadecimal: "#0B0B0B")
 | 
	
		
			
				|  |  | +        backView.addSubview(catagaryBackView)
 | 
	
		
			
				|  |  | +        catagaryBackView.snp.makeConstraints { make in
 | 
	
		
			
				|  |  | +            make.right.equalToSuperview()
 | 
	
		
			
				|  |  | +            make.width.equalTo(cScreenWidth)
 | 
	
		
			
				|  |  | +            make.height.equalTo(40)
 | 
	
		
			
				|  |  | +            make.top.equalToSuperview().offset(58)
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        catagaryBackView.addSubview(catagaryCollectView)
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        let deleteBtn = UIButton()
 | 
	
		
			
				|  |  | +        deleteBtn.backgroundColor = .clear
 | 
	
		
			
				|  |  | +        deleteBtn.setTitleColor(.white, for: .normal)
 | 
	
		
			
				|  |  | +        deleteBtn.titleLabel?.font = UIFont.systemFont(ofSize: 16)
 | 
	
		
			
				|  |  | +        deleteBtn.addTarget(self, action: #selector(deleteBtnAction), for: .touchUpInside)
 | 
	
		
			
				|  |  | +        catagaryBackView.addSubview(deleteBtn)
 | 
	
		
			
				|  |  | +        deleteBtn.setBackgroundImage(imageInRecordScreenKit(by: "voiceDelete"), for: .normal)
 | 
	
		
			
				|  |  | +        deleteBtn.snp.makeConstraints { make in
 | 
	
		
			
				|  |  | +            make.left.equalToSuperview().offset(16)
 | 
	
		
			
				|  |  | +            make.width.equalTo(24)
 | 
	
		
			
				|  |  | +            make.height.equalTo(24)
 | 
	
		
			
				|  |  | +            make.top.equalTo(cancelBtn.bottomY).offset(8)
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +  
 | 
	
		
			
				|  |  | +        backView.addSubview(voicesCollectView)
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    @objc func hidden() {
 | 
	
		
			
				|  |  | +        isHidden = true
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    @objc func cancelAction(){
 | 
	
		
			
				|  |  | +        if(voiceSettingCallBack != nil){
 | 
	
		
			
				|  |  | +            voiceSettingCallBack!(.voiceSettingActionCancel,selectVoice)
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    @objc func okBtnAction(){
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        if(voiceSettingCallBack != nil){
 | 
	
		
			
				|  |  | +            voiceSettingCallBack!(.VoiceSettingActionConfirm,selectVoice)
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    @objc func deleteBtnAction(){
 | 
	
		
			
				|  |  | +        if(voiceSettingCallBack != nil){
 | 
	
		
			
				|  |  | +            voiceSettingCallBack!(.voiceSettingActionDelete,selectVoice)
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +extension BFVoiceSettingView: UICollectionViewDelegate, UICollectionViewDataSource, UIScrollViewDelegate, UICollectionViewDelegateFlowLayout {
 | 
	
		
			
				|  |  | +    func collectionView(_ collectionView: UICollectionView,
 | 
	
		
			
				|  |  | +                        layout _: UICollectionViewLayout,
 | 
	
		
			
				|  |  | +                        sizeForItemAt indexPath: IndexPath) -> CGSize
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +      
 | 
	
		
			
				|  |  | +        if(collectionView == catagaryCollectView){
 | 
	
		
			
				|  |  | +            return CGSize(width: adapterWidth(width: 52) + 9, height: 40)
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return CGSize(width: adapterWidth(width:60) , height: 78)
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection _: Int) -> Int {
 | 
	
		
			
				|  |  | +   
 | 
	
		
			
				|  |  | +        if collectionView == catagaryCollectView {
 | 
	
		
			
				|  |  | +            return categorys.count
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return voices[curretnCategory?.cateName ?? ""]?.count ?? 0
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
 | 
	
		
			
				|  |  | + 
 | 
	
		
			
				|  |  | +        if collectionView == catagaryCollectView {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            let cell = BFVoiceCategoryCell.setCategory(collectionView: collectionView, indexPath: indexPath)
 | 
	
		
			
				|  |  | + 
 | 
	
		
			
				|  |  | +            cell.category = categorys[indexPath.item]
 | 
	
		
			
				|  |  | +            return cell
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        let cell = PQVoiceCell.voiceList(collectionView: collectionView, indexPath: indexPath)
 | 
	
		
			
				|  |  | +        let model = voices[curretnCategory?.cateName ?? ""]?[indexPath.item]
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        cell.voice = model
 | 
	
		
			
				|  |  | +        return cell
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
 | 
	
		
			
				|  |  | +     
 | 
	
		
			
				|  |  | +        if collectionView == catagaryCollectView {
 | 
	
		
			
				|  |  | +            BFLog(message: "===开始点击\(curretnCategory?.cateName ?? "")")
 | 
	
		
			
				|  |  | +            curretnCategory?.isSelected = false
 | 
	
		
			
				|  |  | +            curretnCategory = categorys[indexPath.item]
 | 
	
		
			
				|  |  | +            curretnCategory?.isSelected = true
 | 
	
		
			
				|  |  | +            catagaryCollectView.reloadData()
 | 
	
		
			
				|  |  | +          
 | 
	
		
			
				|  |  | +            voicesCollectView.reloadData()
 | 
	
		
			
				|  |  | +        }else{
 | 
	
		
			
				|  |  | +            selectVoice = voices[curretnCategory?.cateName ?? ""]?[indexPath.item]
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +   
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 |