
- 在FeedListView和MeView中新增previewCurrentIndex状态,支持图片预览的当前索引管理。 - 更新ImagePreviewPager的currentIndex绑定,确保预览逻辑的正确性。 - 在FeedListContentView中添加onImageTap回调,更新previewCurrentIndex以提升用户交互体验。 - 在MainView中调整底部内边距,优化布局效果。
137 lines
4.7 KiB
Swift
137 lines
4.7 KiB
Swift
import SwiftUI
|
|
import ComposableArchitecture
|
|
|
|
struct MainView: View {
|
|
let store: StoreOf<MainFeature>
|
|
var onLogout: (() -> Void)? = nil
|
|
|
|
var body: some View {
|
|
WithViewStore(self.store, observe: { $0 }) { viewStore in
|
|
WithPerceptionTracking {
|
|
InternalMainView(store: store)
|
|
.onChange(of: viewStore.isLoggedOut) { isLoggedOut in
|
|
if isLoggedOut {
|
|
onLogout?()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct InternalMainView: View {
|
|
let store: StoreOf<MainFeature>
|
|
@State private var path: [MainFeature.Destination] = []
|
|
init(store: StoreOf<MainFeature>) {
|
|
self.store = store
|
|
_path = State(initialValue: store.withState { $0.navigationPath })
|
|
}
|
|
var body: some View {
|
|
WithViewStore(self.store, observe: { $0 }) { viewStore in
|
|
WithPerceptionTracking {
|
|
NavigationStack(path: $path) {
|
|
GeometryReader { geometry in
|
|
contentView(geometry: geometry, viewStore: viewStore)
|
|
.navigationDestination(for: MainFeature.Destination.self) { destination in
|
|
DestinationView(destination: destination, store: self.store)
|
|
}
|
|
.onChange(of: path) { newPath in
|
|
viewStore.send(.navigationPathChanged(newPath))
|
|
}
|
|
.onChange(of: viewStore.navigationPath) { newPath in
|
|
if path != newPath {
|
|
path = newPath
|
|
}
|
|
}
|
|
.onAppear {
|
|
viewStore.send(.onAppear)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct DestinationView: View {
|
|
let destination: MainFeature.Destination
|
|
let store: StoreOf<MainFeature>
|
|
|
|
var body: some View {
|
|
switch destination {
|
|
case .appSetting:
|
|
IfLetStore(
|
|
store.scope(state: \.appSettingState, action: \.appSettingAction),
|
|
then: { store in
|
|
WithPerceptionTracking {
|
|
AppSettingView(store: store)
|
|
}
|
|
},
|
|
else: { Text("appSettingState is nil") }
|
|
)
|
|
case .testView:
|
|
TestView()
|
|
}
|
|
}
|
|
}
|
|
|
|
private func contentView(geometry: GeometryProxy, viewStore: ViewStoreOf<MainFeature>) -> some View {
|
|
WithPerceptionTracking {
|
|
ZStack {
|
|
// 背景图片
|
|
Image("bg")
|
|
.resizable()
|
|
.aspectRatio(contentMode: .fill)
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
.clipped()
|
|
.ignoresSafeArea(.all)
|
|
// 主内容
|
|
MainContentView(
|
|
store: store,
|
|
selectedTab: viewStore.selectedTab
|
|
)
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
.padding(.bottom, 80) // 为底部导航栏留出空间
|
|
|
|
// 底部导航栏 - 固定在底部
|
|
VStack {
|
|
Spacer()
|
|
BottomTabView(selectedTab: viewStore.binding(
|
|
get: { Tab(rawValue: $0.selectedTab.rawValue) ?? .feed },
|
|
send: { MainFeature.Action.selectTab(MainFeature.Tab(rawValue: $0.rawValue) ?? .feed) }
|
|
))
|
|
}
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottom)
|
|
.padding(.bottom, 100)
|
|
.ignoresSafeArea(.keyboard, edges: .bottom)
|
|
|
|
// 添加API Loading和错误处理视图
|
|
APILoadingEffectView()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct MainContentView: View {
|
|
let store: StoreOf<MainFeature>
|
|
let selectedTab: MainFeature.Tab
|
|
var body: some View {
|
|
Group {
|
|
if selectedTab == .feed {
|
|
FeedListView(store: store.scope(
|
|
state: \.feedList,
|
|
action: \.feedList
|
|
))
|
|
} else if selectedTab == .other {
|
|
MeView(
|
|
store: store.scope(
|
|
state: \.me,
|
|
action: \.me
|
|
)
|
|
)
|
|
} else {
|
|
EmptyView()
|
|
}
|
|
}
|
|
}
|
|
}
|