在UIKit中设置多个tabbar展示需求运用到UITabBarController
在SwiftUI中 由TabView
组件来进行完成,一同TabView
也可以完成PageViewController的效果,
TabView常规用法1
import SwiftUI
struct ZTMinePageView: View {
var body: some View {
TabView{
Text("设置一").tabItem {
Image(systemName: "arkit").foregroundColor(.red)
Text("设置一")
}
Text("设置二").tabItem {
Image(systemName: "star")
Text("设置二")
}
Text("设置三").tabItem {
Image(systemName: "star").foregroundColor(.red)
Text("设置三")
}
Text("设置四").tabItem {
Image(systemName: "star").foregroundColor(.red)
Text("设置四")
}
}
}
}
tabview此刻不会绑定对应的selectedIndex,只能在初始化的时分设置对应的index,不能动态设置要展示的tabbar的index,
TabView常规用法2
除了上面的点击tabview切换视图,SwiftUI
还答应我们运用情况来控制其时视图。为此 我们需求四步
- 1.创建一个记录其时闪现视图的
@State
特色 - 2.跳转到其他tab中的视图批改该特色
- 3.该特色以
Binding
的方式传给TabView,便于自动跟踪 - 4.告诉SwiftUI 那种值应该闪现那个Tab 具体的如下:
import SwiftUI
struct ZTTestPageView: View {
@State private var selectedTab = 0
var body: some View {
TabView(selection: $selectedTab){
Text("设置一").tabItem {
Image(systemName: "arkit").foregroundColor(.red)
Text("设置一")
}.onTapGesture {
self.selectedTab = 3
}.tag(0)
Text("设置二").tabItem {
Image(systemName: "star")
Text("设置二")
}.tag(1)
Text("设置三").tabItem {
Image(systemName: "star").foregroundColor(.red)
Text("设置三")
}.tag(2)
Text("设置四").tabItem {
Image(systemName: "star").foregroundColor(.red)
Text("设置四")
}.tag(3)
}
}
}
上面代码中当我们点击 设置一界面中的text 这时会批改selectedTab
,而我们在上面把TabView
和selectedTab
绑定到一同了,批改selectedTab
的值 TabView
也会切换对应展示的视图。
- 1.
TabView
只支撑Text
Image
或Image
后边跟Text
的选项卡。传递其他任何类型的视图都会导致一个可见但空的选项卡 - 2.
selection
特色指示默许选中那个tag
TabView常规用法3
在上面的用法中没有方法对TabbarItem
中的图片做选中和非选中的切换,上面截图中的改动只是系统对选中和非选中的一个色彩的处理,事实上我们的图片都是同一个。在实践项目中,点击tabbar切换视图 底部的图片也会跟着改动,而且在其他界面中也会动态的批改其时TabView
的index。
- 1.创建一个环境方针,在App发起的时分设置要展示的初始值,
- 2.其他要批改的地方 获取环境变量并批改
- 3.
TabView
和环境变量彼此绑定,有一方批改 其他方也会跟着改动
1.定义一个全局的环境变量
import SwiftUI
import Combine
final class TabBarIndexObserver: ObservableObject {
@Published
var tabSelected: TabBarItem = .Home
}
2.定义为全局的环境变量 @EnvironmentObject
import SwiftUI
@main
struct SwiftUITestApp: App {
var body: some Scene {
WindowGroup {
ContentView().environmentObject(TabBarIndexObserver())
}
}
}
3.绑定TabView
和环境变量,其间要自己自定义一个TabBarItem
方针,主要是根据其时TabView
中的index 回来 image 和 title,每个展示的视图都要设置tag 否则绑定视图一贯展示的都是0,不会切换到其他视图。图片资源可以自己设置。
import SwiftUI
enum TabBarItem: Int {
case Home
case Living
case Message
case Mine
var titleStr: String {
switch self {
case .Home:
return "主页"
case .Living:
return "直播"
case .Message:
return "消息"
case .Mine:
return "我的"
}
}
var normalImage: Image {
var imageName = ""
switch self {
case .Home:
imageName = ""
case .Living:
imageName = ""
case .Message:
imageName = ""
case .Mine:
imageName = ""
}
return Image(imageName)
}
var selectedImage: Image {
var imageName = ""
switch self {
case .Home:
imageName = ""
case .Living:
imageName = ""
case .Message:
imageName = ""
case .Mine:
imageName = ""
}
return Image(imageName)
}
}
在TabView
中进行对应的设置,给每一个视图设置一个仅有的标识,用这个标识符作为被选中的tab,这些标识符被称为Tag
import SwiftUI
struct ContentView: View {
@EnvironmentObject
private var tabbarIndex: TabBarIndexObserver
private var selectedTab: Binding<Int> {
Binding(
get: { tabbarIndex.tabSelected.rawValue },
set: {
tabbarIndex.tabSelected = TabBarItem(rawValue: $0)!
}
)
}
// 设置对应的normal 和 selected图片 要设置TabView 绑定情况 和 每个View的tag值,在点击的时分把值传递给对应的view
var body: some View {
TabView(selection: selectedTab) {
ZTHomePageView()
.tabItem {tabItem(for: .Home)}
.tag(TabBarItem.Home.rawValue)
ZTLivingPageView()
.tabItem {tabItem(for: .Living)}
.tag(TabBarItem.Living.rawValue)
ZTMessagePageView()
.tabItem {tabItem(for: .Message)}
.tag(TabBarItem.Message.rawValue)
ZTMinePageView()
.tabItem { tabItem(for: .Mine) }
.tag(TabBarItem.Mine.rawValue)
}
.font(.headline)
.accentColor(Color.red) // 设置 tab bar 选中色彩
}
private func tabItem(for tab: TabBarItem) -> some View {
print(selectedTab.wrappedValue)
return VStack {
tab.rawValue == selectedTab.wrappedValue ? tab.selectedImage : tab.normalImage
Text(tab.titleStr)
}
}
}
TabView常规用法4—做轮播图
TabView
完成轮播图时不用设置tabItem 需求指定tabView的闪现类型为.tabViewStyle(PageTabViewStyle())
具体代码如下
struct ZTMinePageView: View {
//设置定时器 每2s运行一次 mode为 common 在主线程执行 autoconnect 当即开始定时器
let timer = Timer.publish(every: 2, tolerance: 0.5, on: .main, in: .common).autoconnect()
@State private var bannerIndex = 0
var body: some View {
if #available(iOS 15.0, *) {
TabView(selection: $bannerIndex){
Image("test_1").resizable().scaledToFit().tag(0)
Image("test_2").resizable().scaledToFit().tag(1)
Image("test_3").resizable().scaledToFit().tag(2)
Image("test_4").resizable().scaledToFit().tag(3)
}
.background(Color(red: 0.5, green: 0.9, blue: 0.3, opacity: 0.3))
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
.onReceive(timer){ time in
self.bannerIndex += 1
if self.bannerIndex > 3{
self.bannerIndex = 0
}
}
.onAppear{
}.onDisappear{
self.timer.upstream.connect().cancel()
}
} else {
}
}
}
其间设置了一个定时器,具体效果如下,假如想要动画 可以自己加上去
TabView
常规用法—躲藏tabbar
App开发中 从一个页面导航到下一个界面时需求躲藏TabBar
,但是现有的SwiftUI 并没有直接供应躲藏TabBar
的方法。假如根视图是一个tabView 在跳转到下一个界面的时分 tabbar并不会主动躲藏,TabView -> NavigationView -> View 这种方法 不会主动躲藏tabbar,具体完成如下
var body: some View {
TabView(selection: selectedTab) {
//在TabView内部做 NavigationView包装
NavigationView{
ZTHomePageView()
}.tabItem {tabItem(for: .Home)}
.tag(TabBarItem.Home.rawValue)
ZTLivingPageView()
.tabItem {tabItem(for: .Living)}
.tag(TabBarItem.Living.rawValue)
ZTMessagePageView()
.tabItem {tabItem(for: .Message)}
.tag(TabBarItem.Message.rawValue)
ZTMinePageView()
.tabItem { tabItem(for: .Mine) }
.tag(TabBarItem.Mine.rawValue)
}
.font(.headline)
.accentColor(Color.red) // 设置 tab bar 选中色彩
}
ZTHomePageView
中对应的Text上添加了跳转事件,
NavigationLink(destination: TestTabView()){
Text("该来的就会来的")
.underline()
.foregroundColor(.yellow)
}
这时分要躲藏底部的tabbar 就需求批改SwiftUI中的层级结构。运用NavigationView
直接包裹TabView
.
var body: some View {
NavigationView{
TabView(selection: selectedTab) {
ZTHomePageView()
.tabItem {tabItem(for: .Home)}
.tag(TabBarItem.Home.rawValue)
ZTLivingPageView()
.tabItem {tabItem(for: .Living)}
.tag(TabBarItem.Living.rawValue)
ZTMessagePageView()
.tabItem {tabItem(for: .Message)}
.tag(TabBarItem.Message.rawValue)
ZTMinePageView()
.tabItem { tabItem(for: .Mine) }
.tag(TabBarItem.Mine.rawValue)
}
.font(.headline)
.accentColor(Color.red) // 设置 tab bar 选中色彩
}
}
再次看下跳转效果
对此还有上面跳转到下一界面 回来按钮的色彩是红色和蓝色 这是因为设置的.accentColor(Color.green)
的问题形成的。
设置Tabbar的背景色
默许情况下 TabView下发的Tabbar是透明的,当页面中的视图过多时会在Tabbar底部展示,而这个时分对TabBar设置一个背景色就可以处理这个问题。在运用TabView的页面的初始化方法init
方法中对下面特色进行批改
init() {
//批改tabbar底部的背景色
UITabBar.appearance().backgroundColor = .blue
UITabBar.appearance().backgroundImage = UIImage()
}
实践效果如下