본문 바로가기

학습 노트/Swift UI (2022)

18. Stepper & Picker & Date Picker & Color Picker

Stepper


 

Apple Developer Documentation

 

developer.apple.com

struct ControlsView: View {
    @State private var stepperVal = 0

    var body: some View {
        VStack {
            Spacer()

            Image(systemName: "gear")
                .resizable()
                .frame(width: CGFloat(stepperVal) * 5, height: CGFloat(stepperVal) * 5, alignment: .center)
                .scaledToFit()

            Spacer()

            Stepper() {
                Label {
                    Text("value is \(stepperVal) and real gear change to \(stepperVal * 5)")
                } icon: {
                    Image(systemName: "gear")
                }

            } onIncrement: {
                if stepperVal >= 100 {
                    stepperVal = 0
                } else {
                    stepperVal += 10
                }
            } onDecrement: {
                if stepperVal <= 0 {
                    stepperVal = 100
                } else {
                    stepperVal -= 10
                }
            }
            .padding()
        }
    }
}

Stepper는 숫자이면서 고정된 크기로 변화하는 값에 주로 사용하는 View다.
위와 같이 Label과 기능을 직접 구현하는 것도 가능하고

struct ControlsView: View {
    @State private var stepperVal = 0

    var body: some View {
        VStack {
            Spacer()

            Image(systemName: "gear")
                .resizable()
                .frame(width: CGFloat(stepperVal) * 5, height: CGFloat(stepperVal) * 5, alignment: .center)
                .scaledToFit()

            Spacer()

            Stepper("value is \(stepperVal) and real gear change to \(stepperVal * 5)", value: $stepperVal, in: 0...100, step: 10)
                .padding()
        }
    }
}

생성자를 사용해 기본 UI를 간편하게 사용할 수도 있다.

 

Picker


 

Apple Developer Documentation

 

developer.apple.com

struct ControlsView: View {
    enum valList: String, CaseIterable {
        case apple = "apple"
        case banana = "banana"
        case carrot = "carrot"
        case durian = "durian"
        case eggplant = "eggplant"
    }

    @State private var pickerVal: valList = .apple

    var body: some View {
        VStack{
            Text(pickerVal.rawValue.capitalized)

            Picker(selection: $pickerVal) {
                Text("apple").tag(valList.apple)
                Text("banana").tag(valList.banana)
                Text("carrot").tag(valList.carrot)
                Text("durian").tag(valList.durian)
                Text("eggplant").tag(valList.eggplant)
            } label: {
                Text(pickerVal.rawValue)
            }
        }
    }
}

Picker는 여러 옵션들을 나열하고 하나를 고르는 경우 사용하는 View다.
이전의 Confirmation Dialog와 마찬가지로 옵션을 개별로 구현해야 하기 때문에 forEach를 사용하는 것이 도움이 된다.
개선된 코드는 다음과 같다.

struct ControlsView: View {
    enum valList: String, CaseIterable, Identifiable {
        case apple = "apple"
        case banana = "banana"
        case carrot = "carrot"
        case durian = "durian"
        case eggplant = "eggplant"
        var id: Self { self }
    }

    @State private var pickerVal: valList = .apple

    var body: some View {
        VStack{
            Text(pickerVal.rawValue.capitalized)

            Picker(selection: $pickerVal) {
                ForEach(valList.allCases) { val in
                    Text(val.rawValue.capitalized)
                }
            } label: {
                Text(pickerVal.rawValue)
            }
        }
    }
}

ForEach를 쓸 때는 대상이 Identifiable 프로토콜을 채용해야 한다는 것을 명심하자.

struct ControlsView: View {
    enum valList: String, CaseIterable, Identifiable {
        case apple = "apple"
        case banana = "banana"
        case carrot = "carrot"
        case durian = "durian"
        case eggplant = "eggplant"
        var id: Self { self }
    }

    @State private var pickerVal: valList = .apple

    var body: some View {
        NavigationView {
            List{
                Text(pickerVal.rawValue.capitalized)

                Picker(selection: $pickerVal) {
                    ForEach(valList.allCases) { val in
                        Text(val.rawValue)
                    }
                } label: {
                    Text(pickerVal.rawValue)
                }
            }
        }
    }
}

Picker는 List에 Embed 될 때 기본 스타일이 적용되는데,
선택 가능한 옵션이 있음을 알리는 꺽쇠를 표시하고, 선택 가능한 옵션을 새 창에 표시한다.

pickerStyle modifier를 사용해 여러 형태의 picker를 사용할 수 있으며
각각은 아래와 같다.

 

Date Picker


 

Apple Developer Documentation

 

developer.apple.com

struct ControlsView: View {
    @State private var pickerVal = Date()
    var body: some View {
        List {
            Text("\(pickerVal)")

            DatePicker("Date", selection: $pickerVal, displayedComponents: [.date, .hourAndMinute])
        }
    }
}

날짜를 선택할 때 사용하는 View다.
기본적으로 사용하는 생성자의 파라미터는 다음과 같다.

  • title
    제목
  • selection
    State Variable
  • in
    범위, 보통은 기본값으로 둔다.
  • displayComponents
    표시할 컴포넌트, 배열로 전달한다.
struct ControlsView: View {
    @State private var pickerVal = Date()

    let dateFormatter: DateFormatter = {
            let df = DateFormatter()
            df.dateStyle = .medium
            return df
        }()

    var body: some View {
        List {
            HStack {
                Spacer()
                Text("\(dateFormatter.string(from: pickerVal))")
                Spacer()
            }

            HStack {
                Spacer()

                DatePicker("Date", selection: $pickerVal, displayedComponents: [.date, .hourAndMinute])
                    .labelsHidden()

                Spacer()
            }
        }
    }
}

Date 타입을 바인딩해 사용하기 때문에 dateFormatter를 그대로 사용할 수 있다.
'labelIsHidden' modifier를 사용해 title을 숨겨 조금 더 깔끔한 분위기를 만들 수도 있다.

현재 적용된 Style은 기본값인 Automatic으로 context에 따라 자동으로 선택되는 Style 중 'compact'에 해당한다.
이외의 두가지를 더 선택할 수 있는데, 각각 아래와 같다.

 

Color Picker


 

Apple Developer Documentation

 

developer.apple.com

struct ControlsView: View {
    @State private var pickerVal = Color.red

    var body: some View {
        pickerVal
            .ignoresSafeArea()
            .overlay {
                ColorPicker(selection: $pickerVal, supportsOpacity: true) {
                    Text("Select Color")
                }
                .padding()
            }
    }
}

색상을 선택할 때 사용할 수 있는 View다.
생성자에서 사용하는 파라미터는 다음과 같다.

  • title
    제목
  • selection
    State Variable
  • supportOpacity
    투명도 지원 여부

Color Picker는 Custom이 불가능하다.

'학습 노트 > Swift UI (2022)' 카테고리의 다른 글

20. Image & SFSymbol & AsyncImage  (0) 2022.10.06
19. Color & Material  (1) 2022.10.06
17. Toggle & Slider & ProgressView  (0) 2022.10.05
16. Button & Link & Menu  (0) 2022.10.02
14 ~ 15. TextField & TextField Style & TextEditor  (0) 2022.09.28