187 lines
5.7 KiB
Swift
187 lines
5.7 KiB
Swift
|
|
//
|
|||
|
|
// EncounterAICardView.swift
|
|||
|
|
// Crush
|
|||
|
|
//
|
|||
|
|
// Created by Leon on 2025/9/10.
|
|||
|
|
//
|
|||
|
|
|
|||
|
|
import UIKit
|
|||
|
|
import Combine
|
|||
|
|
|
|||
|
|
protocol EncounterAICardViewDelegate: AnyObject{
|
|||
|
|
func cardViewTapLike(_ obj: MeetCard?)
|
|||
|
|
func cardViewTapGift(_ obj: MeetCard?)
|
|||
|
|
func cardViewTapDislike(_ obj: MeetCard?)
|
|||
|
|
func cardViewTapHeader(_ obj: MeetCard?, cardView: EncounterAICardView?)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class EncounterAICardView: MeetDragCardView {
|
|||
|
|
|
|||
|
|
static let cardWidth = UIScreen.width - 12 * 2.0
|
|||
|
|
static let cardHeight = UIScreen.height - UIWindow.tabBarTotalHeight - UIWindow.navBarTotalHeight - 12 - 12
|
|||
|
|
|
|||
|
|
var scrollContainer: LTScrollContainer!
|
|||
|
|
var indicator: PageIndicatorView!
|
|||
|
|
|
|||
|
|
var header: EncounterAICardHeader!
|
|||
|
|
var albumView: EncounterAICardAlbumView!
|
|||
|
|
|
|||
|
|
weak var delegate : EncounterAICardViewDelegate?
|
|||
|
|
|
|||
|
|
var card: MeetCard?
|
|||
|
|
|
|||
|
|
// Flag
|
|||
|
|
var isPullingToAIHomePage = false
|
|||
|
|
|
|||
|
|
private var cancellables = Set<AnyCancellable>()
|
|||
|
|
|
|||
|
|
override init(frame: CGRect) {
|
|||
|
|
super.init(frame: frame)
|
|||
|
|
setupViews()
|
|||
|
|
setupData()
|
|||
|
|
setupEvent()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
required init?(coder: NSCoder) {
|
|||
|
|
fatalError("init(coder:) has not been implemented")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private func setupViews() {
|
|||
|
|
backgroundColor = .c.cbd
|
|||
|
|
|
|||
|
|
scrollContainer = {
|
|||
|
|
let v = LTScrollContainer()
|
|||
|
|
v.scrollView.delegate = self
|
|||
|
|
v.scrollView.bounces = true
|
|||
|
|
v.scrollView.showsVerticalScrollIndicator = false
|
|||
|
|
addSubview(v)
|
|||
|
|
v.snp.makeConstraints { make in
|
|||
|
|
make.edges.equalToSuperview()
|
|||
|
|
}
|
|||
|
|
return v
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
indicator = {
|
|||
|
|
let v = PageIndicatorView()
|
|||
|
|
addSubview(v)
|
|||
|
|
v.snp.makeConstraints { make in
|
|||
|
|
make.centerY.equalToSuperview()
|
|||
|
|
make.trailing.equalToSuperview().offset(-4)
|
|||
|
|
}
|
|||
|
|
return v
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
header = {
|
|||
|
|
let v = EncounterAICardHeader()
|
|||
|
|
scrollContainer.stack.addArrangedSubview(v)
|
|||
|
|
v.snp.makeConstraints { make in
|
|||
|
|
make.leading.trailing.equalToSuperview()
|
|||
|
|
}
|
|||
|
|
return v
|
|||
|
|
}()
|
|||
|
|
|
|||
|
|
albumView = {
|
|||
|
|
let v = EncounterAICardAlbumView()
|
|||
|
|
scrollContainer.stack.addArrangedSubview(v)
|
|||
|
|
v.snp.makeConstraints { make in
|
|||
|
|
make.leading.trailing.equalToSuperview()
|
|||
|
|
}
|
|||
|
|
return v
|
|||
|
|
}()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private func setupData(){
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private func setupEvent(){
|
|||
|
|
header.dislikeButton.addTarget(self, action: #selector(tapDislikeButton), for: .touchUpInside)
|
|||
|
|
header.likeButton.addTarget(self, action: #selector(tapLikeButton), for: .touchUpInside)
|
|||
|
|
header.giftButton.addTarget(self, action: #selector(tapGiftButton), for: .touchUpInside)
|
|||
|
|
header.imageBgButton.addTarget(self, action: #selector(tapImageBgButton), for: .touchUpInside)
|
|||
|
|
header.overlayBgButton.addTarget(self, action: #selector(tapImageBgButton), for: .touchUpInside)
|
|||
|
|
|
|||
|
|
PhotosViewModel.shared.$album.sink {[weak self] photo in
|
|||
|
|
guard let self = self else{return}
|
|||
|
|
guard let album = photo , let albumId = photo?.albumId else {return}
|
|||
|
|
|
|||
|
|
let albumList = self.card?.albumList ?? []
|
|||
|
|
for per in albumList{
|
|||
|
|
let perAlbum = per
|
|||
|
|
if albumId == perAlbum.albumId{
|
|||
|
|
perAlbum.updateFrom(album)
|
|||
|
|
self.albumView.config(albumList)
|
|||
|
|
break
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}.store(in: &cancellables)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// MARK: - Public
|
|||
|
|
|
|||
|
|
func config(_ data: MeetCard?){
|
|||
|
|
self.card = data
|
|||
|
|
guard let card = data else { return }
|
|||
|
|
|
|||
|
|
// 配置Header数据
|
|||
|
|
header.config(card)
|
|||
|
|
|
|||
|
|
// 配置相册数据
|
|||
|
|
albumView.configCard(card: card)
|
|||
|
|
albumView.config(card.albumList ?? [])
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// MARK: - Action
|
|||
|
|
|
|||
|
|
@objc func tapDislikeButton(){
|
|||
|
|
delegate?.cardViewTapDislike(card)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@objc func tapLikeButton(){
|
|||
|
|
delegate?.cardViewTapLike(card)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@objc func tapGiftButton(){
|
|||
|
|
delegate?.cardViewTapGift(card)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@objc func tapImageBgButton(){
|
|||
|
|
delegate?.cardViewTapHeader(card, cardView: self)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
extension EncounterAICardView: UIScrollViewDelegate{
|
|||
|
|
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
|||
|
|
// 计算滚动进度 (0.0 到 1.0)
|
|||
|
|
let maxOffset = scrollView.contentSize.height - scrollView.bounds.size.height
|
|||
|
|
let progress = maxOffset > 0 ? scrollView.contentOffset.y / maxOffset : 0
|
|||
|
|
//dlog("progress:\(progress)")
|
|||
|
|
// 更新指示器
|
|||
|
|
//indicator.updateIndicator(progress: progress)
|
|||
|
|
indicator.updateIndicator(top: progress >= 0.5)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
|
|||
|
|
let offsetY = scrollView.contentOffset.y
|
|||
|
|
let contentHeight = scrollView.contentSize.height
|
|||
|
|
let height = scrollView.frame.size.height
|
|||
|
|
|
|||
|
|
if offsetY > contentHeight - height + 40 {
|
|||
|
|
|
|||
|
|
guard let aiId = card?.aiId else{return}
|
|||
|
|
//print("松手时,滑到底部之外了")
|
|||
|
|
if isPullingToAIHomePage == false{
|
|||
|
|
CLTool.feedbackGenerator()
|
|||
|
|
AppRouter.goAIRoleHome(aiId: aiId)
|
|||
|
|
|
|||
|
|
isPullingToAIHomePage = true
|
|||
|
|
}
|
|||
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {[weak self] in
|
|||
|
|
self?.isPullingToAIHomePage = false
|
|||
|
|
}
|
|||
|
|
} else if offsetY < 0 {
|
|||
|
|
//print("松手时,滑到顶部之外了")
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|