feat: 更新FeedView、HomeView和MeView以增强用户界面和交互体验
- 在FeedView中添加加号按钮,允许用户进行操作。 - 更新HomeView以支持全屏显示和更好的布局。 - 在MeView中优化用户信息展示,增加用户ID显示。 - 调整底部导航栏样式,提升视觉效果和用户体验。 - 确保视图在安全区域内适配,增强整体布局的适应性。
This commit is contained in:
@@ -17,18 +17,18 @@ enum Tab: Int, CaseIterable {
|
|||||||
var iconName: String {
|
var iconName: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .feed:
|
case .feed:
|
||||||
return "sparkles"
|
return "feed unselected"
|
||||||
case .me:
|
case .me:
|
||||||
return "person"
|
return "me unselected"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectedIconName: String {
|
var selectedIconName: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .feed:
|
case .feed:
|
||||||
return "sparkles"
|
return "feed selected"
|
||||||
case .me:
|
case .me:
|
||||||
return "person.fill"
|
return "me selected"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,31 +43,36 @@ struct BottomTabView: View {
|
|||||||
Button(action: {
|
Button(action: {
|
||||||
selectedTab = tab
|
selectedTab = tab
|
||||||
}) {
|
}) {
|
||||||
VStack(spacing: 4) {
|
Image(selectedTab == tab ? tab.selectedIconName : tab.iconName)
|
||||||
Image(systemName: selectedTab == tab ? tab.selectedIconName : tab.iconName)
|
.resizable()
|
||||||
.font(.system(size: 20))
|
.aspectRatio(contentMode: .fit)
|
||||||
.foregroundColor(selectedTab == tab ? .purple : .gray)
|
.frame(width: 30, height: 30)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
Text(tab.title)
|
|
||||||
.font(.caption2)
|
|
||||||
.foregroundColor(selectedTab == tab ? .purple : .gray)
|
|
||||||
}
|
|
||||||
.frame(maxWidth: .infinity)
|
|
||||||
}
|
}
|
||||||
.buttonStyle(PlainButtonStyle())
|
.buttonStyle(PlainButtonStyle())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.vertical, 12)
|
.frame(height: 60)
|
||||||
.padding(.horizontal, 8)
|
.padding(.horizontal, 16)
|
||||||
.background(
|
.background(
|
||||||
.ultraThinMaterial,
|
RoundedRectangle(cornerRadius: 30)
|
||||||
in: Rectangle()
|
.fill(.ultraThinMaterial)
|
||||||
)
|
.overlay(
|
||||||
.overlay(
|
RoundedRectangle(cornerRadius: 30)
|
||||||
Rectangle()
|
.stroke(Color.white.opacity(0.1), lineWidth: 0.5)
|
||||||
.frame(height: 0.5)
|
)
|
||||||
.foregroundColor(.black.opacity(0.2)),
|
.shadow(
|
||||||
alignment: .top
|
color: Color.black.opacity(0.34),
|
||||||
|
radius: 10.7,
|
||||||
|
x: 0,
|
||||||
|
y: 1.9
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
.padding(.horizontal, 15)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
BottomTabView(selectedTab: .constant(.feed))
|
||||||
|
.background(Color.purple) // 预览时添加背景色以便查看效果
|
||||||
|
}
|
||||||
|
@@ -2,43 +2,57 @@ import SwiftUI
|
|||||||
|
|
||||||
struct FeedView: View {
|
struct FeedView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView {
|
GeometryReader { geometry in
|
||||||
VStack(spacing: 20) {
|
ScrollView {
|
||||||
// 顶部标题
|
VStack(spacing: 20) {
|
||||||
HStack {
|
// 顶部区域 - 标题和加号按钮
|
||||||
Spacer()
|
HStack {
|
||||||
Text("Enjoy your Life Time")
|
Spacer()
|
||||||
.font(.system(size: 22, weight: .semibold))
|
|
||||||
.foregroundColor(.white)
|
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
.padding(.top, 20)
|
|
||||||
|
|
||||||
// 心脏图标
|
// 标题
|
||||||
Image(systemName: "heart.fill")
|
Text("Enjoy your Life Time")
|
||||||
.font(.system(size: 60))
|
.font(.system(size: 22, weight: .semibold))
|
||||||
.foregroundColor(.red)
|
.foregroundColor(.white)
|
||||||
.padding(.top, 40)
|
|
||||||
|
|
||||||
// 励志文字
|
Spacer()
|
||||||
Text("The disease is like a cruel ruler,\nand time is our most precious treasure.\nEvery moment we live is a victory\nagainst the inevitable.")
|
|
||||||
.font(.system(size: 16))
|
|
||||||
.multilineTextAlignment(.center)
|
|
||||||
.foregroundColor(.white.opacity(0.9))
|
|
||||||
.padding(.horizontal, 30)
|
|
||||||
.padding(.top, 20)
|
|
||||||
|
|
||||||
// 模拟动态卡片
|
// 右侧加号按钮
|
||||||
LazyVStack(spacing: 16) {
|
Button(action: {
|
||||||
ForEach(0..<3) { index in
|
// 加号按钮操作
|
||||||
DynamicCardView(index: index)
|
}) {
|
||||||
|
Image("add icon")
|
||||||
|
.frame(width: 36, height: 36)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.padding(.horizontal, 20)
|
||||||
.padding(.horizontal, 16)
|
// .padding(.top, geometry.safeAreaInsets.top + 20)
|
||||||
.padding(.top, 30)
|
|
||||||
|
|
||||||
// 底部安全区域
|
// 心脏图标
|
||||||
Color.clear.frame(height: 100)
|
Image(systemName: "heart.fill")
|
||||||
|
.font(.system(size: 60))
|
||||||
|
.foregroundColor(.red)
|
||||||
|
.padding(.top, 40)
|
||||||
|
|
||||||
|
// 励志文字
|
||||||
|
Text("The disease is like a cruel ruler,\nand time is our most precious treasure.\nEvery moment we live is a victory\nagainst the inevitable.")
|
||||||
|
.font(.system(size: 16))
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.foregroundColor(.white.opacity(0.9))
|
||||||
|
.padding(.horizontal, 30)
|
||||||
|
.padding(.top, 20)
|
||||||
|
|
||||||
|
// 模拟动态卡片
|
||||||
|
LazyVStack(spacing: 16) {
|
||||||
|
ForEach(0..<3) { index in
|
||||||
|
DynamicCardView(index: index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 16)
|
||||||
|
.padding(.top, 30)
|
||||||
|
|
||||||
|
// 底部安全区域 - 为底部导航栏和安全区域留出空间
|
||||||
|
Color.clear.frame(height: geometry.safeAreaInsets.bottom + 100)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,43 +64,37 @@ struct DynamicCardView: View {
|
|||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 12) {
|
VStack(alignment: .leading, spacing: 12) {
|
||||||
// 用户信息行
|
// 用户信息
|
||||||
HStack(spacing: 12) {
|
HStack {
|
||||||
// 头像
|
|
||||||
Circle()
|
Circle()
|
||||||
.fill(Color.blue.opacity(0.6))
|
.fill(Color.gray.opacity(0.3))
|
||||||
.frame(width: 40, height: 40)
|
.frame(width: 40, height: 40)
|
||||||
.overlay(
|
.overlay(
|
||||||
Text("👤")
|
Text("U\(index + 1)")
|
||||||
.font(.system(size: 20))
|
.font(.system(size: 16, weight: .medium))
|
||||||
|
.foregroundColor(.white)
|
||||||
)
|
)
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
HStack {
|
Text("用户\(index + 1)")
|
||||||
Text("NAMENAMENAME....")
|
.font(.system(size: 16, weight: .medium))
|
||||||
.font(.system(size: 14, weight: .medium))
|
.foregroundColor(.white)
|
||||||
.foregroundColor(.white)
|
|
||||||
|
|
||||||
Spacer()
|
Text("2小时前")
|
||||||
|
.font(.system(size: 12))
|
||||||
Text("ID:7271557")
|
.foregroundColor(.white.opacity(0.6))
|
||||||
.font(.caption)
|
|
||||||
.foregroundColor(.white.opacity(0.7))
|
|
||||||
}
|
|
||||||
|
|
||||||
Text("09/12")
|
|
||||||
.font(.caption)
|
|
||||||
.foregroundColor(.white.opacity(0.7))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spacer()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 内容文字
|
// 动态内容
|
||||||
Text("这是动态内容 \(index + 1)。今天是美好的一天,分享一些生活中的点点滴滴。")
|
Text("今天是美好的一天,分享一些生活中的小确幸。希望大家都能珍惜每一个当下的时刻。")
|
||||||
.font(.system(size: 15))
|
.font(.system(size: 14))
|
||||||
.foregroundColor(.white)
|
.foregroundColor(.white.opacity(0.9))
|
||||||
.lineLimit(nil)
|
.multilineTextAlignment(.leading)
|
||||||
|
|
||||||
// 图片网格(模拟)
|
// 图片网格
|
||||||
LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 8), count: 3), spacing: 8) {
|
LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 8), count: 3), spacing: 8) {
|
||||||
ForEach(0..<3) { imageIndex in
|
ForEach(0..<3) { imageIndex in
|
||||||
Rectangle()
|
Rectangle()
|
||||||
@@ -132,3 +140,7 @@ struct DynamicCardView: View {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
FeedView()
|
||||||
|
}
|
||||||
|
@@ -10,53 +10,33 @@ struct HomeView: View {
|
|||||||
WithPerceptionTracking {
|
WithPerceptionTracking {
|
||||||
GeometryReader { geometry in
|
GeometryReader { geometry in
|
||||||
ZStack {
|
ZStack {
|
||||||
// 使用 "bg" 图片作为背景
|
// 使用 "bg" 图片作为背景 - 全屏显示
|
||||||
Image("bg")
|
Image("bg")
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fill)
|
.aspectRatio(contentMode: .fill)
|
||||||
.frame(width: geometry.size.width, height: geometry.size.height)
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
.clipped()
|
.clipped()
|
||||||
.ignoresSafeArea(.all)
|
.ignoresSafeArea(.all)
|
||||||
|
|
||||||
VStack(spacing: 0) {
|
// 主要内容区域 - 全屏显示
|
||||||
// 顶部导航区域
|
ZStack {
|
||||||
HStack {
|
switch selectedTab {
|
||||||
Spacer()
|
case .feed:
|
||||||
|
FeedView()
|
||||||
// 右上角加号按钮
|
.transition(.opacity)
|
||||||
Button(action: {
|
case .me:
|
||||||
// 加号按钮操作
|
MeView()
|
||||||
}) {
|
.transition(.opacity)
|
||||||
Image(systemName: "plus")
|
|
||||||
.font(.system(size: 20, weight: .medium))
|
|
||||||
.foregroundColor(.red)
|
|
||||||
.frame(width: 36, height: 36)
|
|
||||||
.background(
|
|
||||||
Color.white.opacity(0.2)
|
|
||||||
.cornerRadius(18)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 20)
|
}
|
||||||
.padding(.top, 10)
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
|
||||||
// 主要内容区域
|
// 底部导航栏 - 悬浮在最上层
|
||||||
ZStack {
|
VStack {
|
||||||
// 根据选中的 tab 显示不同的视图
|
Spacer()
|
||||||
switch selectedTab {
|
|
||||||
case .feed:
|
|
||||||
FeedView()
|
|
||||||
.transition(.opacity)
|
|
||||||
case .me:
|
|
||||||
MeView()
|
|
||||||
.transition(.opacity)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
||||||
|
|
||||||
// 底部导航栏
|
|
||||||
BottomTabView(selectedTab: $selectedTab)
|
BottomTabView(selectedTab: $selectedTab)
|
||||||
}
|
}
|
||||||
|
.padding(.bottom, geometry.safeAreaInsets.bottom + 100)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
|
@@ -2,73 +2,76 @@ import SwiftUI
|
|||||||
|
|
||||||
struct MeView: View {
|
struct MeView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView {
|
GeometryReader { geometry in
|
||||||
VStack(spacing: 20) {
|
ScrollView {
|
||||||
// 顶部标题
|
VStack(spacing: 20) {
|
||||||
HStack {
|
// 顶部标题
|
||||||
Spacer()
|
|
||||||
Text("我的")
|
|
||||||
.font(.system(size: 22, weight: .semibold))
|
|
||||||
.foregroundColor(.white)
|
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
.padding(.top, 20)
|
|
||||||
|
|
||||||
// 用户头像区域
|
|
||||||
VStack(spacing: 16) {
|
|
||||||
Circle()
|
|
||||||
.fill(Color.white.opacity(0.2))
|
|
||||||
.frame(width: 80, height: 80)
|
|
||||||
.overlay(
|
|
||||||
Image(systemName: "person.fill")
|
|
||||||
.font(.system(size: 40))
|
|
||||||
.foregroundColor(.white)
|
|
||||||
)
|
|
||||||
|
|
||||||
Text("用户昵称")
|
|
||||||
.font(.system(size: 18, weight: .medium))
|
|
||||||
.foregroundColor(.white)
|
|
||||||
|
|
||||||
Text("ID: 123456789")
|
|
||||||
.font(.system(size: 14))
|
|
||||||
.foregroundColor(.white.opacity(0.7))
|
|
||||||
}
|
|
||||||
.padding(.top, 30)
|
|
||||||
|
|
||||||
// 功能菜单
|
|
||||||
VStack(spacing: 12) {
|
|
||||||
MenuItemView(icon: "gearshape", title: "设置", action: {})
|
|
||||||
MenuItemView(icon: "person.circle", title: "个人信息", action: {})
|
|
||||||
MenuItemView(icon: "heart", title: "我的收藏", action: {})
|
|
||||||
MenuItemView(icon: "clock", title: "浏览历史", action: {})
|
|
||||||
MenuItemView(icon: "questionmark.circle", title: "帮助与反馈", action: {})
|
|
||||||
}
|
|
||||||
.padding(.horizontal, 20)
|
|
||||||
.padding(.top, 40)
|
|
||||||
|
|
||||||
// 退出登录按钮
|
|
||||||
Button(action: {}) {
|
|
||||||
HStack {
|
HStack {
|
||||||
Image(systemName: "rectangle.portrait.and.arrow.right")
|
Spacer()
|
||||||
.font(.system(size: 16))
|
Text("我的")
|
||||||
Text("退出登录")
|
.font(.system(size: 22, weight: .semibold))
|
||||||
.font(.system(size: 16, weight: .medium))
|
.foregroundColor(.white)
|
||||||
|
Spacer()
|
||||||
}
|
}
|
||||||
.foregroundColor(.red)
|
.padding(.top, geometry.safeAreaInsets.top + 20)
|
||||||
.frame(maxWidth: .infinity)
|
|
||||||
.frame(height: 50)
|
|
||||||
.background(
|
|
||||||
Color.white.opacity(0.1)
|
|
||||||
.cornerRadius(12)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.padding(.horizontal, 20)
|
|
||||||
.padding(.top, 30)
|
|
||||||
|
|
||||||
// 底部安全区域
|
// 用户头像区域
|
||||||
Color.clear.frame(height: 100)
|
VStack(spacing: 16) {
|
||||||
|
Circle()
|
||||||
|
.fill(Color.white.opacity(0.2))
|
||||||
|
.frame(width: 80, height: 80)
|
||||||
|
.overlay(
|
||||||
|
Image(systemName: "person.fill")
|
||||||
|
.font(.system(size: 40))
|
||||||
|
.foregroundColor(.white)
|
||||||
|
)
|
||||||
|
|
||||||
|
Text("用户昵称")
|
||||||
|
.font(.system(size: 18, weight: .medium))
|
||||||
|
.foregroundColor(.white)
|
||||||
|
|
||||||
|
Text("ID: 123456789")
|
||||||
|
.font(.system(size: 14))
|
||||||
|
.foregroundColor(.white.opacity(0.7))
|
||||||
|
}
|
||||||
|
.padding(.top, 30)
|
||||||
|
|
||||||
|
// 功能菜单
|
||||||
|
VStack(spacing: 12) {
|
||||||
|
MenuItemView(icon: "gearshape", title: "设置", action: {})
|
||||||
|
MenuItemView(icon: "person.circle", title: "个人信息", action: {})
|
||||||
|
MenuItemView(icon: "heart", title: "我的收藏", action: {})
|
||||||
|
MenuItemView(icon: "clock", title: "浏览历史", action: {})
|
||||||
|
MenuItemView(icon: "questionmark.circle", title: "帮助与反馈", action: {})
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 20)
|
||||||
|
.padding(.top, 40)
|
||||||
|
|
||||||
|
// 退出登录按钮
|
||||||
|
Button(action: {}) {
|
||||||
|
HStack {
|
||||||
|
Image(systemName: "rectangle.portrait.and.arrow.right")
|
||||||
|
.font(.system(size: 16))
|
||||||
|
Text("退出登录")
|
||||||
|
.font(.system(size: 16, weight: .medium))
|
||||||
|
}
|
||||||
|
.foregroundColor(.red)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.frame(height: 50)
|
||||||
|
.background(
|
||||||
|
Color.white.opacity(0.1)
|
||||||
|
.cornerRadius(12)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 20)
|
||||||
|
.padding(.top, 30)
|
||||||
|
|
||||||
|
// 底部安全区域 - 为底部导航栏和安全区域留出空间
|
||||||
|
Color.clear.frame(height: geometry.safeAreaInsets.bottom + 100)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.ignoresSafeArea(.container, edges: .top)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,3 +108,7 @@ struct MenuItemView: View {
|
|||||||
.buttonStyle(PlainButtonStyle())
|
.buttonStyle(PlainButtonStyle())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
MeView()
|
||||||
|
}
|
Reference in New Issue
Block a user