質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1349閲覧

独立したenumに対応したPickerをもつviewを作りたい

k-kuma.esd

総合スコア21

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/11/01 07:00

独立したenumに対応したPickerをもつviewを作りたい

SwiftUIで複数のenumに対応したPickerを作りたいと思っています。

enumを要素にするPickerは以下の様にすれば簡単に作る事ができます。

Swift

1enum Options1: String, Identifiable, CaseIterable { 2 case option1_1 = "OptionValue1_1" 3 case option1_2 = "OptionValue1_2" 4 case option1_3 = "OptionValue1_3" 5 var id: String { self.rawValue } 6} 7 8 9struct PartContentView: View { 10 @Binding var selectedOption: Options1 11 12 var body: some View { 13 VStack { 14 Picker("Select option", selection: $selectedOption) { 15 ForEach(Options1.allCases, id:.id) { option in 16 Text(option.rawValue.capitalized) 17 .tag(option) // (1) 18 } 19 } 20 } 21 } 22} 23 24struct ContentView: View { 25 @State private var selectedOption: Options1 = .option1_1 26 27 var body: some View { 28 VStack { 29 PartContentView(selectedOption: $selectedOption) 30 .padding() 31 32 Text("selected option value is (selectedOption.rawValue)") 33 .padding() 34 } 35 .padding() 36 } 37}

このとき、Option1と同じインターフェースを持つ

enum Options2: String, Identifiable, CaseIterable

を定義したとして、

"struct PartContentView"がOption1でもOption2でも動作するようにするは"PartContentView"をどう書けばいいのでしょうか。

PartContentViewにGenericsでenumの持つプロトタイプを提示すればいいかと思い、以下の様にしてみたのですが、

Swift

1enum Options1: String, Identifiable, CaseIterable, Hashable { 2 case option1_1 = "OptionValue1_1" 3 case option1_2 = "OptionValue1_2" 4 case option1_3 = "OptionValue1_3" 5 var id: String { self.rawValue } 6} 7 8enum Options2: String, Identifiable, CaseIterable , Hashable { 9 case option2_1 = "OptionValue2_1" 10 case option2_2 = "OptionValue2_2" 11 case option2_3 = "OptionValue2_3" 12 var id: String { self.rawValue } 13} 14 15 16struct PartContentView<T: Identifiable & CaseIterable & Hashable>: View { 17 @Binding var selectedOption: T 18 19 var body: some View { 20 VStack { 21 Picker("Select option", selection: $selectedOption) { 22 ForEach(T.allCases, id:.self) { option in 23 Text(option.rawValue) 24 .tag(option) // (1) 25 } 26 } 27 } 28 } 29}

ForEach(T.allCases, id:.self) { option in
Text(option.rawValue)

の行で

  • Generic struct 'ForEach' requires that 'T.AllCases' conform to 'RandomAccessCollection'
  • Value of type 'T' has no member 'rawValue'

とエラーになってしまい、うまくいきません。

SwiftUIにはまだ不慣れな部分が多く、そもそもの流儀に従っていない(Swiftyでない?)のであれば、どのようにするのがスマートでしょうか。

補足情報(FW/ツールのバージョンなど)

xcodeのバージョンは13.1、swiftのバージョンは5です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

解決しました。

・「Generic struct 'ForEach' requires that 'T.AllCases' conform to 'RandomAccessCollection'」
については、

● Compile error: Generic struct ‘ForEach’ requires that ‘S.AllCases’ conform to ‘RandomAccessCollection’: but .allCases is fine when using it directly
https://forums.swift.org/t/compile-error-generic-struct-foreach-requires-that-s-allcases-conform-to-randomaccesscollection-but-allcases-is-fine-when-using-it-directly/38417

を参考(というか、答えが書いてあるわけですが)に

ForEach(T.allCases, id:.self)

ForEach(Array(T.allCases), id:.self)

とすることで解決しました。

・Value of type 'T' has no member 'rawValue'

については

enumをCustomStringConvertibleに準拠させて、rawValueの代わりにdescriptionを使う事で解決しました。

投稿2022/03/01 07:59

k-kuma.esd

総合スコア21

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問