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

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

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

Q&A

解決済

1回答

106閲覧

【SwiftUI】ForEachで繰り返している箇所に検索機能をつけたい。

coffeetaro

総合スコア1

0グッド

0クリップ

投稿2024/03/17 15:14

実現したいこと

コーヒー器具(ドリッパーとコーヒーサーバー)の組み合わせをシュミレーションするアプリを作っています。

やりたいことは以下の通りです。
①ContentViewではドリッパーとコーヒーサーバの画像を表示
②ドリッパーかコーヒーサーバーの画像をタップした時に、showSheet1(ドリッパーの選択画面)もしくはshowSheet2(コーヒーサーバーの選択画面)に遷移
③各々のSheetの検索欄にメーカー名を入力した時に画像の絞り込み
④各々のSheetで"選ぶ"ボタンを押してContentViewに戻ると組み合わせが変わる

この中の③でエラーが出てしまいます。
アプリ開発は初めてで調べながら作業していましたが、2ヶ月ほど調べても解決できなかったので質問させていただきます。

以下にContentViewからSheet1のコード全文を載せます。
import SwiftUI

struct Dripper: Identifiable {
var id = UUID()
var DI: String//ドリッパーイメージ変数
var DM: String//ドリッパーメーカー変数
var DG: String//ドリッパーギア変数
var DL: String//ドリッパーリンク変数
}

struct Server: Identifiable {
var id = UUID()
var SI: String//サーバーイメージ変数
var SM: String//サーバーメーカー変数
var SG: String//サーバーギア変数
var SL: String//サーバーリンク変数
}

struct ContentView: View {

@State private var dRipper = [ Dripper(DI: "a", DM: "ORIGAMI(オリガミ)", DG: "Dripper Air S", DL: "https://origami-kai.com/products/origami_dripperair_s?variant=42193295704306"), Dripper(DI: "b", DM: "CAFEC(カフェック)", DG: "フラワードリッパー", DL: "リンク2"), Dripper(DI: "c", DM: "Holzklotz(ホルツクロッツ)", DG: "コーヒーサーバー", DL: "リンク3"), Dripper(DI: "a", DM: "Hario(ハリオ)", DG: "v60", DL: "リンク4") ] @State private var sErver = [ Server(SI: "c", SM: "Holzklotz", SG: "コーヒーサーバー", SL: "https://www.kalita.co.jp/products/server"), Server(SI: "d", SM: "Karita", SG: "コーヒーサーバー", SL: "リンク2"), Server(SI: "a", SM: "cores", SG: "サーバー", SL: "リンク3"), Server(SI: "b", SM: "Saza", SG: "コーヒー", SL: "リンク4") ] @State var showSheet1: Bool = false @State var showSheet2: Bool = false @State var dripper:String = "1" @State var server:String = "2" @State private var searchText: String = "" var searchResult: [String] { if searchText.isEmpty { return dRipper } else { return dRipper.filter { $0.contains(searchText) } } } var body: some View { VStack { Header() Text("広告") } VStack{ Spacer() ZStack{ RoundedRectangle(cornerRadius: 7) .frame(width: UIScreen.main.bounds.size.width / 6 * 5, height: UIScreen.main.bounds.size.width / 6 * 4) .foregroundColor(.white) .shadow(radius: 7) Button(action: { showSheet1.toggle() },label: { Image(dripper) .resizable() .scaledToFit() .frame(width: UIScreen.main.bounds.size.width / 6 * 4, height: UIScreen.main.bounds.size.width / 6 * 4) }) } ZStack{ RoundedRectangle(cornerRadius: 7) .frame(width: UIScreen.main.bounds.size.width / 6 * 5, height: UIScreen.main.bounds.size.width / 6 * 4) .foregroundColor(.white) .shadow(radius: 7) Button(action: { showSheet2.toggle() },label: { Image(server) .resizable() .scaledToFit() .frame(width: UIScreen.main.bounds.size.width / 6 * 4, height: UIScreen.main.bounds.size.width / 6 * 4) }) } Spacer() } .sheet(isPresented: $showSheet1){ NavigationView{ List{ ForEach(dRipper) { Dripper in ZStack{ RoundedRectangle(cornerRadius: 7) .frame(width: UIScreen.main.bounds.size.width / 6 * 5, height: UIScreen.main.bounds.size.width / 6 * 2) .foregroundColor(.white) .shadow(radius: 7) HStack{ Image(Dripper.DI)//ドリッパーイメージ変数 .resizable() .scaledToFit() .frame(width: UIScreen.main.bounds.size.width / 7 * 2, height: UIScreen.main.bounds.size.width / 6 * 4) Spacer().frame(width: 19) VStack{ Text(Dripper.DM)//ドリッパーメーカー変数 .frame(maxWidth: 165, alignment: .leading) .font(.headline) Text(Dripper.DG)//ドリッパーギア変数 .frame(maxWidth: 165, alignment: .leading) HStack{ ZStack{ RoundedRectangle(cornerRadius: 7) .frame(width: UIScreen.main.bounds.size.width / 10 * 2, height: UIScreen.main.bounds.size.width / 20 * 2) .foregroundColor(.blue) .shadow(radius: 3) Button("選ぶ"){ dripper = Dripper.DI//ドリッパーイメージ変数 } .foregroundColor(.white) .font(.headline) } ZStack{ RoundedRectangle(cornerRadius: 7) .frame(width: UIScreen.main.bounds.size.width / 10 * 2, height: UIScreen.main.bounds.size.width / 20 * 2) .foregroundColor(.orange) .shadow(radius: 3) Button("買う"){ if let url = URL(string: Dripper.DL){ UIApplication.shared.open(url,options: [.universalLinksOnly: false],completionHandler: { completed in print(completed)}) }//ドリッパーリンク変数 } .foregroundColor(.white) .font(.headline) } } } } }//ドリッパーリスト }//ForEach .frame(maxWidth: .infinity) }//List }//NavigationView }//シート1

発生している問題・分からないこと

検索欄にメーカー名を入力した時に、画像の絞り込みをする関数を実装しようとするとエラーが出ます。

エラーメッセージ

error

1Cannot convert return expression of type '[Dripper]' to return type '[String]' 2Cannot convert return expression of type '[Dripper]' to return type '[String]' 3Value of type 'Dripper' has no member 'contains'

該当のソースコード

var searchResult: [String] { if searchText.isEmpty { return dRipper } else { return dRipper.filter { $0.contains(searchText) } } }

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

returnの後の部分をDripperに変えてみましたがエラーになりました。

補足

特になし

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

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

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

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

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

guest

回答1

0

ベストアンサー

他に問題点があるかどうかまで見られていないですが、
エラーになっている部分についてだけ回答しますね。

Cannot convert return expression of type '[Dripper]' to return type '[String]'

searchResult[String]型を返す必要があるのですが、[Dripper]型を返しているためエラーになっているようです。
var searchResult: [String] {...}のように、[String]型を返すように定義しているのは、
メーカー名のみ(の配列)を返す想定からでしょうか?
その場合、dRipper.map { $0.DM }のようにDripper型のメーカー名のみ(の配列)を返すように変換する感じかなと思いました。

Value of type 'Dripper' has no member 'contains'

$0.contains(...)のように記述していますが、Dripper型(ここでの$0はDripper型です)にはcontainsメソッドがないためエラーになっているようです。
”メーカー名を入力して検索”とのことですので、$0.DM.contains(...)かなと思いました。


上の内容を踏まえて、searchResultを修正したものを下に記載します。
.filter().map()の中の記述は、できるだけ型などが明確になるように、$0のような省略した記述ではなく、省略しない記述をしています。

swift

1 var searchResult: [String] { 2 if searchText.isEmpty { 3 return dRipper.map({ (dripperParam: Dripper) -> String in dripperParam.DM }) 4 } else { 5 return dRipper 6 .filter({ (dripperParam: Dripper) -> Bool in dripperParam.DM.contains(searchText) }) 7 .map({ (dripperParam: Dripper) -> String in dripperParam.DM }) 8 } 9 }

質問に対する回答になっていますでしょうか。
何かありましたらコメントくださいね。
頑張ってください。

投稿2024/03/18 03:09

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

coffeetaro

2024/03/18 15:38

解決しました! searchResultの型のお話と、containsメソッドのお話のおかげでやりたいことができました。 新しい気づきをありがとうございます! これからも挑戦を続けて必ずアプリを完成させます。 本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問