티스토리 뷰

반응형

Custom  Segmented Control

import SwiftUI

/// 커스텀 세그먼트 뷰 (컨텐츠 크기만큼 동적 너비 버전)
struct SegmentedFlexibleView: View {
    
    let segments: [String]
    @Binding var currentPage: Int
    @Namespace private var name
    
    var body: some View {
        ScrollViewReader { proxy in
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 0) {
                    ForEach(segments.indices, id: \.self) { index in
                        Button {
                            currentPage = index
                        } label: {
                            VStack {
                                Text(segments[index])
                                    .font(.footnote)
                                    .fontWeight(.medium)
                                    .foregroundStyle(currentPage == index ? .orange : Color(uiColor: .systemGray))
                                ZStack {
                                    Capsule()
                                        .fill(.clear)
                                        .frame(height: 4)
                                    if currentPage == index {
                                        Capsule()
                                            .fill(.orange)
                                            .frame(height: 4)
                                            .matchedGeometryEffect(id: "Tab", in: name)
                                    }
                                }
                            }
                            .padding(.horizontal, 8) // 각 항목의 양쪽 여백 추가
                        }
                        .id(index)
                    }
                }
            }
            .onChange(of: currentPage) { _, newValue in
                withAnimation {
                    proxy.scrollTo(newValue, anchor: .center)
                }
            }
        }
        .animation(.spring(duration: 0.3), value: currentPage)
    }
}

#Preview {
    struct Preview: View {
        var segments: [Color] = [.red, .green, .blue, .brown, .purple, .pink, .yellow, .orange, .cyan, .teal, .gray, .black]
        
        @State var currentPage = 0
        
        var body: some View {
            VStack {
                SegmentedFlexibleView(segments: segments.map { "\($0)" },
                                      currentPage: $currentPage)
                
                TabView(selection: $currentPage) {
                    ForEach(segments.indices, id: \.self) { index in
                        segments[index]
                    }
                }
                .tabViewStyle(.page(indexDisplayMode: .never))
                .scrollTargetBehavior(.paging)
            }
            .ignoresSafeArea(.all, edges: .bottom)
        }
    }
    return Preview()
}

iOS

Swift

Xcode

Objective-C

SwiftUI

UISegmentedControl

Picker

탭뷰

탭뷰

탭메뉴

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함