// // SPPlayerDetailRecommandView.swift // MoviaBox // // Created by 佳尔 on 2025/5/12. // import UIKit class SPPlayerDetailRecommandView: HWPanModalContentView { private lazy var dataArr: [SPShortModel] = [] var clickCloseButton: (() -> Void)? var clickPlayButton: ((_ model: SPShortModel) -> Void)? //MARK: UI属性 private lazy var bgImageView: UIImageView = { let imageView = UIImageView(image: UIImage(named: "recommand_bg_image_01")) return imageView }() private lazy var titleLabel: UILabel = { let label = UILabel() label.font = .fontMedium(ofSize: 20) label.textColor = .colorFFFFFF() label.text = "movia_top_today".localized return label }() private lazy var closeButton: UIButton = { let button = UIButton(type: .custom) button.setImage(UIImage(named: "close_icon_01"), for: .normal) button.addTarget(self, action: #selector(handleCloseButton), for: .touchUpInside) return button }() private lazy var bannerView: ZKCycleScrollView = { let view = ZKCycleScrollView(frame: .zero, shouldInfiniteLoop: true) view.delegate = self view.dataSource = self view.itemSize = CGSize(width: 231, height: 322) view.itemZoomScale = 0.8 view.itemSpacing = 0 view.register(SPPlayerDetailRecommandCell.self, forCellWithReuseIdentifier: "cell") view.hidesPageControl = true return view }() private lazy var videoNameLabel: UILabel = { let label = UILabel() label.font = .fontRegular(ofSize: 18) label.textColor = .colorFFFFFF(alpha: 0.8) label.textAlignment = .center label.numberOfLines = 2 return label }() private lazy var playButton: UIButton = { let button = UIButton(type: .custom) button.setTitle("movia_play_now".localized, for: .normal) button.setTitleColor(.color622100(), for: .normal) button.titleLabel?.font = .fontMedium(ofSize: 18) button.layer.cornerRadius = 8 button.layer.masksToBounds = true button.setBackgroundImage(UIImage(color: .colorFFC555()), for: .normal) button.addTarget(self, action: #selector(handlePlayButton), for: .touchUpInside) return button }() override init(frame: CGRect) { super.init(frame: frame) _setupUI() requestDataArr() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } //MARK: HWPanModalPresentable override func longFormHeight() -> PanModalHeight { return PanModalHeightMake(.content, 540) } override func showDragIndicator() -> Bool { return false } override func backgroundConfig() -> HWBackgroundConfig { let config = HWBackgroundConfig() config.backgroundAlpha = 0.6 return config } override func allowsTapBackgroundToDismiss() -> Bool { return false } override func allowsDragToDismiss() -> Bool { return false } override func allowsPullDownWhenShortState() -> Bool { return false } } extension SPPlayerDetailRecommandView { @objc private func handleCloseButton() { self.dismiss(animated: true) { } self.clickCloseButton?() } @objc private func handlePlayButton() { guard self.dataArr.count > 0 else { return } self.dismiss(animated: true) { } let model = self.dataArr[bannerView.currentIdx] self.clickPlayButton?(model) } } extension SPPlayerDetailRecommandView { private func _setupUI() { addSubview(bgImageView) addSubview(titleLabel) addSubview(closeButton) addSubview(bannerView) addSubview(videoNameLabel) addSubview(playButton) bgImageView.snp.makeConstraints { make in make.edges.equalToSuperview() } titleLabel.snp.makeConstraints { make in make.centerX.equalToSuperview() make.top.equalToSuperview().offset(27) } closeButton.snp.makeConstraints { make in make.right.equalToSuperview().offset(-16) make.centerY.equalTo(titleLabel) } bannerView.snp.makeConstraints { make in make.left.right.equalToSuperview() make.top.equalToSuperview().offset(78) make.height.equalTo(322) } videoNameLabel.snp.makeConstraints { make in make.centerX.equalToSuperview() make.top.equalTo(bannerView.snp.bottom).offset(15) make.width.lessThanOrEqualTo(260) } playButton.snp.makeConstraints { make in make.left.equalToSuperview().offset(16) make.centerX.equalToSuperview() make.top.equalTo(bannerView.snp.bottom).offset(81) make.height.equalTo(46) } } } //MARK: -------------- ZKCycleScrollViewDelegate & ZKCycleScrollViewDataSource -------------- extension SPPlayerDetailRecommandView: ZKCycleScrollViewDelegate, ZKCycleScrollViewDataSource { func numberOfItems(in cycleScrollView: ZKCycleScrollView) -> Int { return self.dataArr.count } func cycleScrollView(_ cycleScrollView: ZKCycleScrollView, cellForItemAt index: Int) -> ZKCycleScrollViewCell { let cell = cycleScrollView.dequeueReusableCell(withReuseIdentifier: "cell", for: index) as! SPPlayerDetailRecommandCell cell.model = self.dataArr[index] return cell } func cycleScrollView(_ cycleScrollView: ZKCycleScrollView, didScrollFromIndex fromIndex: Int, toIndex: Int) { let model = self.dataArr[toIndex] videoNameLabel.text = model.name } } extension SPPlayerDetailRecommandView { private func requestDataArr() { SPVideoAPI.requestPlayerDetailsRecommand { [weak self] list in guard let self = self else { return } if let list = list { self.dataArr = list let model = self.dataArr.first self.videoNameLabel.text = model?.name self.bannerView.reloadData() } } } }