
- 将iOS平台版本更新至17,确保与最新的开发环境兼容。 - 更新Podfile中的iOS部署目标至17.0,确保依赖项与新版本兼容。 - 修改Podfile.lock以反映新的依赖项版本,确保项目一致性。 - 在多个视图中重构代码,优化状态管理和视图逻辑,提升用户体验。
195 lines
8.5 KiB
Swift
195 lines
8.5 KiB
Swift
import SwiftUI
|
||
import ComposableArchitecture
|
||
import Perception
|
||
|
||
// PreferenceKey 用于传递图片高度
|
||
struct ImageHeightPreferenceKey: PreferenceKey {
|
||
static let defaultValue: CGFloat = 0
|
||
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
|
||
value = max(value, nextValue())
|
||
}
|
||
}
|
||
|
||
struct LoginView: View {
|
||
let store: StoreOf<LoginFeature>
|
||
let onLoginSuccess: () -> Void // 新增:登录成功回调
|
||
|
||
// 使用本地@State管理UI状态
|
||
@State private var showIDLogin: Bool = false
|
||
@State private var showEmailLogin: Bool = false
|
||
@State private var showLanguageSettings: Bool = false
|
||
@State private var showUserAgreement: Bool = false
|
||
@State private var showPrivacyPolicy: Bool = false
|
||
|
||
// 计算属性
|
||
private var topImageHeight: CGFloat = 200 // 默认值
|
||
|
||
var body: some View {
|
||
WithPerceptionTracking {
|
||
NavigationStack {
|
||
GeometryReader { geometry in
|
||
ZStack {
|
||
// 使用与 splash 相同的背景图片
|
||
Image("bg")
|
||
.resizable()
|
||
.aspectRatio(contentMode: .fill)
|
||
.ignoresSafeArea(.all)
|
||
VStack(spacing: 0) {
|
||
// 上半部分的"top"图片
|
||
ZStack {
|
||
Image("top")
|
||
.resizable()
|
||
.aspectRatio(contentMode: .fit)
|
||
.frame(maxWidth: .infinity)
|
||
.padding(.top, -100)
|
||
.background(
|
||
GeometryReader { topImageGeometry in
|
||
Color.clear.preference(key: ImageHeightPreferenceKey.self, value: topImageGeometry.size.height)
|
||
}
|
||
)
|
||
// E-PARTI 文本,底部对齐"top"图片底部,间距20
|
||
HStack {
|
||
Text(LocalizedString("login.app_title", comment: ""))
|
||
.font(FontManager.adaptedFont(.bayonRegular, designSize: 56, for: geometry.size.width))
|
||
.foregroundColor(.white)
|
||
.padding(.leading, 20)
|
||
Spacer()
|
||
}
|
||
.padding(.top, max(0, topImageHeight - 100)) // top图片高度 - 140
|
||
}
|
||
|
||
// 下半部分的登录按钮区域
|
||
VStack(spacing: 20) {
|
||
// 登录按钮
|
||
LoginButton(
|
||
title: LocalizedString("login.id_login", comment: ""),
|
||
icon: "person.circle",
|
||
action: {
|
||
showIDLogin = true
|
||
}
|
||
)
|
||
|
||
LoginButton(
|
||
title: LocalizedString("login.email_login", comment: ""),
|
||
icon: "envelope",
|
||
action: {
|
||
showEmailLogin = true
|
||
}
|
||
)
|
||
|
||
// 底部设置按钮
|
||
HStack(spacing: 20) {
|
||
Button(action: {
|
||
showLanguageSettings = true
|
||
}) {
|
||
Text(LocalizedString("login.language", comment: ""))
|
||
.font(.system(size: 14))
|
||
.foregroundColor(.white.opacity(0.8))
|
||
}
|
||
|
||
Button(action: {
|
||
showUserAgreement = true
|
||
}) {
|
||
Text(LocalizedString("login.user_agreement", comment: ""))
|
||
.font(.system(size: 14))
|
||
.foregroundColor(.white.opacity(0.8))
|
||
}
|
||
|
||
Button(action: {
|
||
showPrivacyPolicy = true
|
||
}) {
|
||
Text(LocalizedString("login.privacy_policy", comment: ""))
|
||
.font(.system(size: 14))
|
||
.foregroundColor(.white.opacity(0.8))
|
||
}
|
||
}
|
||
}
|
||
.padding(.horizontal, 28)
|
||
.padding(.bottom, 140)
|
||
}
|
||
|
||
// 添加API Loading和错误处理视图
|
||
APILoadingEffectView()
|
||
|
||
// 移除旧的 NavigationLink,改用 navigationDestination
|
||
}
|
||
}
|
||
.navigationBarHidden(true)
|
||
// 新增:适配 iOS 16 的 navigationDestination
|
||
.navigationDestination(isPresented: $showIDLogin) {
|
||
WithPerceptionTracking {
|
||
IDLoginView(
|
||
store: store.scope(
|
||
state: \.idLoginState,
|
||
action: \.idLogin
|
||
),
|
||
onBack: {
|
||
showIDLogin = false
|
||
},
|
||
showIDLogin: $showIDLogin // 新增:传递Binding
|
||
)
|
||
.navigationBarHidden(true)
|
||
}
|
||
}
|
||
.navigationDestination(isPresented: $showEmailLogin) {
|
||
WithPerceptionTracking {
|
||
EMailLoginView(
|
||
store: store.scope(
|
||
state: \.emailLoginState,
|
||
action: \.emailLogin
|
||
),
|
||
onBack: {
|
||
showEmailLogin = false
|
||
},
|
||
showEmailLogin: $showEmailLogin // 新增:传递Binding
|
||
)
|
||
.navigationBarHidden(true)
|
||
}
|
||
}
|
||
}
|
||
.sheet(isPresented: $showLanguageSettings) {
|
||
WithPerceptionTracking {
|
||
LanguageSettingsView(isPresented: $showLanguageSettings)
|
||
}
|
||
}
|
||
.webView(
|
||
isPresented: $showUserAgreement,
|
||
url: APIConfiguration.webURL(for: .userAgreement)
|
||
)
|
||
.webView(
|
||
isPresented: $showPrivacyPolicy,
|
||
url: APIConfiguration.webURL(for: .privacyPolicy)
|
||
)
|
||
// 新增:监听登录成功,调用回调
|
||
.onChange(of: store.isAnyLoginCompleted) { completed in
|
||
if completed {
|
||
onLoginSuccess()
|
||
}
|
||
}
|
||
// 新增:监听showIDLogin关闭时,若已登录则跳转首页
|
||
.onChange(of: showIDLogin) { newValue in
|
||
if newValue == false && store.isAnyLoginCompleted {
|
||
onLoginSuccess()
|
||
}
|
||
}
|
||
// 新增:监听showEmailLogin关闭时,若已登录则跳转首页
|
||
.onChange(of: showEmailLogin) { newValue in
|
||
if newValue == false && store.isAnyLoginCompleted {
|
||
onLoginSuccess()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//#Preview {
|
||
// LoginView(
|
||
// store: Store(
|
||
// initialState: LoginFeature.State()
|
||
// ) {
|
||
// LoginFeature()
|
||
// },
|
||
// onLoginSuccess: {}
|
||
// )
|
||
//}
|