swiftUI에서는 위와 같은 picker를 해당 코드로 만들 수 있습니다.
enum Flavor: String, CaseIterable, Identifiable {
case chocolate
case vanilla
case strawberry
var id: String { self.rawValue }
}
struct FlavorPicker: View {
@State private var selectedFlavor = Flavor.chocolate
var body: some View {
VStack {
Picker("Flavor", selection: $selectedFlavor) {
ForEach(Flavor.allCases) { flavor in
Text(flavor.rawValue)
.tag(flavor)
}
}
Text("Selected flavor: \(selectedFlavor.rawValue)")
}
}
}
피커 쪽만 떼어서 볼까요?
Picker("Flavor", selection: $selectedFlavor) {
ForEach(Flavor.allCases) { flavor in
Text(flavor.rawValue)
.tag(flavor)
}
}
꽤나 간단합니다. 이때 “흠.. 피커에서 어떤 요소를 클릭했는지 어떻게 감지하지?” 라는 의문점이 들 수 있는데요! 여기서 tag(_:)
modifier를 주목해봅시다.
Text
마다 붙인 태그 값은, selection
파라미터로 넘겨진 $selectedFlavor
값과 연관됩니다. 만약 피커에서 chocolate
을 선택하면, chocolate
에 해당하는 tag 값으로 $selectedFlavor
이 변화됩니다.
사실 ForEach
로 Picker를 생성을 하면 내부의 id
를 이용해서 자동으로 tag
를 어사인 해줍니다. (여기선 Flavor
가 Identifiable protocol
을 따르고 있기 때문에 가능)
pickerStyle
pickerStyle(_:)
modifier를 통해서 피커의 스타일 (automatic
, wheel
, menu
, segmented
, inline
, radioGroup
) 을 지정할 수 있습니다.
Picker(~~~)
.pickerStyle(.wheel)
다만 Xcode13.0 이전의 환경을 사용하고 있으신 분들은 .pickerStyle(InlinePickerStyle())
요런식으로 해당하는 struct를 생성해서 넣어줘야할 것 같습니다. (왜냐면 Xcode 12.5 에서는 .inline
이 안먹혔거든여)
하나씩 어떤 스타일이 적용되는지 살펴봅시다.
automatic
picker 의 context에 따라 달라지는 default 스타일입니다.
wheel
선택한 옵션과 몇 가지 인접 옵션을 표시하는 휠에 옵션을 표시하는 스타일입니다.
menu
사용자가 버튼을 누를 때 메뉴로 옵션을 표시하거나, 더 큰 메뉴에 중첩될 때 하위 메뉴로 옵션을 표시하는 스타일입니다.
segmented
segmented control에 옵션을 표시하는 스타일입니다.
inline
각 옵션이 현재 컨테이너의 다른 view들과 함께 inline 으로 표시 됩니다. picker가 List 안에 있을 때 차이점을 확인 할 수 있습니다.
List {
Picker("Flavor", selection: $selectedFlavor) {
ForEach(Flavor.allCases) { flavor in
Text(flavor.rawValue)
.tag(flavor)
}
}
.pickerStyle(.inline)
Text("Selected flavor: \(selectedFlavor.rawValue)")
}
radioGroup
라디오 버튼의 그룹으로 옵션을 표시하는 스타일입니다. 하지만 macOS 에서만 사용 가능합니다.
DatePicker
DatePicker도 그냥 picker 와 마찬가지로 간단하게 구현할 수 있습니다.
@State private var today = Date()var body: some View {
DatePicker(
"Start Date",
selection: $today,
in: dateRange,
displayedComponents: [.date, .hourAndMinute]
)
}
추가로 date의 범위도 지정할 수 있습니다
//범위 지정
var dateRange: ClosedRange<Date> {
let min = Calendar.current.date(byAdding: .year, value: -1, to: today)!
let max = Calendar.current.date(byAdding: .year, value: 1, to: today)!
return min...max
}var body: some View {
DatePicker(
"Start Date",
selection: $today,
in: dateRange, //범위 파라미터 추가
displayedComponents: [.date, .hourAndMinute]
)
}
datePickerStyle
datePickerStyle(_:)
view modifier를 통해서 date 피커의 스타일 (automatic
, compact
, graphical
, wheel
, stepperField
, field
) 을 지정할 수 있습니다.
DatePicker(~~)
.datePickerStyle(.compact)
automatic
date picker의 기본 스타일입니다. 이걸로 지정하면 compact
랑 동일하게 나오네여
compact
component 를 compact하고 textual한 형식으로 표시하는 스타일입니다.
graphical
interactive한 달력 또는 시계를 표시하는 스타일입니다.
wheel
휠에서 각 component 를 column으로 표시하는 스타일입니다.
stepperField
편집 가능한 필드에 component를 표시하는 시스템 스타일이며, 선택한 component 를 증가/감소할 수 있는 스텝퍼가 있습니다. 하지만 macOS 에서만 사용 가능합니다.
field
편집 가능한 필드에 component 를 표시하는 스타일입니다. 하지만 macOS 에서만 사용 가능합니다. 이곳에 따르면 해당 필드를 클릭하면 GraphicalStyle subview로 팝업이 나타난다고 합니다.
ColorPicker
ColorPicker도 다른 피커들과 마찬가지로 간단하게 구현할 수 있습니다.
struct FormattingControls: View {
@State private var bgColor =
Color(.sRGB, red: 0.98, green: 0.9, blue: 0.2)var body: some View {
VStack {
ColorPicker("Alignment Guides", selection: $bgColor)
}
}
}
color picker는 현재 선택된 색상을 표시하며, 사용자가 새 색상을 선택할 수 있는 더 큰 시스템 color picker를 표시합니다.
opacity를 지원하지 않으려면 supportOpacity
매개 변수를 false
로 설정합니다.
ColorPicker("Alignment Guides",
selection: $bgColor,
supportsOpacity: false)