![見出し画像](https://assets.st-note.com/production/uploads/images/97249362/rectangle_large_type_2_df06531a8019d78a35af8bed57ca60ac.png?width=800)
SwiftUIのTabViewでボタンアクションによるスライド切り替え
TabViewの基本的な使い方
SwiftUIでTabViewを表示するには、以下のようにTabViewの中にそれぞれのViewを配置し、.tabItemモディファイアでタブアイテムを設定できる。
struct ContentView: View {
var body: some View {
TabView {
Page1()
.tabItem {
Image(systemName: "1.circle.fill")
Text("Page1")
}
Page2()
.tabItem {
Image(systemName:"2.circle.fill")
Text("Page2")
}
}
}
}
struct Page1: View {
var body: some View {
Text("Page1")
}
}
struct Page2: View {
var body: some View {
Text("Page2")
}
}
![](https://assets.st-note.com/img/1675517839602-KOYeVdPTCQ.png)
TabViewStyle
DefaultTabViewStyle:iOSやmacOSで使用でき、スタイルを指定しない・automaticを指定する場合に表示されるスタイル。iOSでは画面下部に、macOSでは画面上部にタブアイテムが表示される。
PageTabViewStyle:iOSで使えるページをスワイプで切り替えられるスタイル
ページインジケータを表示したくない場合は.tabViewStyle(.page(indexDisplayMode: .never))を指定すればよい。
CarouselTabViewStyle:watchOSのみで使えるスタイル
ボタンアクションでスライド切り替え
DefaultTabViewStyleのように画面下部にタブアイテムを表示したくない、またはスワイプでのページングもしたくないなどの場合は、自前で設置したボタンからページ切り替え・スワイプアクションを無効にする必要がある。
今回は画面上部にカスタムのタブバーを配置し、ボタンアクションでスライドアニメーションでページを切り替え、さらにスワイプアクションも無効としている。
struct CustomSampleView: View {
@State var selected = 0
var body: some View {
VStack(spacing: 0) {
CustomTabBarView(selected: $selected)
TabView(selection: $selected) {
CustomPage1().tag(0)
CustomPage2().tag(1)
CustomPage3().tag(2)
}
// スワイプアクションを無効化
.disabled(true)
// ページスタイル(インジケータ非表示)
.tabViewStyle(.page(indexDisplayMode: .never))
// 切り替え時のアニメーション
.animation(.easeInOut, value: selected)
}
.ignoresSafeArea(edges: .bottom)
}
}
struct CustomTabBarView: View {
@Binding var selected: Int
var body: some View {
HStack {
CustomTabBarButtonView(selected: $selected, title: "Page1", tag: 0)
CustomTabBarButtonView(selected: $selected, title: "Page2", tag: 1)
CustomTabBarButtonView(selected: $selected, title: "Page3", tag: 2)
}
}
}
struct CustomTabBarButtonView: View {
@Binding var selected: Int
var title: String
var tag: Int
var body: some View {
Button {
selected = tag
} label: {
VStack(spacing: 0) {
Text(title)
.padding(8)
Rectangle()
.frame(height: 8)
.hidden(isHidden: selected != tag)
}
}
}
}
struct CustomPage1: View {
var body: some View {
Color.red
.ignoresSafeArea()
}
}
struct CustomPage2: View {
var body: some View {
Color.green
.ignoresSafeArea()
}
}
struct CustomPage3: View {
var body: some View {
Color.blue
.ignoresSafeArea()
}
}
タブバーボタン下部のRectangleを選択状態に応じて非表示にしたいので、以下のような条件に応じてViewを非表示にするViewModifierを定義した。
/// 条件に応じてViewを非表示にするViewModifier
struct HiddenViewModifier: ViewModifier {
var isHidden: Bool
func body(content: Content) -> some View {
if isHidden {
content.hidden()
} else {
content
}
}
}
extension View {
func hidden(isHidden: Bool) -> some View {
modifier(HiddenViewModifier(isHidden: isHidden))
}
}
![](https://assets.st-note.com/production/uploads/images/97249164/picture_pc_92c181ca434f6d743bfa199f866f1c15.gif)
サンプルコード
参考
この記事が気に入ったらサポートをしてみませんか?