-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathSegmentedControlView.swift
More file actions
67 lines (63 loc) · 2.45 KB
/
SegmentedControlView.swift
File metadata and controls
67 lines (63 loc) · 2.45 KB
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//
// SegmentedControlView.swift
// AIProject
//
// Created by 장지현 on 7/31/25.
//
import SwiftUI
/// 사용자 지정 세그먼트 컨트롤 뷰
///
/// 이 뷰는 `tabTitles`에 지정된 탭 제목을 표시하고,
/// 현재 선택된 탭을 `selection` 바인딩을 통해 제어합니다.
///
/// - Parameters:
/// - selection: 현재 선택된 탭 인덱스를 나타내는 바인딩 변수
/// - tabTitles: 각 탭에 표시할 제목 문자열 배열
/// - width: SegmentedControl 너비를 지정하는 값, 기본값은 150
struct SegmentedControlView: View {
/// 선택된 탭의 언더라인 애니메이션을 위한 네임스페이스
@Namespace private var underlineAnimation
/// 현재 선택된 탭 인덱스를 나타내는 바인딩 변수
@Binding var selection: Int
/// 각 탭에 표시할 제목 문자열 배열
let tabTitles: [String]
/// SegmentedControl 너비 (기본값 150)
var width: CGFloat = 150
/// 뷰 계층 구조를 정의하고, 각 탭 버튼과 배경을 구성합니다.
var body: some View {
HStack(spacing: 0) {
ForEach(0..<tabTitles.count, id: \.self) { idx in
Button {
withAnimation(.easeInOut) {
selection = idx
}
} label: {
Text(tabTitles[idx])
.font(selection == idx ? .ico15B : .ico15)
.frame(maxWidth: .infinity)
.padding(.horizontal, 14)
.padding(.vertical, 8)
.foregroundColor(selection == idx ? .white : .iCoLabelSecondary)
.background(
ZStack {
if selection == idx {
Capsule()
.fill(.iCoAccent)
.matchedGeometryEffect(id: "underline", in: underlineAnimation)
}
}
)
}
}
}
.padding(8)
.background(.iCoBackgroundAccent)
.frame(width: width)
.clipShape(Capsule())
.overlay { Capsule().strokeBorder(.defaultGradient, lineWidth: 0.5) }
}
}
#Preview {
SegmentedControlView(selection: .constant(0), tabTitles: ["1D", "1D", "1D", "1D", "1D"], width: 320)
.padding()
}