Swift/Swift 개발 노트

[iOS/SwiftUI] Picker

힛해 2024. 8. 23. 02:28
728x90

https://developer.apple.com/documentation/swiftui/picker

 

Picker | Apple Developer Documentation

A control for selecting from a set of mutually exclusive values.

developer.apple.com

 

상단에 탭뷰처럼 사용할 수 있는 UI 요소들을 찾아보다 Picker라는 것이 있다는 것을 알게되었다.

 

iOS 13이상에서 사용할 수 있다고 한다.

@MainActor @preconcurrency
struct Picker<Label, SelectionValue, Content> where
Label : View, SelectionValue : Hashable, Content : View

 

 

이전에 포스팅한 TabView와 마찬가지로 바인딩된 selection 값으로 현재 선택으로 표시할 값을 제공한다고 한다.

 

default 스타일로 기본적인 사용방법을 이해하고 다른 스타일을 이미지로 확인해보자.

 

1. default

struct ContentView: View {
    enum Flavor: String, CaseIterable, Identifiable {
        case chocolate, vanilla, strawberry
        var id: Self { self }
    }


    @State private var selectedFlavor: Flavor = .chocolate
    
    var body: some View {
        List {
            Picker("Flavor", selection: $selectedFlavor) {
                Text("Chocolate").tag(Flavor.chocolate)
                Text("Vanilla").tag(Flavor.vanilla)
                Text("Strawberry").tag(Flavor.strawberry)
            }
        }
    }
}

 

실행결과

 

기본적인 Picker의 형태는 말그대로 선택하는 UI 구조체 요소로 클릭시 선택할 수 있는 값들이 나오게 된다.

 

레이블에 부제목 추가하기

Picker 매개변수로 이름을 지정하지 않고 label을 선언해주면 부제목을 만들 수 있다고 한다.

 

struct ContentView: View {
    enum Flavor: String, CaseIterable, Identifiable {
        case chocolate, vanilla, strawberry
        var id: Self { self }
    }


    @State private var selectedFlavor: Flavor = .chocolate
    
    var body: some View {
        List {
            Picker(selection: $selectedFlavor) {
                Text("Chocolate").tag(Flavor.chocolate)
                Text("Vanilla").tag(Flavor.vanilla)
                Text("Strawberry").tag(Flavor.strawberry)
            } label: {
                Text("Flavor")
                Text("Choose your favorite flavor")
            }
        }
    }
}

 

 

 

또한 반복문을 활용해 열거형을 배열화하여 만들 수도 있다.

Picker("Flavor", selection: $selectedFlavor) {
    ForEach(Flavor.allCases) { flavor in
        Text(flavor.rawValue.capitalized)
    }
}

 

또한 연관 데이터로 만들어서 활용할 수도 있다.

 

enum Topping: String, CaseIterable, Identifiable {
    case nuts, cookies, blueberries
    var id: Self { self }
}


extension Flavor {
    var suggestedTopping: Topping {
        switch self {
        case .chocolate: return .nuts
        case .vanilla: return .cookies
        case .strawberry: return .blueberries
        }
    }
}


@State private var suggestedTopping: Topping = .nuts

 

List {
    Picker("Flavor", selection: $suggestedTopping) {
        ForEach(Flavor.allCases) { flavor in
            Text(flavor.rawValue.capitalized)
                .tag(flavor.suggestedTopping)
        }
    }
    HStack {
        Text("Suggested Topping")
        Spacer()
        Text(suggestedTopping.rawValue.capitalized)
            .foregroundStyle(.secondary)
    }
}

 

 

2. segmented

List {
            Picker(selection: $selectedFlavor) {
                Text("Chocolate").tag(Flavor.chocolate)
                Text("Vanilla").tag(Flavor.vanilla)
                Text("Strawberry").tag(Flavor.strawberry)
            } label: {
                Text("Flavor")
                Text("Choose your favorite flavor")
            }
            
        }
        .pickerStyle(.segmented)

 

3. inline

List {
            Picker(selection: $selectedFlavor) {
                Text("Chocolate").tag(Flavor.chocolate)
                Text("Vanilla").tag(Flavor.vanilla)
                Text("Strawberry").tag(Flavor.strawberry)
            } label: {
                Text("Flavor")
                Text("Choose your favorite flavor")
            }
            
        }
        .pickerStyle(.inline)

 

 

4. menu

        List {
            Picker(selection: $selectedFlavor) {
                Text("Chocolate").tag(Flavor.chocolate)
                Text("Vanilla").tag(Flavor.vanilla)
                Text("Strawberry").tag(Flavor.strawberry)
            } label: {
                Text("Flavor")
                Text("Choose your favorite flavor")
            }
            
        }
        .pickerStyle(.menu)

 

5. wheel

 List {
            Picker(selection: $selectedFlavor) {
                Text("Chocolate").tag(Flavor.chocolate)
                Text("Vanilla").tag(Flavor.vanilla)
                Text("Strawberry").tag(Flavor.strawberry)
            } label: {
                Text("Flavor")
                Text("Choose your favorite flavor")
            }
            
        }
        .pickerStyle(.wheel)

 

 

정리

오늘은 Picker의 스타일들을 알아보았다.

모두 디자인적으로는 깔끔하나 특색있는 앱에서 사용하기에는 너무 밋밋한 감이지 않나 라는 생각이든다.