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

この記事からわかること

  • SwiftUITabView使い方
  • タブビューを簡単に実装する方法
  • tabItem変更するには?
  • スワイプタブ送りできるようにする
  • タブを上部設置する方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

Swift UIでタブでページ切り替えるような画面を簡単に構築できるTabView構造体の使い方と記述方法をまとめていきます。

TabView構造体とは?

Apple公式リファレンス:TabView

struct TabView<SelectionValue, Content> where SelectionValue : Hashable, Content : View

TabView構造体複数のタブでページを切り替えられる画面を実装できるSwift UIで使用できる構造体です。デフォルトではタブボタンは表示されないのでtabItemを使用して明示的に表示させる必要があります。

タブはビューの下側に設置され、クリックすることで表示されるビューを切り替えることができるようになります。

TabView構造体を扱う上で重要となるポイントを整理しておきます。

使い方

実際にタブビューを実装してみます。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モディファイアを付与してタブボタンの色を変数する

引数に変更したい色を指定すればアクティブになっているタブボタンの色を変更することができます。

TabView {
    ・・・
}.accentColor(.orange)

未選択のタブボタンの色を変える

アクティブになっていないタブボタンはデフォルトで灰色になっています。これを変更するにはUITabBarクラスのイニシャライザから設定します。UITabBarクラスはUIKitで使用していたUIViewの1つでありSwiftUIでも基本的にUIViewを活用して定義されているので、リンクしたUIViewの設定値を変更することでSwiftUIのViewにも反映されます。

TabViewにイニシャライザを付与して非アクティブのタブボタンの色を変数する
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の背景色を変更する

TabViewの背景色を変更するにはタブボタン同様にUITabBarクラスのイニシャライザから設定していきます。

init() {
  // 文字色
  UITabBar.appearance().unselectedItemTintColor = .white
  // 背景色
  UITabBar.appearance().backgroundColor = .black
}
TabViewの背景色を変更する

タブが多すぎる場合

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

TabViewの背景色を変更する
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.appearanceisHiddentrueを設定することで非表示にすることができます。

init() {
    // タブを非表示
    UITabBar.appearance().isHidden = true
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index