Files
e-party-iOS/yana/MVVM/View/MomentListHomePage.swift
edwinQQQ 6b575dab27 feat: 实现MomentListItem点赞功能及状态管理
- 在MomentListItem中新增点赞功能,用户点击按钮可触发点赞请求。
- 使用MVVM+Combine架构管理点赞状态,确保UI与状态同步。
- 添加加载状态和错误处理,提升用户体验和交互反馈。
- 更新相关视图以支持新的点赞逻辑,优化代码可读性和维护性。
2025-08-07 11:50:30 +08:00

160 lines
7.4 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import SwiftUI
// MARK: - BackgroundView
struct MomentListBackgroundView: View {
var body: some View {
Image("bg")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.clipped()
.ignoresSafeArea(.all)
}
}
// MARK: - MomentListHomePage
struct MomentListHomePage: View {
@StateObject private var viewModel = MomentListHomeViewModel()
// MARK: -
@State private var previewItem: PreviewItem? = nil
@State private var previewCurrentIndex: Int = 0
var body: some View {
GeometryReader { geometry in
ZStack {
//
MomentListBackgroundView()
VStack(alignment: .center, spacing: 0) {
//
Text(LocalizedString("feedList.title", comment: "Enjoy your Life Time"))
.font(.system(size: 22, weight: .semibold))
.foregroundColor(.white)
.frame(maxWidth: .infinity, alignment: .center)
.padding(.top, 60)
// Volume
Image("Volume")
.frame(width: 56, height: 41)
.padding(.top, 16)
//
Text(LocalizedString("feedList.slogan",
comment: ""))
.font(.system(size: 16))
.multilineTextAlignment(.leading)
.foregroundColor(.white.opacity(0.9))
.padding(.horizontal, 30)
.padding(.bottom, 30)
//
if !viewModel.moments.isEmpty {
ScrollView {
LazyVStack(spacing: 16) {
ForEach(Array(viewModel.moments.enumerated()), id: \.element.dynamicId) { index, moment in
MomentListItem(
moment: moment,
onImageTap: { images, tappedIndex in
//
previewCurrentIndex = tappedIndex
previewItem = PreviewItem(images: images, index: tappedIndex)
debugInfoSync("📸 MomentListHomePage: 图片被点击")
debugInfoSync(" 动态索引: \(index)")
debugInfoSync(" 图片索引: \(tappedIndex)")
debugInfoSync(" 图片数量: \(images.count)")
}
)
.padding(.leading, 16)
.padding(.trailing, 32)
.onAppear {
//
if index == viewModel.moments.count - 3 {
viewModel.loadMoreData()
}
}
}
//
if viewModel.isLoadingMore {
HStack {
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .white))
.scaleEffect(0.8)
Text("加载更多...")
.font(.system(size: 14))
.foregroundColor(.white.opacity(0.8))
}
.padding(.vertical, 20)
}
//
if !viewModel.hasMore && !viewModel.moments.isEmpty {
Text("没有更多数据了")
.font(.system(size: 14))
.foregroundColor(.white.opacity(0.6))
.padding(.vertical, 20)
}
}
.padding(.bottom, 160) //
}
.refreshable {
//
viewModel.refreshData()
}
.onAppear {
//
debugInfoSync("📱 MomentListHomePage: 显示动态列表")
debugInfoSync(" 动态数量: \(viewModel.moments.count)")
debugInfoSync(" 是否有更多: \(viewModel.hasMore)")
debugInfoSync(" 是否正在加载更多: \(viewModel.isLoadingMore)")
}
} else if viewModel.isLoading {
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .white))
.padding(.top, 20)
} else if let error = viewModel.error {
VStack(spacing: 16) {
Text(error)
.font(.system(size: 14))
.foregroundColor(.red)
.multilineTextAlignment(.center)
.padding(.horizontal, 20)
//
Button(action: {
viewModel.refreshData()
}) {
Text("重试")
.font(.system(size: 14, weight: .medium))
.foregroundColor(.white)
.padding(.horizontal, 20)
.padding(.vertical, 8)
.background(Color.white.opacity(0.2))
.cornerRadius(8)
}
}
.padding(.top, 20)
}
Spacer()
}
}
}
.ignoresSafeArea()
.onAppear {
viewModel.onAppear()
}
// MARK: -
.fullScreenCover(item: $previewItem) { item in
ImagePreviewPager(
images: item.images as [String],
currentIndex: $previewCurrentIndex
) {
previewItem = nil
debugInfoSync("📸 MomentListHomePage: 图片预览已关闭")
}
}
}
}