feat: 优化CreateFeedView以提升用户体验
- 移除不必要的键盘高度管理,简化代码逻辑。 - 修改发布按钮逻辑,使其始终可见,增强用户交互。 - 更新内容输入区域样式,增加圆角背景,提升视觉效果。 - 调整图片选择按钮样式,使用图像替代硬编码背景,提升一致性。 - 处理点击空白处收起键盘的功能,改善用户体验。
This commit is contained in:
@@ -4,7 +4,6 @@ import PhotosUI
|
||||
|
||||
struct CreateFeedView: View {
|
||||
let store: StoreOf<CreateFeedFeature>
|
||||
@State private var keyboardHeight: CGFloat = 0
|
||||
@State private var isKeyboardVisible: Bool = false
|
||||
@FocusState private var isTextEditorFocused: Bool
|
||||
|
||||
@@ -13,26 +12,32 @@ struct CreateFeedView: View {
|
||||
NavigationStack {
|
||||
GeometryReader { geometry in
|
||||
VStack(spacing: 0) {
|
||||
// 背景色
|
||||
Color(hex: 0x0C0527)
|
||||
.ignoresSafeArea()
|
||||
|
||||
// 主要内容区域
|
||||
VStack(spacing: 20) {
|
||||
ContentInputSection(store: store, isFocused: $isTextEditorFocused)
|
||||
ImageSelectionSection(store: store)
|
||||
LoadingAndErrorSection(store: store)
|
||||
ZStack {
|
||||
// 背景色
|
||||
Color(hex: 0x0C0527)
|
||||
.ignoresSafeArea()
|
||||
|
||||
// 底部间距
|
||||
Color.clear.frame(height: bottomSpacing(geometry))
|
||||
// 主要内容区域
|
||||
VStack(spacing: 20) {
|
||||
ContentInputSection(store: store, isFocused: $isTextEditorFocused)
|
||||
ImageSelectionSection(store: store)
|
||||
LoadingAndErrorSection(store: store)
|
||||
|
||||
// 底部间距
|
||||
// Color.clear.frame(height: geometry.safeAreaInsets.bottom + 100)
|
||||
Spacer()
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
||||
.ignoresSafeArea(.keyboard, edges: .bottom)
|
||||
.background(Color(hex: 0x0C0527))
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
|
||||
.ignoresSafeArea(.keyboard, edges: .bottom)
|
||||
|
||||
// 底部发布按钮 - 只在键盘隐藏时显示
|
||||
if !isKeyboardVisible {
|
||||
PublishButtonSection(store: store, keyboardHeight: keyboardHeight, geometry: geometry, isFocused: $isTextEditorFocused)
|
||||
}
|
||||
// 底部发布按钮 - 始终显示
|
||||
PublishButtonSection(store: store, geometry: geometry, isFocused: $isTextEditorFocused)
|
||||
|
||||
}
|
||||
.onTapGesture {
|
||||
isTextEditorFocused = false // 点击空白处收起键盘
|
||||
}
|
||||
}
|
||||
.navigationTitle(NSLocalizedString("createFeed.title", comment: "Image & Text Publish"))
|
||||
@@ -74,29 +79,20 @@ struct CreateFeedView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.preferredColorScheme(.dark)
|
||||
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { notification in
|
||||
if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
|
||||
keyboardHeight = keyboardFrame.height
|
||||
if let _ = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
|
||||
isKeyboardVisible = true
|
||||
}
|
||||
}
|
||||
.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
|
||||
keyboardHeight = 0
|
||||
isKeyboardVisible = false
|
||||
}
|
||||
.onDisappear {
|
||||
keyboardHeight = 0
|
||||
isKeyboardVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - 辅助方法
|
||||
private func bottomSpacing(_ geometry: GeometryProxy) -> CGFloat {
|
||||
max(keyboardHeight, geometry.safeAreaInsets.bottom) + 100
|
||||
}
|
||||
|
||||
// MARK: - 工具栏按钮计算属性
|
||||
private var toolbarButtonText: String {
|
||||
if store.isUploadingImages {
|
||||
@@ -121,8 +117,9 @@ struct ContentInputSection: View {
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
// 文本输入框 - 移除深灰色背景
|
||||
ZStack(alignment: .topLeading) {
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.fill(Color.init(hex: 0x1C143A))
|
||||
if store.content.isEmpty {
|
||||
Text(NSLocalizedString("createFeed.enterContent", comment: "Enter Content"))
|
||||
.foregroundColor(.white.opacity(0.5))
|
||||
@@ -148,6 +145,7 @@ struct ContentInputSection: View {
|
||||
.foregroundColor(characterCountColor)
|
||||
}
|
||||
}
|
||||
.frame(height: 200)
|
||||
.padding(.horizontal, 20)
|
||||
.padding(.top, 20)
|
||||
}
|
||||
@@ -248,7 +246,6 @@ struct LoadingAndErrorSection: View {
|
||||
// MARK: - 发布按钮组件
|
||||
struct PublishButtonSection: View {
|
||||
let store: StoreOf<CreateFeedFeature>
|
||||
let keyboardHeight: CGFloat
|
||||
let geometry: GeometryProxy
|
||||
@FocusState.Binding var isFocused: Bool
|
||||
|
||||
@@ -289,7 +286,7 @@ struct PublishButtonSection: View {
|
||||
.opacity(buttonOpacity)
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.bottom, bottomPadding)
|
||||
.padding(.bottom, geometry.safeAreaInsets.bottom + 20)
|
||||
}
|
||||
.background(Color(hex: 0x0C0527))
|
||||
}
|
||||
@@ -308,10 +305,6 @@ struct PublishButtonSection: View {
|
||||
return NSLocalizedString("createFeed.publish", comment: "Publish")
|
||||
}
|
||||
}
|
||||
|
||||
private var bottomPadding: CGFloat {
|
||||
max(keyboardHeight, geometry.safeAreaInsets.bottom) + 20
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - iOS 16+ 图片选择网格组件
|
||||
@@ -357,7 +350,7 @@ struct ImageItemView: View {
|
||||
Image(uiImage: image)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(height: 100)
|
||||
.frame(width: 100, height: 100)
|
||||
.clipped()
|
||||
.cornerRadius(8)
|
||||
|
||||
@@ -387,14 +380,8 @@ struct CreateAddImageButton: View {
|
||||
maxSelectionCount: 9,
|
||||
matching: .images
|
||||
) {
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.fill(Color.white.opacity(0.1))
|
||||
.frame(height: 100)
|
||||
.overlay(
|
||||
Image(systemName: "plus")
|
||||
.font(.system(size: 40))
|
||||
.foregroundColor(.white.opacity(0.6))
|
||||
)
|
||||
Image("add photo")
|
||||
.frame(width: 100, height: 100)
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user