实现的效果如上图所示,支持左右滑动切换页面,也支持点击顶部的toolbar菜单切换页面,每个页面里面的每一项都是一个carditem.swift,这是我封装的一个card组件,用于展示每一个card内容,carditem.swift内容如下:
//
// CardItem.swift
// SwiftBook
//
// Created by Song on 2024/7/6.
//
import SwiftUI
struct CardItem: View {
// 传递过来的图片和昵称
var preImg = ""
var avatar = ""
var nickname = ""
var distance = ""
var body: some View {
VStack {
Image(preImg)
.resizable()
.aspectRatio(contentMode: .fit)
HStack {
HStack {
Image(avatar)
.resizable()
.frame(width: 20, height: 20)
.aspectRatio(contentMode: .fit)
.mask(Circle())
Text(nickname)
}
Spacer()
Text("\(distance)km")
}
}
.padding()
.background(.white)
.cornerRadius(10)
}
}
#Preview {
CardItem()
}
这个组件封装出来的效果如图所示:里面使用到的就是水平布局和垂直布局,还有一个Image组件
首页实现
然后就是首页里面的toolbar使用,以及NavigationStack和TabView,还有tabViewStyle,还有navigationBarTitleDisplayMode,还有ToolbarItem。简单讲一下使用他们的必要性以及作用。
NavigationStack是导航栈,要配合TabView一起使用,才能达到TabView的效果。
TabView:是实现点击每一项toolbar实现页面切换的必备视图
tabViewStyle:是为了使用tabview的page样式,以此实现页面切换的效果,并设置indexDisplayMode为never,让切换页面之间不显示小白点,就是轮播图。还有一种是点击底部tab的效果。
navigationBarTitleDisplayMode:为了让顶部toolbar和内容之间没有空白间隙,设置inline模式。
toolbar+ToolbarItem:为了实现顶部的toolbar菜单效果。还有顶部右侧的搜索图标显示。
首页代码内容:
//
// Hongshu.swift
// SwiftBook
//
// Created by Song on 2024/7/6.
//
import SwiftUI
struct Hongshu: View {
@State var current = 0
var body: some View {
NavigationStack {
ScrollView(content: {
TabView(selection: $current) {
HStack(content: {
VStack(content: {
CardItem(preImg: "juzi", avatar: "juzi", nickname: "11111", distance: "555")
CardItem(preImg: "putao", avatar: "putao", nickname: "putao", distance: "11")
CardItem(preImg: "shanchu", avatar: "xigua", nickname: "山竹", distance: "53")
Spacer()
})
VStack(content: {
CardItem(preImg: "hongyou", avatar: "liulian", nickname: "liula", distance: "11")
CardItem(preImg: "taozi", avatar: "xigua2", nickname: "山竹", distance: "53")
CardItem(preImg: "lizhi", avatar: "xigua2", nickname: "山竹", distance: "53")
Spacer()
})
})
.padding(.horizontal)
.tag(0)
HStack(content: {
VStack(content: {
CardItem(preImg: "taozi", avatar: "taozi", nickname: "11111", distance: "555")
CardItem(preImg: "xigua", avatar: "xigua", nickname: "putao", distance: "11")
CardItem(preImg: "hongyou", avatar: "xigua", nickname: "山竹", distance: "53")
Spacer()
})
VStack(content: {
CardItem(preImg: "liulian", avatar: "liulian", nickname: "liula", distance: "11")
CardItem(preImg: "xigua2", avatar: "xigua2", nickname: "山竹", distance: "53")
Spacer()
})
})
.padding(.horizontal)
.tag(1)
HStack(content: {
VStack(content: {
CardItem(preImg: "xigua", avatar: "taozi", nickname: "11111", distance: "555")
CardItem(preImg: "default", avatar: "xigua", nickname: "putao", distance: "11")
CardItem(preImg: "xigua2", avatar: "xigua", nickname: "山竹", distance: "53")
Spacer()
})
VStack(content: {
CardItem(preImg: "liulian", avatar: "liulian", nickname: "liula", distance: "11")
CardItem(preImg: "taozi", avatar: "xigua2", nickname: "山竹", distance: "53")
Spacer()
})
})
.padding(.horizontal)
.tag(2)
}
.tabViewStyle(.page(indexDisplayMode: .never))
.frame(width: UIScreen.main.bounds.width,
height: UIScreen.main.bounds.height)
})
.background(.gray.opacity(0.3))
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .principal, content: {
HStack {
Text("首页")
.foregroundColor(
current == 0 ? .blue : .black)
.onTapGesture {
current = 0
}
Text("附近")
.foregroundColor(
current == 1 ? .blue : .black)
.onTapGesture {
current = 1
}
Text("推荐")
.foregroundColor(
current == 2 ? .blue : .black)
.onTapGesture {
current = 2
}
}
})
ToolbarItem(placement: .topBarTrailing, content: {
HStack {
Image(systemName: "magnifyingglass")
}
})
}
.tag("home")
}
}
}
#Preview {
Hongshu()
}