TabView 作为一个很强大的组件,几乎很多app都会用到。它方便的管理不同业务模块的UI显示。
struct TabViewSample: View {
var body: some View {
TabView {
Text("首页")
.font(.title)
.fontWeight(.semibold)
.tabItem {
Image(systemName: "house")
Text("首页")
}
Text("📚大全")
.tabItem {
Image(systemName: "book.closed")
Text("书籍")
}
Text("设置")
.tabItem {
Image(systemName: "gear")
Text("设置")
}
}
.tint(Color.purple)
}
}
以上就是最简单的示例,我们可以轻松的改变它的外观颜色,使用tint即可。默认是蓝色,我们的例子中使用的紫色。
Tab 切换
我们实现一个在首页里面点击按钮跳转到setting页面的需求。我把代码稍微进行了改造,给首页加入了一个button
struct TabViewSample: View {
@State var selectedTab: Int = 0
var body: some View {
TabView(selection: $selectedTab) {
VStack {
Text("首页")
.font(.title)
.fontWeight(.semibold)
Button(action: {
}, label: {
Text("切换到setting tab")
.foregroundColor(.white)
.font(.headline)
.padding()
.background(Color.purple.cornerRadius(10))
})
}
.tabItem {
Image(systemName: "house")
Text("首页")
}
.tag(0)
Text("📚大全")
.tabItem {
Image(systemName: "book.closed")
Text("书籍")
}
.tag(1)
Text("设置")
.tabItem {
Image(systemName: "gear")
Text("设置")
}
.tag(2)
}
.tint(Color.purple)
}
}
但是问题来了,这样会显得我们的代码非常长。是时候进行提取一下代码做简化了。
我们会将首页的VStack里面的内容提取为一个组件。一下是组件的代码。
struct MainView: View {
var body: some View {
VStack {
Text("首页")
.font(.title)
.fontWeight(.semibold)
Button(action: {
}, label: {
Text("切换到setting tab")
.foregroundColor(.white)
.font(.headline)
.padding()
.background(Color.purple.cornerRadius(10))
})
}
}
}
调用变成:
MainView()
.tabItem {
Image(systemName: "house")
Text("首页")
}
.tag(0)
这样有利于代码的整洁,其他人看了也不会因为代码过长而感到头疼。
那么改如何实现点击首页的Button切换到Setting页面呢?
由于我们操作的对象不在一个视图层级内,我们需要在MainView点击,然后来改变父类TabView的切换。所以我们需要使用到之前说过的一个属性包装起@binding来实现
我们把Setting Tab的内容也稍微改变了一下,便于识别
ZStack {
Color.blue
.edgesIgnoringSafeArea(.top)
VStack {
Text("设置")
.font(.title)
.fontWeight(.semibold)
}
}
.tabItem {
Image(systemName: "gear")
Text("设置")
}
.tag(2)
我们现在就可以实现上述效果了,具体效果如下:
Badge
tab上面的小红点很简单,只需要在对应想实现的地方加入一下方法即可
MainView(selectedTab: $selectedTab)
.badge(2)
.tabItem {
Image(systemName: "house")
Text("首页")
}
.tag(0)
首页的Tab上面就有对应的Badge显示了
最后整体代码是这样的
struct TabViewSample: View {
@State var selectedTab: Int = 0
var body: some View {
TabView(selection: $selectedTab) {
MainView(selectedTab: $selectedTab)
.badge(2)
.tabItem {
Image(systemName: "house")
Text("首页")
}
.tag(0)
Text("📚大全")
.tabItem {
Image(systemName: "book.closed")
Text("书籍")
}
.tag(1)
ZStack {
Color.blue
.edgesIgnoringSafeArea(.top)
VStack {
Text("设置")
.font(.title)
.fontWeight(.semibold)
}
}
.badge("!")
.tabItem {
Image(systemName: "gear")
Text("设置")
}
.tag(2)
}
.tint(Color.purple)
}
}
struct MainView: View {
@Binding var selectedTab: Int
var body: some View {
var body: some View {
VStack {
Text("首页")
.font(.title)
.fontWeight(.semibold)
Button(action: {
selectedTab = 2
}, label: {
Text("切换到setting tab")
.foregroundColor(.white)
.font(.headline)
.padding()
.background(Color.purple.cornerRadius(10))
})
}
}
}
}
TabView 的另一种形态
在SwiftUI中tabView有另一种形式的存在,就如我们平时看到的图片左右切换控价一样。它可以左右滑动来切换内容,代码和之前相差无几。但是效果却差别很大,只需要把TabViewSample里面的代码改成如下即可。注意的是我们设置了**.tabViewStyle(.page)**
struct TabView2Sample: View {
@State var selectedTab: Int = 0
var body: some View {
ZStack {
Color.yellow
.edgesIgnoringSafeArea(.all)
TabView(selection: $selectedTab) {
MainView(selectedTab: $selectedTab)
.tag(0)
Text("📚大全")
.tag(1)
Text("设置")
.tag(2)
}
.tabViewStyle(.page)
}
}
}
效果如下:
大家有什么看法呢?欢迎留言讨论。
公众号:RobotPBQ