apple/SwiftUI & Combine

[SwiftUI] Picker, segmentedStyle (feat. enum CaseIterable)

lgvv 2022. 5. 23. 15:53

Picker,  segmentedStyle (feat. enum CaseIterable)

 

(feat. enum CaseIterable)의 경우에는 따로 enum에 대해서 사용하는 방식을 포스팅 할 예정이지만, 그 전에 어떻게 사용하는지 간략하게 사용법? 정도는 나와있어서 참고해보면 좋다.

 

이번에는 코드를 한번 보자!

✅ Picker, segmentedStyle에 대해서 알아보자.

import SwiftUI


struct ContentView: View {
    
    @State private var selectionValue = 0
    
    let myColorArray = ["레드", "그린", "블루"]
    
    func changeColor(index: Int) -> Color {
        switch index {
        case 0:
            return Color.red
        case 1:
            return Color.green
        case 2:
            return Color.blue
        default:
            return Color.red
        }
    }
    
    var body: some View {
        
        VStack(alignment: .center){
            
            // 원을 그리기 위한 코드
            Circle()
                .foregroundColor(self.changeColor(index: selectionValue))
                .frame(width: 50, height: 50)
            
            Text("선택된 값 : \(selectionValue)")
            Text("선택된 색깔 : \(myColorArray[selectionValue])")
            
            Picker(selection: $selectionValue, // Picker의 인덱스 바인딩
                             label: Text(""),
                          content: {
                          Text("레드").tag(0)
                          Text("그린").tag(1)
                          Text("블루").tag(2)
                          }).pickerStyle(SegmentedPickerStyle()) // 픽커 스타일을 지정
            
            Picker(selection: $selectionValue,
                          label: Text(""),
                       content: {
                       Text("레드").tag(0)
                       Text("그린").tag(1)
                       Text("블루").tag(2)
            })
                .frame(width: 50, height: 100)
                .clipped() // 픽커에서 줄을 없애기 위한 코드
                .padding(10)
                // border은 바깥 테두리에 대한 코드
                .border(self.changeColor(index: selectionValue), width: 10) 
            
          
            
        }.padding(.horizontal, 50)
        
       
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

예시

 

 

✅ 이번에는 조금 더 Advanced한 것들을 진행해보자.

import SwiftUI

// enum에서 CaseIterable를 사용하요 allCase로 for문을 적용할 수 있다! 
enum School : String, CaseIterable {
    case elementary = "초등학교"
    case middle = "중학교"
    case high = "고등학교"
}

// swiftUI Identifiable통해 아이디를 지정할 수 있다.
struct MyFriend : Identifiable, Hashable {
    var id = UUID() // Identifiable통해 고유 아이디를 지정하는 표현
    var name : String
    var school : School   
}

func prepareData() -> [MyFriend]{
    var newList = [MyFriend]()
    
    for i in 0...20 {
    	// 여기서 allCases를 사용!
        let newFriend = MyFriend(name: "내 친구 \(i)", school: School.allCases.randomElement()!)
        newList.append(newFriend)
    }
    return newList
}


struct MyFilteredList: View {
    
    @State private var filteredValue = School.elementary
    
    @State private var myFriendsList = [MyFriend]()
    
    // 생성자 메소드
    init() {
        _myFriendsList = State(initialValue: prepareData()) // 초기값을 이렇게 넣을 수 있다니! 
    }
    
    var body: some View{
        VStack{
            Text("선택된 필터 : \(filteredValue.rawValue)")
            
            Picker(selection: $filteredValue,
               label: Text(""),
            content: { // items에 대한 정보들
                Text("초등학교").tag(School.elementary)
                Text("중학교").tag(School.middle)
                Text("고등학교").tag(School.high)
            }).pickerStyle(SegmentedPickerStyle())
            
            List {
                ForEach(myFriendsList.filter{ filterTerm in
//                    $0.school == filteredValue // 클로저로 처리 가능 
                    filterTerm.school == filteredValue
                }) { friendItem in
                    GeometryReader{ geometryProxy in
                        HStack{
                            Text("name: \(friendItem.name)")
                                .frame(width: geometryProxy.size.width / 3) 
                            Divider()
                            Text("school: \(friendItem.school.rawValue)")
                                .frame(width: geometryProxy.size.width / 2)
                        }
                    }
                }
            }
            
//            List{
//                ForEach(myFriendsList, id: \.self){ friendItem in
//
//                    GeometryReader{ geometryProxy in
//                        HStack{
//                            Text("name: \(friendItem.name)")
//                                .frame(width: geometryProxy.size.width / 3)
//                            Divider()
//                            Text("school: \(friendItem.school.rawValue)")
//                                .frame(width: geometryProxy.size.width / 2)
//                        }
//                    }
//                }
//            }
            
        }
    }
}

 

🟠 요즘 많이 주목하는게 enum이다.

enum에 CaseIterable을 사용하여 allCases를 사용하는 코드가 정말 간결하고 코드적으로 좋다고 느끼고 있다.

이건 나중에 자세히 정리할 것이지만 아무튼 정 말 좋 아!

 

결과에 대한 UI

 

(참고)

https://www.hohyeonmoon.com/blog/swiftui-tutorial-picker/

 

SwiftUI Picker 사용하기 | Hohyeon Moon

Hohyeon Moon iOS developer. Code for a happier life. Resume

www.hohyeonmoon.com

https://seons-dev.tistory.com/34

 

SwiftUI : Picker / Picker Style / Section

Picker 와 Section 에 대해 알아보도록 합시다. Picker selection binding , label , content 를 표시할 내용을 제공하여 Picker 를 만듭니다. selection parameter 를 현재 selection 으로 표시할 값을 제공하는..

seons-dev.tistory.com