Avatar
Kishikawa Katsumi 5/31/2020 11:30 AM
コードが複雑すぎてコンパイルがいつまで経っても終わらないからコンパイラが途中で処理を中止してるんですね。 複雑すぎて、といっても見た目にはさほど複雑ではないコードでも起こるので大変です。 典型的には、クロージャを入れ子にしたり、Modifierをドットで繋いでメソッドチェーンをすると途中経過の戻り値や引数の型の関係をコンパイラがうまく推測できずに失敗するという事象です。
11:31 AM
解決するにはほとんどの場合、入れ子やメソッドチェーン(ドットで繋いで続けてメソッドを呼び出す)を分解してコンパイラに一つ一つの簡単なものとして与えるようにします。
11:32 AM
例でいうと import SwiftUI struct ContentView: View { var body: some View { VStack { Text("Hello SwiftUI Playground!") .font(.largeTitle) .foregroundColor(.blue) .padding() Button(action: {}) { HStack { Image(systemName: "suit.heart.fill") .foregroundColor(.red) Text("Let's Get Started!") .font(.headline) .foregroundColor(.white) } .padding(12) .background(Color.orange) .cornerRadius(8) } } } }
11:33 AM
^ こういう元のコードがあるとして、これは1つの大きなクロージャで中のクロージャは全部外側のクロージャの入れ子になっています。これがもっと多くの入れ子を含んだりするとそのエラーが起こります。
11:35 AM
なのでそうなったら、 import SwiftUI struct ContentView: View { var body: some View { let button = Button(action: {}) { HStack { Image(systemName: "suit.heart.fill") .foregroundColor(.red) Text("Let's Get Started!") .font(.headline) .foregroundColor(.white) } .padding(12) .background(Color.orange) .cornerRadius(8) } let text = Text("Hello SwiftUI Playground!") .font(.largeTitle) .foregroundColor(.blue) .padding() return VStack { button text } } } このように入れ子になっているクロージャを取り出していったん変数に格納してそれを同じように最後に組み合わせるようにします。 こうすると、もともと入れ子になっていた1つ1つのクロージャは簡単なクロージャでいったん型の推測が可能になるのでだいたい問題が解決します。無理な場合はもっと細かく分解します。
11:37 AM
SwiftUIでありがちなパターンだと、そのエラー以外でもどうせ10個以上のクロージャを入れ子に持つことはできないので、ちょっとした部品を作るだけでもすぐに制限に引っかかります。 なので上記の例にあげたくらいのコードになったらカスタムビューとしてコードを切り出すほうがうまくいきます。 ちょっとひとかたまりのコードができたら再利用するかどうかはあまり気にせず名前をつけてカスタムビューにしてしまうのがいいです。