Picker에서 nil 고르는 법 (feat. selection & tag)

SteadySlower·2022년 9월 1일
0

🤔 nil인 단어장을 선택하고 싶다.

Picker는 여러 선택지 중에 하나를 선택하는 입력을 받는 View입니다.

저의 경우는 단어장을 마감하는 기능을 만들면서 마감할 단어장에서 틀린 단어들을 이동할 단어장을 고를 때 Picker를 사용할 생각이었습니다.

하지만 문제가 있는 것이 틀린 단어를 이동하는 경우도 있지만 굳이 이동할 필요가 없을 경우도 있습니다. 하지만 이런 경우에는 기존에 Picker를 구현하는 방식으로는 nil을 고를 수가 없습니다.

selection과 tag

아래 코드를 잠시 보도록 하겠습니다. Picker에 보면 selection이라는 인자를 Binding으로 전달하게 되어 있습니다. Picker는 이 변수를 조작해서 Picker에서 선택된 정보를 전달합니다. 저는 이 변수를 단어장의 id 값으로 했습니다.

Picker 내부에는 Picker에서 보여줄 선택지를 구현해 놓을 수 있는데요. 각각의 선택지에 해당하는 View에는 tag라는 메소드를 적용할 수 있습니다. 이 tag는 Picker를 통해 해당 선택지를 골랐을 때 selection에 연결된 값에 어떤 값을 할당할 지 정의하는 역할을 합니다.

그렇다면 선택된 단어장이 없음을 나타내는 nil을 tag에 사용하기 위해서는 어떻게 해야 할까요?

  1. 먼저 selection에 전달하는 변수를 optional로 선언해야 합니다.
  2. 그리고 tag에 nil을 정의하는데 nil만 쓰면 안되고 아래처럼 타입 캐스팅으로 selection에 할당한 타입과 동일한 타입으로 캐스팅을 해주어야 합니다.
  3. 그리고 nil이 아닌 선택지들도 동일하게 옵셔널 타입으로 캐스팅을 해주어야 합니다.
//🎨 View
Picker("이동할 단어장 고르기", selection: $viewModel.selectedID) {
    Text("이동 안함")
        .tag(nil as String?)
    ForEach(viewModel.wordBooks) {
        Text($0.title)
            .tag($0.id as String?)
    }
}
//💾 ViewModel
@Published var selectedID: String?

마치며…

예전에 Picker에서 selection과 tag의 관계를 몰랐을 때는 주로 selection에 index 값을 저장할 Int 타입의 변수를 많이 사용했고 내부의 선택지도 index를 이용해서 많이 구현했었는데요.

tag를 적절하게 사용하면 원하는 타입을 변수에서 사용할 수 있을 뿐만 아니라 nil 값을 선택할 수도 있습니다.

profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.

0개의 댓글