CNLiveShopGoodsDetailsViewController.swift 16.3 KB
//
//  CNLiveShopGoodsDetailsViewController.swift
//  metaCode
//
//  Created by zx on 2023/11/20.
//

import Foundation
import YYImage
import YYWebImage
import SKPhotoBrowser
import CNLiveShareToolKit
import BKCycleScrollView

///分类类型
enum CNLiveShopGoodsDetailsVCType:Int {
    ///正常
    case normal
    ///预览
    case preview
}

class CNLiveShopGoodsDetailsViewController:CNLiveBaseViewController,UITableViewDelegate,UITableViewDataSource, BKCycleScrollViewDelegate{
    
    let kDSGoodsDetailsTableViewCellID = "DSGoodsDetailsTableViewCell"
    let kDSPlayerAnimateTimeInterval:CGFloat = 0.25
    /// 格式
    var type:CNLiveShopGoodsDetailsVCType?
    /// 商品id
    var goodsId:String?
    /// 编辑商品预览使用
    var detailsModel:CNLiveShopGoodsDetailsModel?
    
    var leftCircleBgView:CNLiveRoundedRectView?
    var leftImageView:YYAnimatedImageView?
    var shareCircleBgView:CNLiveRoundedRectView?
    var shareImageView:YYAnimatedImageView?

    var CSV_playerView:CNLivePlayerView?
    
    weak var cycleScrollView :BKCycleScrollView? = {
        let cycleScrollView = BKCycleScrollView()
        return cycleScrollView
    }()
    
    lazy var tableView : UITableView = {
        let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: KSreenWidth, height: self.view.height), style: .plain)
        tableView.dataSource = self
        tableView.delegate = self
        tableView.separatorStyle = .none
        tableView.tableFooterView = UIView.init()
        tableView.backgroundColor = HexColor("#f1f2f6")
        tableView.register(CNLiveGoodsDetailsTableViewCell.self, forCellReuseIdentifier: kDSGoodsDetailsTableViewCellID)
        return tableView
    }()
        
    //图片集合
    lazy var imgs :NSMutableArray = {
        let imgs = NSMutableArray()
        return imgs
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.initNav()
        self.view.insertSubview(self.tableView, belowSubview: self.topNavView)
        navigationBarHidden = false
        if self.type == .preview{
            self.insertData()
        }else{
            self.requestGoodsInfo()
        }
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        self.tableView.frame = CGRect(x: 0, y: 0, width: self.view.width, height: self.view.height)
    }
    
    var isPrefersStatusBarHidden:Bool = false
    override var prefersStatusBarHidden: Bool {
        return self.isPrefersStatusBarHidden
    }
    
    deinit {
        if (self.cycleScrollView != nil){
            self.cycleScrollView = nil
        }
        self.destroyPlayerView()
    }
    
    func initNav(){
        self.topNavView.backgroundColor = UIColor(white: 1, alpha: 0)
        self.topLine.alpha = 0
        self.leftNavBtns.forEach { $0.removeFromSuperview() }
        
        let backNavBtn = UIButton(type: .custom)
        backNavBtn.frame = CGRect(x: 0, y: get_system_statusBar_height(), width: get_system_nav_ui_height(), height: get_system_nav_ui_height())
        backNavBtn.addTarget(self, action: #selector(backNavBtnClick), for: .touchUpInside)
        self.topNavView.addSubview(backNavBtn)
        
        self.leftCircleBgView = CNLiveRoundedRectView(frame: CGRect(x: 15, y: (backNavBtn.height - 32)/2, width: 32, height: 32))
        self.leftCircleBgView?.fillColor = HexColor("#848484", alpha: 0.45)
        self.leftCircleBgView?.radius = self.leftCircleBgView!.height/2
        self.leftCircleBgView?.isUserInteractionEnabled = false
        backNavBtn.addSubview(self.leftCircleBgView!)
        
        let wLeftImageView = YYAnimatedImageView(frame: CGRect(x: 15, y: (backNavBtn.height - 32)/2, width: 32, height: 32))
        wLeftImageView.clipsToBounds = true
        wLeftImageView.contentMode = .scaleAspectFit
        wLeftImageView.image = UIImage(named: "DS_goods_back_g")
        backNavBtn.addSubview(wLeftImageView)
        
        self.leftImageView = YYAnimatedImageView(frame: CGRect(x: 15, y: (backNavBtn.height - 32)/2, width: 32, height: 32))
        self.leftImageView?.clipsToBounds = true
        self.leftImageView?.contentMode = .scaleAspectFit
        self.leftImageView?.image = UIImage(named: "DS_goods_back_g")
        self.leftImageView?.alpha = 0
        backNavBtn.addSubview(self.leftImageView!)

        if self.goodsId?.count ?? 0 > 0{
            let shareNavBtn = UIButton(type: .custom)
            shareNavBtn.frame = CGRect(x: KSreenWidth-62, y: get_system_statusBar_height(), width: get_system_nav_ui_height(), height: get_system_nav_ui_height())
            shareNavBtn.addTarget(self, action: #selector(shareNavBtnClick), for: .touchUpInside)
            self.topNavView.addSubview(shareNavBtn)
            
            self.shareCircleBgView = CNLiveRoundedRectView(frame: CGRect(x: 15, y: (shareNavBtn.height - 32)/2, width: 32, height: 32))
            self.shareCircleBgView?.fillColor = HexColor("#848484", alpha: 0.45)
            self.shareCircleBgView?.radius = self.shareCircleBgView!.height/2
            self.shareCircleBgView?.isUserInteractionEnabled = false
            shareNavBtn.addSubview(self.shareCircleBgView!)
            
            let wShareImageView =  YYAnimatedImageView(frame: CGRect(x: 15, y: (shareNavBtn.height - 32), width: 32, height: 32))
            wShareImageView.clipsToBounds = true
            wShareImageView.contentMode = .scaleAspectFit
            wShareImageView.image = UIImage(named: "DS_goods_share_g")
            wShareImageView.alpha = 0
            shareNavBtn.addSubview(wShareImageView)
            
            self.shareImageView =  YYAnimatedImageView(frame: CGRect(x: 15, y: (shareNavBtn.height - 32), width: 32, height: 32))
            self.shareImageView?.clipsToBounds = true
            self.shareImageView?.contentMode = .scaleAspectFit
            self.shareImageView?.image = UIImage(named: "DS_goods_share_g")
            self.shareImageView?.alpha = 0
            shareNavBtn.addSubview(self.shareImageView!)
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.detailsModel?.detail_img.count ?? 0
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let detailsContentModel = self.detailsModel?.detail_img[indexPath.row]
        if detailsContentModel?.w ?? 0 > 0{
            return floor(self.view.width / (detailsContentModel?.w ?? 0) * (detailsContentModel?.h ?? 0))
        }else{
            return 200
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: kDSGoodsDetailsTableViewCellID) as! CNLiveGoodsDetailsTableViewCell
        let detailsContentModel = self.detailsModel?.detail_img[indexPath.row]
        
        var escapedUrl = detailsContentModel?.simg?.removingPercentEncoding
        escapedUrl = escapedUrl?.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
        cell.displayImageView?.yy_setImage(with: URL(string: escapedUrl!), placeholder: nil, options: [.showNetworkActivity , .setImageWithFadeAnimation], completion: { image, url, from, stage, error in

            if (image == nil) {
                return
            }
            if (image!.size.height == detailsContentModel?.h) {
                return
            }
            detailsContentModel?.w = image!.size.width
            detailsContentModel?.h = image!.size.height
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        })
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let browser = SKPhotoBrowser(photos: self.imgs as! [SKPhotoProtocol])
        browser.initializePageIndex(indexPath.row)
        currentViewController()?.present(browser, animated: true)
    }
    
    // MARK: - UIScrollViewDelegate
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if self.tableView == scrollView{

            if self.tableView.contentOffset.y < 0{
                self.topNavView.backgroundColor = UIColor(white: 1, alpha: 0)
                self.leftCircleBgView?.alpha = 1
                self.leftImageView?.alpha = 0
                
                self.shareCircleBgView?.alpha = 1
                self.shareImageView?.alpha = 0
                self.topLine.alpha = 0
            }else if self.tableView.contentOffset.y >= 128{
                self.topNavView.backgroundColor = UIColor(white: 1, alpha: 1)
                self.leftCircleBgView?.alpha = 0
                self.leftImageView?.alpha = 1
                
                self.shareCircleBgView?.alpha = 0
                self.shareImageView?.alpha = 1
                self.topLine.alpha = 1
            }else{
                let indexAlpha = self.tableView.contentOffset.y/128.0
                self.leftCircleBgView?.alpha = 1 - indexAlpha
                self.leftImageView?.alpha = indexAlpha
                self.shareCircleBgView?.alpha = 1 - indexAlpha
                self.shareImageView?.alpha = indexAlpha
                self.topLine.alpha = indexAlpha
                self.topNavView.backgroundColor = UIColor(white: 1, alpha: indexAlpha)
            }
        }
    }
    
    // MARK: - 获取商品详情
    func requestGoodsInfo(){
        showLoading(message: "")
        CNLiveShopGoodListViewModel.getGoodsInfoWithGoodsId(goodsId: self.goodsId ?? "") { result, status in
            hiddenLoading()
            if status == .failed{
                showMessage(message: "获取失败")
                return
            }
            if status == .success{
                let model = result as! CNLiveShopGoodsDetailsModel
                self.detailsModel = model
                self.insertData()
            }
        }
    }

    func insertData(){
        var headerView:CNLiveShopGoodsDetailsTableHeaderView?
        if self.tableView.tableHeaderView == nil{
            headerView = CNLiveShopGoodsDetailsTableHeaderView(frame: CGRect(x: 0, y: 0, width: KSreenWidth, height: 0))
            headerView!.bannerView.delegate = self
            headerView!.clickGiveGiftBlock = {
                
            }
        }else{
            headerView = self.tableView.tableHeaderView as? CNLiveShopGoodsDetailsTableHeaderView
        }
        headerView!.detailsModel = self.detailsModel
        self.tableView.tableHeaderView = headerView
        self.tableView.reloadData()
        self.tableView.setContentOffset(CGPointZero, animated: true)
        for model in self.detailsModel!.detail_img {
            let photo = SKPhoto.photoWithImageURL(model.simg ?? "")
            photo.shouldCachePhotoURLImage = false
            photo.photoURL = model.simg
            self.imgs.add(photo)
        }
    }
    
    // MARK: - 销毁播放器
    func destroyPlayerView(){
        self.CSV_playerView?.stop()
        if self.CSV_playerView?.currentOrientation != .portrait{
            self.CSV_playerView?.currentOrientation = .portrait
        }
        self.CSV_playerView?.superview?.removeFromSuperview()
        self.CSV_playerView?.removeFromSuperview()
        self.CSV_playerView = nil
    }

    // MARK: - BKCycleScrollViewDelegate
    func cycleScrollView(_ cycleScrollView: BKCycleScrollView, play playIndex: UInt, superView: UIView) {
        let dataModel = cycleScrollView.displayDataArr![Int(playIndex)] as BKCycleScrollDataModel
        if (self.CSV_playerView == nil){
            let playerView = CNLivePlayerView()
            self.CSV_playerView = playerView
            if dataModel.imageUrl.count > 0{
                self.CSV_playerView?.controlView.coverImageUrl = dataModel.imageUrl
            }else if dataModel.image.size != CGSizeZero{
                self.CSV_playerView?.controlView.coverImage = dataModel.image
            }
            self.CSV_playerView?.controlView.fullScreenType = .inWindowOrientation
            self.CSV_playerView?.controlView.topNaviView?.backBtn?.isHidden = true
            self.CSV_playerView?.isMonitorDeviceOrientation = false
            self.CSV_playerView?.controlView.gestureView?.panGestureRecognizer?.isEnabled = false
            self.CSV_playerView?.controlView.coverImageViewContentMode = .scaleAspectFill
            self.CSV_playerView?.switchInterfaceOrientationCallBack = { playerView in
                if playerView.controlView.isFullScreen!{
                    playerView.controlView.bottomProgressView?.isHidden = true
                }else{
                    playerView.controlView.bottomProgressView?.isHidden = false
                }
                if #available(iOS 11.0, *) {
                    self.setNeedsUpdateOfHomeIndicatorAutoHidden()
                } else {
                    
                }
                UIView.animate(withDuration: self.kDSPlayerAnimateTimeInterval) {
                    //iPhoneX系列在横屏时隐藏状态栏
                    if playerView.controlView.isAlphaMessage == false{
                        if (isiPhoneXSeries || Double(UIDevice.current.systemVersion) ?? 0 >= 13) && (playerView.controlView.isFullScreen != nil) {
                            self.isPrefersStatusBarHidden = true
                        }else{
                            self.isPrefersStatusBarHidden = false
                        }
                        self.setNeedsStatusBarAppearanceUpdate()
                    }
                    if playerView.controlView.isFullScreen ?? false{
                        playerView.isMonitorDeviceOrientation = true
                    }else{
                        playerView.isMonitorDeviceOrientation = false
                    }
                }
                if playerView.currentOrientation == .portrait{
                    playerView.controlView.gestureView?.panGestureRecognizer?.isEnabled = false
                }else{
                    if playerView.controlView.isLockScreen{
                        playerView.controlView.gestureView?.panGestureRecognizer?.isEnabled = false
                    }else{
                        playerView.controlView.gestureView?.panGestureRecognizer?.isEnabled = true
                    }
                }
            }
            self.CSV_playerView?.playerPlayingCallBack = {
                playerView in
                self.cycleScrollView?.playVideo()
            }
            self.CSV_playerView?.playerPausedCallBack = {
                playerView in
                self.cycleScrollView?.pauseVideo()
            }
            self.CSV_playerView?.playerDidToEndCallBack = {
                playerView in
                self.cycleScrollView?.stopVideo()
                self.destroyPlayerView()
            }
        }
        superView.addSubview(self.CSV_playerView!)
        self.CSV_playerView!.frame = superView.bounds
        let model = cycleScrollView.displayDataArr?[Int(playIndex)]
        self.CSV_playerView?.setPlayUrl(playUrl: URL(string: model?.videoUrl ?? "") ?? URL(fileURLWithPath: ""), isLive: false)
        self.CSV_playerView?.play()
    }
    
    func cycleScrollView(_ cycleScrollView: BKCycleScrollView, pause pauseIndex: UInt) {
        self.CSV_playerView?.pauseWithIsRemoveKVOsAndNotifications(isRemove: false)
    }
    
    func cycleScrollView(_ cycleScrollView: BKCycleScrollView, stop stopIndex: UInt) {
        self.destroyPlayerView()
    }
        
    // MARK: - BtnAction
    @objc func backNavBtnClick(){
        self.navigationController?.popViewController(animated: true)
    }

    @objc func shareNavBtnClick(){
        CNLiveShopGoodListViewModel.postGetShareDataWithType(type: 2, targetId: self.goodsId!, ext: "") {[weak self] result, status in
            let model = result as! CNLiveShopCommentRequestShareModel
            CNLiveShareManager.showShareViewWithParam(forShareTitle: model.share_title, shareUrl: model.url, shareDesc: model.share_desc, shareImage: model.share_img, screenFull: false, hiddenWjj: true, hiddenQQ: false, hiddenWB: true, hiddenLifeCircle: true, hiddenWechatCircle: false, hiddenWechat: false, hiddenSafari: false, formVC: self, topImage: nil, topTitles: nil, platformType: .all) { str in
                
            } completerBlock: { resultType, platformType, typtString in
                if (resultType == .succ) {
                    showMessage(message: "分享成功")
                }
                if (resultType == .fail) {
                    showMessage(message: "分享失败")
                }
            }
        }
    }
}