SwiftUI

SwiftUI Segmented Control

Daesiker 2021. 4. 1. 17:24
반응형

개요

UIKit에서 UISegmentedControl은 SwiftUI의 Picker와 같은 역할을 한다. 이번에는 Picker 컴포넌트와 UISegmentedControl 함수를 통해 서로 다른 이미지를 View에 표시해주는 간단한 프로젝트를 해볼 예정이다.

코드

SideOfTheForce

enum SideOfTheForce: String, CaseIterable {
    case light = "Light"
    case grey = "Grey"
    case dark = "Dark"
}

Picker의 타이틀을 정해주는 String 타입의 enum이다. light, grey, dark 총 3가지의 case가 있고 이것을 String값으로 반환해준다. CaseIterable 프로토콜을 채용하면 안에 있는 값들을 배열처럼 사용할 수 있다. 이것은 밑에서 다시 다룰 것이다.

HeroImageView

struct HeroImageView: View {
    var heroName: String
    
    var body: some View {
        Image(heroName)
            .resizable()
            .frame(width: 250, height: 400)
            .shadow(color: .white, radius: 100)
    }
}

String 타입의 heroName 변수를 선언한뒤 body에 해당 값에 맞는 이미지를 만들어 준다. .shadow 속성을 통해 그림자를 넣어 주었는데 제일 앞에 gif를 자세히 보면 캐릭터 주변이 살짝 누리끼리한 것을 알 수 있다. 여기에 컬러를 흰색으로 주고 radius를 100을 줌으로써 해당 효과를 넣을 수 있다.

ChosenHereView

struct ChosenHereView: View {
    var selectedSide: SideOfTheForce
    
    var body: some View {
        switch selectedSide {
        case .light:
            HeroImageView(heroName: "anakin")
        case .grey:
            HeroImageView(heroName: "ahsoka")
        case .dark:
            HeroImageView(heroName: "vader")
            
        }
    }
}

앞서 만든 SideOfTheForce 타입의 selectedSide 변수를 선언해 주었다. 그다음에 selectedSide의 case에 맞게 heroName 파라미터의 값을 변경하여 HeroImageView를 넣어준다.

ContentView

struct ContentView: View {
    
    init() {
        UISegmentedControl.appearance().selectedSegmentTintColor = .yellow
        UISegmentedControl.appearance().setTitleTextAttributes([.foregroundColor: UIColor.black], for: .selected)
    }
    @State private var selectedSide: SideOfTheForce = .dark
    
    var body: some View {
        NavigationView {
            VStack {
                Picker("Choose a Side", selection: $selectedSide) {
                    ForEach(SideOfTheForce.allCases, id: \.self) {
                        Text($0.rawValue)
                    }
                }
                .pickerStyle(SegmentedPickerStyle())
                .padding()
                
                Spacer()
                ChosenHereView(selectedSide: selectedSide)
                Spacer()
            }
            .navigationTitle("Choose a Side")
        }
    }
}

우선 SideOfTheForce 타입의 selectedSide를 @State로 감싸준 후 초기 값을 .dark로 선언하였다. 이제 이 selectedSide가 바뀌면 이미지가 바뀔 수 있도록 body 코드를 짜면 된다.

우선 NavigationView와 VStack으로 body안의 내용을 감싼뒤에 Picker 컴포넌트를 선언한다. Picker의 첫번째 파라미터는 해당 Picker의 키값이다. 이 Picker을 다른 함수에서 사용하고 싶을 때 이 키값을 통해 접근이 가능하다. selection은 현재 선택한 값이 무엇인지 알려주는 함수이다. 여기에 $selectedSide를 입력함으로써 selectedSide가 선택한 값에 맞게 바뀌게 할 수 있다. 그 다음에 Picker안에 어떤 컨텐츠가 있는지 알려줘야 하는데 여기서는 반복문을 통해 SideOfTheForce의 모든 케이스들을 가져왔다. SideOfTheForce에 CaseIterable 프로토콜을 채용함으로써 배열처럼 사용할 수 있게 되었고 allCases 함수를 통해 안에 내용을 하나씩 가져올 수 있다. $0에 대해서 잘 모른다면 클로져를 공부하고 오는 것을 추천한다. 여기서는 $0이 .light라면 $0.rawValue는 "Light"이다. 그 다음에 pickerStyle 속성에 SegmentPickerStyle()을 선언하면 Picker가 가로 형태로 나온다.

init() 부분에서는 UISegmentControl 함수를 이용해서 해당 Picker에 TintColor와 TextColor을 꾸며준다. 여기서 선택한 요소의 배경색을 노란색으로 텍스트는 검정색으로 바꾸어준다.

반응형

'SwiftUI' 카테고리의 다른 글

SwiftUI Link  (0) 2021.04.03
SwiftUI Binding, Environment  (0) 2021.03.31
SwiftUI Profile View  (0) 2021.03.30
SwiftUI 사진 가져오기(3)  (0) 2021.03.20
SwiftUI 사진 가져오기(2)  (0) 2021.03.19