Visual_Novel_iOS/crush/Crush/Src/Modules/Home/View/EncounterAICardView.swift

187 lines
5.7 KiB
Swift
Raw Normal View History

2025-10-09 10:29:35 +00:00
//
// 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("")
}
}
}