0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SwiftUIでスワイプを実装する方法

Last updated at Posted at 2025-03-03

スワイプを実装方法

1.TabView を実装

2.DragGesture() をカスタムして実装

TabViewを使用

メリット

✅ デフォルトでスワイプ対応
• .tabViewStyle(PageTabViewStyle()) を指定するだけで、スワイプでページ遷移が可能。

✅ アニメーションが自動適用
• TabView は ページ間のスワイプアニメーションが自動で適用される。

✅ シンプルなコード
• TabView に .tag() を設定するだけでページ管理が可能。

デメリット

❌ 自由なカスタマイズが難しい
• TabView のスワイプアニメーションを カスタマイズするのは難しい。

❌ プログラム的なページ切り替えがやや面倒
• currentPage を tag で管理する必要がある。

❌ スワイプが有効な範囲が制限される
• TabView は画面 全体のスワイプ しかサポートしないため、一部の領域だけでスワイプを有効にするのが難しい。



import SwiftUI


struct Tab_View: View {
    @State private var currentPage: Page = .home

    var body: some View {
        TabView(selection: $currentPage) {
            Tab_HomeView(currentPage: $currentPage)
                .tag(Page.home)

            Page3View(currentPage: $currentPage)
                .tag(Page.page1)

            Page4View(currentPage: $currentPage)
                .tag(Page.page2)
        }
        .tabViewStyle(PageTabViewStyle(indexDisplayMode: .always)) // スワイプでページ切り替え
    }
}

struct Tab_HomeView: View {
    @Binding var currentPage: Page

    var body: some View {
        VStack {
            Text("たぶViewホーム画面")
                .font(.largeTitle)

            .padding()
        }
    }
}

struct Page3View: View {
    @Binding var currentPage: Page

    var body: some View {
        VStack {
            Text("Page 1")
                .font(.largeTitle)
            Button("ホームに戻る") {
                currentPage = .home
            }
            .padding()
        }
    }
}

struct Page4View: View {
    @Binding var currentPage: Page

    var body: some View {
        VStack {
            Text("Page 2")
                .font(.largeTitle)
            Button("ホームに戻る") {
                currentPage = .home
            }
            .padding()
        }
    }
}

#Preview {
    Tab_View()
}

DragGesture()を使用

メリット

✅ 自由にカスタマイズ可能
• スワイプ感度、スワイプの方向、スワイプ距離 などを自由に設定できる。

✅ スワイプが有効な領域を調整できる
• contentShape(Rectangle()) などを使えば、 画面全体ではなく、一部の領域だけスワイプを有効にすることが可能。

✅ ページの制御がしやすい
• currentPage の変更だけでページを管理できる。

デメリット

❌ アニメーションが自動でつかない
• TabView のように スムーズなスワイプアニメーションはデフォルトで適用されない ため、カスタムで withAnimation を適用する必要がある。

❌ ページ数が多いとコードが複雑になる
• switch currentPage { ... } のような ページ管理コードが増えてしまう。

import SwiftUI

enum Page {
    case home, page1, page2
}

struct ContentView: View {
    @State private var currentPage: Page = .home

    var body: some View {
        ZStack {
            currentPageView()
                .gesture(
                    DragGesture()
                        .onEnded { value in
                            if value.translation.width < -100 { // 左スワイプ
                                goToNextPage()
                            } else if value.translation.width > 100 { // 右スワイプ
                                goToPreviousPage()
                            }
                        }
                )
        }
    }

    func currentPageView() -> some View {
        switch currentPage {
        case .home:
            return AnyView(Tab_HomeView(currentPage: $currentPage))
        case .page1:
            return AnyView(Page1View(currentPage: $currentPage))
        case .page2:
            return AnyView(Page2View(currentPage: $currentPage))
        }
    }

    func goToNextPage() {
        switch currentPage {
        case .home:
            currentPage = .page1
        case .page1:
            currentPage = .page2
        case .page2:
            break // 何もしない(最後のページ)
        }
    }

    func goToPreviousPage() {
        switch currentPage {
        case .home:
            break // 何もしない(最初のページ)
        case .page1:
            currentPage = .home
        case .page2:
            currentPage = .page1
        }
    }
}

struct HomeView: View {
    @Binding var currentPage: Page

    var body: some View {
        VStack {
            Text("ホーム画面")
                .font(.largeTitle)

            List {
                Text("大根")
                Text("キャベツ")
                Text("じゃがいも")
            }
        }
    }
}

struct Page1View: View {
    @Binding var currentPage: Page

    var body: some View {
        VStack {
            Text("Page 1")
                .font(.largeTitle)
            Button("ホームに戻る") {
                currentPage = .home
            }
            .padding()
        }
    }
}

struct Page2View: View {
    @Binding var currentPage: Page

    var body: some View {
        VStack {
            Text("Page 2")
                .font(.largeTitle)
            Button("ホームに戻る") {
                currentPage = .home
            }
            .padding()
        }
    }
}


#Preview {
    ContentView().environmentObject(UserSettings())
}
0
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?