【Swift UI】TabViewの使い方とtabItemの色を変更する方法!

この記事からわかること
- SwiftUIのTabViewの使い方
- タブビューを簡単に実装する方法
- tabItemの色を変更するには?
- スワイプでタブ送りできるようにする
- タブを上部に設置する方法
index
[open]
\ アプリをリリースしました /
Swift UIでタブでページ切り替えるような画面を簡単に構築できるTabView構造体の使い方と記述方法をまとめていきます。
TabView構造体とは?
struct TabView<SelectionValue, Content> where SelectionValue : Hashable, Content : View
TabView構造体
は複数のタブでページを切り替えられる画面を実装できるSwift UIで使用できる構造体です。デフォルトではタブボタンは表示されないのでtabItem
を使用して明示的に表示させる必要があります。
タブはビューの下側に設置され、クリックすることで表示されるビューを切り替えることができるようになります。
TabView構造体を扱う上で重要となるポイントを整理しておきます。
- 選択されているタブ番号を格納する変数の準備
- タブボタンになるtabItem
- タブ番号を示すtagの指定
使い方
実際にタブビューを実装してみます。TabView
の引数には選択されているタブ番号を保持するための変数を渡す必要があります。そのため最初にInt
型の変数を定義します。初期値としてはアクティブにしたいタブ番号を指定し、内部から変更できるように@State
をつけて宣言します。
@State var selectedTag:Int = 1
宣言した変数をTabView(selection:)
形式で渡すことで、タブでアクティブになっているページを管理できるようになります。
TabView(selection: $selectedTag) {
Text("Tab Content 1").tabItem { Text("Tab Label 1") }.tag(1)
Text("Tab Content 2").tabItem { Text("Tab Label 2") }.tag(2)
}
中(正確には引数Content:
)にはタブページとして表示させたいビューを渡します。そのビューに対してタブボタンを実装するためのtabItem
とタブ番号を明示的に指定するtag(番号)
を付与することで下部にタブボタンが表示されます。
Text("Tab Content 1").tabItem{
Image(systemName: "pencil.circle")
Text("Add")
}..tag(1)
またtabItemの中にImage要素とText要素を記述すると自動でVStackがかかった状態(縦に並ぶ)になります。
タブボタンの色を変更する
タブボタンの色はデフォルトでは青色になっています。これを変更するにはTabView自体にaccentColor
モディファイアを使います。

引数に変更したい色を指定すればアクティブになっているタブボタンの色を変更することができます。
TabView {
・・・
}.accentColor(.orange)
未選択のタブボタンの色を変える
アクティブになっていないタブボタンはデフォルトで灰色になっています。これを変更するにはUITabBarクラスのイニシャライザから設定します。UITabBarクラスはUIKitで使用していたUIViewの1つでありSwiftUIでも基本的にUIViewを活用して定義されているので、リンクしたUIViewの設定値を変更することでSwiftUIのViewにも反映されます。

struct ContentView: View {
init() {
UITabBar.appearance().unselectedItemTintColor = .brown
}
var body: some View { ・・・
タブビューをスワイプで切り替える
タブビューは下のボタンをクリックすることで切り替えますが、左右へのスワイプでビューを切り替えることも可能です。
実装するにはTabViewにtabViewStyle
モディファイアを追加し、引数にPageTabViewStyle()
または.page
を渡します。tabItemでの文字表示はできなくなるので削除しておきます。
TabView(selection: $selectedTag) {
Text("Tab Content 1").tag(1)
Text("Tab Content 2").tag(2)
}.tabViewStyle(PageTabViewStyle())
タブにバッチを付与する
タブボタンにバッチを付与することも可能です。実装するにはbadge
モディファイアを使います。バッチには数値または文字列が指定可能です。
TabView(selection: $selectedTag) {
Text("Tab Content 1")
.badge("2")
.tabItem{
Image(systemName: "pencil.circle")
Text("Add")
}.tag(1)
Text("Tab Content 2")
.badge("Tip")
.tabItem{
Image(systemName: "yensign.circle")
Text("Calc")
}.tag(2)
}

TabViewの背景色を変更する
TabViewの背景色を変更するにはタブボタン同様にUITabBarクラスのイニシャライザから設定していきます。
init() {
// 文字色
UITabBar.appearance().unselectedItemTintColor = .white
// 背景色
UITabBar.appearance().backgroundColor = .black
}

タブが多すぎる場合
表示させたいタブが多すぎる(4つ以上)場合は自動でmore
という表示になります。クリックするとリスト形式で非表示のタブが表示され、そこからさらにクリックすることで画面遷移することができます。

struct ContentView: View {
@State var selectedTag = 1
var count:Int = 10
var body: some View {
TabView(selection: $selectedTag) {
ForEach(0...count, id: \.self) { i in
Text("Tab Content \(i)").tabItem {
Text("Tab Label \(i)")
Image(systemName: "person")
}.tag(i)
}
}
}
}
moreを表示させないようにする
more
を表示させないようにするには.tabViewStyle(.page)
を指定してスタイルを変更することで非表示にすることができます。
TabView {
// ...
}
.tabViewStyle(.page)
上部にタブを設置する方法
タブを切り替えるボタンは自動で下部に設置されますが、上部に設置したい場合はスタイルとしては用意されていないのでオリジナルで実装する必要があります。
とはいえバインディングしている変数にアクティブにしたいタブ番号を渡すボタンを作れば良いだけなので以下のように簡単に実装できます。
struct ContentView: View {
@State var selectedTag = 1
var numArray:[Int] = [0,1,2,3,4,5,6,7]
var body: some View {
VStack{
ScrollView(.horizontal) {
LazyHStack {
ForEach(numArray, id: \.self) { item in
Button {
selectedTag = numArray.firstIndex(of: item)!
} label: {
Text("\(numArray.firstIndex(of: item)!)")
}.padding()
.background(.cyan)
.foregroundColor(.white)
}
}
}.padding()
TabView(selection: $selectedTag) {
ForEach(numArray, id: \.self) { i in
Text("Tab Content \(i)").tag(i)
}
}.tabViewStyle(.page)
}
}
}
タブ自体を非表示にする
タブビューの機能は使用したいけど下部に表示されるタブボタンレイアウトは不要の場合はUITabBar.appearance
のisHidden
にtrue
を設定することで非表示にすることができます。
init() {
// タブを非表示
UITabBar.appearance().isHidden = true
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。