LoginSignup
7
5

【SwiftUI】Twitterのカテゴリータブを作成する

Last updated at Posted at 2023-05-07

はじめに

TwitterのカテゴリータブをSwiftUIでマネして作ってみました。

カテゴリータブどこ?

カテゴリータブって勝手に呼んでるだけです
正式名は知りません
IMG_2825.jpg

完成形

Simulator Screen Recording - iPhone 14 Pro - 2023-05-07 at 22.37.21.gif

実装

import SwiftUI

struct TwitterCategoryTabView<T: View>: View {
    @State private var selection = 0
    
    let tabs: [TwitterCategoryTabItem<T>]

    var body: some View {
        VStack(spacing: 0) {
            ScrollView(.horizontal, showsIndicators: false) {
                ScrollViewReader { proxy in
                    HStack {
                        ForEach(tabs.indices, id: \.self) { index in
                            Text(tabs[index].tabLabel)
                                .font(.headline)
                                .padding(.all, 10)
                                .twitterCategoryTabSelectionStyle(isSelected: index == selection)
                                .tag(index)
                                .onTapGesture {
                                    withAnimation {
                                        selection = index
                                    }
                                }
                        }
                    }
                    .onChange(of: selection) { index in
                        withAnimation {
                            proxy.scrollTo(index, anchor: .center)
                        }
                    }
                }
            }
            
            Divider()
            
            TabView(selection: $selection) {
                ForEach(tabs.indices, id: \.self) { index in
                    tabs[index].content()
                        .tag(index)
                }
            }
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
        }
    }
}

struct TwitterCategoryTabItem<T>: Identifiable where T: View {
    let id = UUID()
    let tabLabel: String
    let content: () -> T

    init(_ tabLabel: String, @ViewBuilder content: @escaping () -> T) {
        self.tabLabel = tabLabel
        self.content = content
    }
}

struct TwitterCategoryTabSelectionStyle: ViewModifier {
    let isSelected: Bool

    func body(content: Content) -> some View {
        ZStack(alignment: .bottom) {
            content
                .foregroundColor(isSelected ? .primary : .secondary)

            if isSelected {
                RoundedRectangle(cornerRadius: 3)
                    .frame(height: 3)
                    .foregroundColor(Color(red: 35/255, green: 140/255, blue: 216/255))
                    .padding(.horizontal, 3)
            }
        }
    }
}

extension View {
    func twitterCategoryTabSelectionStyle(isSelected: Bool) -> some View {
        self.modifier(TwitterCategoryTabSelectionStyle(isSelected: isSelected))
    }
}

使い方

import SwiftUI

struct ContentView: View {
    var body: some View {
        TwitterCategoryTabView(tabs: [
            .init("おすすめ", content: {
                mockView()
            }),
            .init("トレンド", content: {
                mockView()
            }),
            .init("ニュース", content: {
                mockView()
            }),
            .init("スポーツ", content: {
                mockView()
            }),
            .init("エンターテイメント", content: {
                mockView()
            })
        ])
    }
    
    private func mockView() -> some View {
        List {
            ForEach(0..<10) { index in
                Text("トピック: \(index)")
            }
        }
        .listStyle(.plain)
    }
}

おわり

いい感じに作ることができました

参考記事

7
5
0

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
7
5