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

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

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

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Q&A

1回答

4940閲覧

値の上書きをしたい Type of expression is ambiguous without more context

citam1660

総合スコア4

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

0グッド

0クリップ

投稿2019/12/22 19:19

編集2019/12/22 19:25

前提・実現したいこと

SwiftUIで、通常と異なる値が加わった音楽プレーヤーを作ろうと思っています。
リストViewで該当の曲を選択すると、該当の曲の情報が再生画面Viewの値を上書きする(該当の曲の情報と再生画面の情報が同じになる)ようにしたいです。
別の画面に移行しても、下のバーに再生中の曲の情報を載せていたいので、情報を上書きした方がいいのではないかと思いました。

発生している問題・エラーメッセージ

Type of expression is ambiguous without more context

エラーを直す方法が分かりません

該当のソースコード

DiaryList.swift

1import SwiftUI 2 3struct MusicData: Identifiable { 4 var id: String = UUID().uuidString 5 var makeDateString: String 6 var musicTitle: String 7 var memo: String 8 var favorite: Bool 9 var jacket: String 10 var activity: Double 11 var joysad: Double 12 var hopefear: Double 13 var angercalm: Double 14} 15 16struct DiaryList: View { 17 var modelData: [MusicData] = [ 18 MusicData(makeDateString: "20190703", musicTitle: "楽しい", memo: "めちゃ楽しい", favorite: true, jacket: "", activity: -1, joysad: -1, hopefear: -1, angercalm: -1), 19 MusicData(makeDateString: "20190704", musicTitle: "", memo: "", favorite: false, jacket: "", activity: -1, joysad: 1, hopefear: 0, angercalm: -1) 20 ] 21 22 var body: some View { 23 NavigationView { 24 List { 25 ForEach(modelData) { MusicData in 26 NavigationLink(destination: PlayView() 27 ) { 28 HStack(alignment: .center, spacing: 3) { 29 Image(MusicData.jacket) 30 .resizable() 31 .frame(width: 64, height: 64) 32 33 VStack(alignment: .leading, spacing: 3.0) { 34 35 Text(MusicData.makeDateString) 36 .font(.headline) 37 .fontWeight(.semibold) 38 .lineLimit(0) 39 40 Text(MusicData.musicTitle) 41 .font(.subheadline) 42 .fontWeight(.regular) 43 .foregroundColor(Color.gray) 44 .lineLimit(0) 45 } 46 .padding([.top, .leading, .bottom], 12.0) 47 48 Spacer() 49 } 50 .onTapGesture(perform: 51 PlayView().makeDateString = MusicData.makeDateString) 52 //↑ここでエラーメッセージが出ます↑ 53 } 54 } 55 } 56 } 57 } 58} 59 60struct DiaryList_Previews: PreviewProvider { 61 static var previews: some View { 62 ForEach(["iPhone SE", "iPhone 8", "iPhone Xs"], id: .self) { deviceName in 63 DiaryList() 64 .environment(.locale, .init(identifier: "ja")) 65 .previewDevice(PreviewDevice(rawValue: deviceName)) 66 .previewDisplayName(deviceName) 67 } 68 } 69} 70

PlayView.swift

1import SwiftUI 2import UIKit 3 4struct PlayView: View { 5 6 @State var playingtime: Double = 5 7 @State var playing = false 8 9 @State var pressinfo = false 10 11 @State var makeDateString: String = "再生停止中" 12 @State var musicTitle: String = "曲名未設定" 13 @State var memo: String = "" 14 @State var favorite: Bool = false 15 @State var jacket: String = "jacket" 16 @State var activity: Double = 0 17 @State var joysad: Double = 0 18 @State var hopefear: Double = 0 19 @State var angercalm: Double = 0 20 21 var body: some View { 22 GeometryReader { geometry in 23 VStack(alignment: .leading) { 24 25 Spacer() 26 27 HStack { 28 VStack(alignment: .leading, spacing: 4.0){ 29 Text("(self.makeDateString)") 30 .font(.headline) 31 .lineLimit(0) 32 33 Text("(self.musicTitle)") 34 .font(.subheadline) 35 .foregroundColor(Color.gray) 36 .lineLimit(0) 37 } 38 39 Spacer() 40 41 Button(action:{ 42 self.pressinfo = true 43 }){ 44 Image("info") 45 .resizable() 46 .aspectRatio(1, contentMode: .fit) 47 .frame(width: 42, height: 42) 48 } 49 .sheet(isPresented: self.$pressinfo, content: { 50 explanation() 51 }) 52 53 } 54 55 Spacer() 56 57 HStack { 58 Spacer() 59 60 Image(self.jacket) 61 .resizable() 62 .aspectRatio(1, contentMode: .fit) 63 .shadow(radius:5) 64 65 Spacer() 66 } 67 .frame(maxHeight: geometry.size.width * 0.8) 68 69 Spacer() 70 71 72 VStack(spacing: 0.0){ 73 Slider(value: self.$playingtime, in: 0...15) 74 75 HStack { 76 Text("(self.playingtime)") 77 .font(.caption) 78 79 Spacer() 80 81 Text("00:15") 82 .font(.caption) 83 } 84 } 85 86 Spacer() 87 88 HStack{ 89 Spacer() 90 Button(action:{ 91 92 }){ 93 PreviousPlayBadge() 94 } 95 .frame(width: geometry.size.width / 4, height: geometry.size.width / 4) 96 97 Button(action:{ 98 self.playing.toggle() 99 }){ 100 if(self.playing){ 101 PauseBadge() 102 } else { 103 PlayBadge() 104 } 105 } 106 .frame(width: geometry.size.width / 4, height: geometry.size.width / 4) 107 108 Button(action:{ 109 110 }){ 111 NextPlayBadge() 112 } 113 .frame(width: geometry.size.width / 4, height: geometry.size.width / 4) 114 Spacer() 115 } 116 117 Spacer() 118 119 } 120 } 121 .padding(.horizontal) 122 .navigationBarTitle(Text("再生中"), displayMode: .inline) 123 .navigationBarItems(trailing: Button(action: { 124 125 }) { 126 Text("Action") 127 }) 128 } 129} 130 131struct PlayView_Previews: PreviewProvider { 132 static var previews: some View { 133 ForEach(["iPhone SE", "iPhone 8", "iPhone Xs Max"], id: .self) { deviceName in 134 PlayView() 135 .environment(.locale, .init(identifier: "ja")) 136 .previewDevice(PreviewDevice(rawValue: deviceName)) 137 .previewDisplayName(deviceName) 138 } 139 } 140} 141 142

試したこと

『MusicData.makeDateString』の部分のコードを、『modelData.MusicData.makeDateString』『self.modelData.MusicData.makeDateString』『MusicData().makeDateString』などいろいろ変更して試しました。

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

Xcode Version 11.3 (11C29)

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

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

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

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

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

guest

回答1

0

エラーは型を確定できないという意味です.

swift

1.onTapGesture(perform: 2 PlayView().makeDateString = MusicData.makeDateString)

と、() -> Void型の関数を渡すところにいきなり文を書いているのが原因で、

.onTapGesture(perform: { PlayView().makeDateString = MusicData.makeDateString })

としたら回避できると思います(別のエラーがでるかもしれません)。

ただ、このやり方でPlayViewに値を伝えることはできません。上記の文は、新しくPlayViewを作って値を与えて、それを捨てる、というコードなので、思っているような動作にはなりません。

しかし、問題はこの事ではなくて、そもそも、PlayViewの内部状態であるmakeDateStringに対して、別のビューであるDiaryListから書き込みを行うというような使い方が間違っています。

@Stateは内部状態の保持用で、そのビューの内部だけで完結するべきものです。
makeDateStringmusicTitleのように外部から与えるべき情報に@Stateを使うのは正しくありません。これらは、@Stateではなくて、@ObservedObjectまたは@EnvironmentObjectとして外部から与える必要があります。

SwiftUIは新しい技術でこれまでとは違うので、使うならきちんと最初からどこかで学ぶ事をお勧めします。
残念ながら、私は、これがいいと提示できる情報を持っていませんが、WWDCのビデオくらいは見たほうがいいかなと思います。日本語の字幕が出せます。なお、ビデオでは@ObjectBindingとして出てきますが、これが今は@ObservedObjectと名前が変わっています。

WWDC2019 Introducing SwiftUI

他にも関連ビデオが複数あり、上記ページの下の方に一覧で出ているので、見てみる事をお勧めします。

投稿2019/12/23 06:41

eytyet

総合スコア803

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問