🔥
[SwiftUI]TabViewをボタンアクションでアニメーション付きで変える
今回はSwiftUIでTabView
を使い、UIKitのUIPageViewController
のようなページ遷移実装します。
やりたいこと
-
TabView
を使用してページ遷移を実装する - スワイプでページ遷移ができる
- ボタンアクションなどでアニメーション付きのページ遷移ができる
特に、最後の「プログラムでアニメーション付きページ遷移をする」ところができるように実装します。
環境
- Xcode: 14.3
- iOS: 16.4
実装
TabViewでページ遷移するようにする
スワイプ操作でTabViewでページ遷移するように実装します。
@State var currentTab: Int = 0
TabView(selection: $currentTab) {
PageView(index: 1).tag(0)
PageView(index: 2).tag(1)
PageView(index: 3).tag(2)
}
.tabViewStyle(.page(indexDisplayMode: .never))
.tabViewStyle
に.page(indexDisplayMode: .never)
を設定することで、ページ遷移の挙動になります。さらにindexDisplayMode
つまり下部に表示される現在のページを表すドットの表示について.never
を設定することで非表示としています。
TabView.selection
の説明については割愛します。
.page
はiOS14から使用できます。
@available(iOS 14.0, tvOS 14.0, watchOS 7.0, *)
@available(macOS, unavailable)
extension TabViewStyle where Self == PageTabViewStyle {
public static var page: PageTabViewStyle { get }
public static func page(indexDisplayMode: PageTabViewStyle.IndexDisplayMode) -> PageTabViewStyle
}
現状では、プログラム的にページを変えるためにcurrentTab
を変更しても、ページは瞬時に変わります。
ページ遷移時にアニメーションを追加する
通常のスワイプでページを変更すると、当然アニメーションでのページ遷移となります。
ボタンアクションなどでプログラム的にアニメーション付きでページを変えるためには、以下の実装が必要になります。
TabView(selection: $currentTab) {
PageView(index: 1).tag(0)
PageView(index: 2).tag(1)
PageView(index: 3).tag(2)
}
.tabViewStyle(.page(indexDisplayMode: .never))
.animation(.easeInOut, value: currentTab)
.animation(_:value:)
を使用することで、valueに設定した値の変更を検知してアニメーションをします。
これでプログラム的なページ変更でもアニメーションするようになりました。
最終的な実装
struct ContentView: View {
@State var currentTab: Int = 0
var body: some View {
VStack {
TabView(selection: $currentTab) {
PageView(index: 1).tag(0)
PageView(index: 2).tag(1)
PageView(index: 3).tag(2)
}
.frame(maxHeight: .infinity)
.tabViewStyle(.page(indexDisplayMode: .never))
.animation(.easeInOut, value: currentTab)
HStack(spacing: 32) {
Button("Page.1") {
currentTab = 0
}
.padding()
Button("Page.2") {
currentTab = 1
}
.padding()
Button("Page.3") {
currentTab = 2
}
.padding()
}
}
.padding()
}
}
このようなアニメーションになります。
ソースコード
ソースコードはこちらに置きました。
参考
SwiftUIのTabViewでボタンアクションによるスライド切り替え|TAAT
Animate transition between views o… | Apple Developer Forums
Discussion