Balbas Code

「Extra trailing closure passed in call」の解決方法

公開日: 2023-09-17 08:59:28
更新日: 2023-10-10 23:09:35

Extra trailing closure passed in callというエラーの治し方


Extra trailing closure passed in call
訳: 追加の末尾クロージャが呼び出しで渡されました。



こちらの関数呼び出しの部分でエラー。


PullToRefresh(onRefresh: viewModel.startRefreshing) {
List {
ForEach(viewModel.dataList) { item in
VStack(alignment: .leading) {
Text(item.DATE).font(.headline)
Text(item.SUBJECT ?? "").font(.headline)
Text(item.MAINTEXT ?? "").font(.subheadline)
}
}
}
}

 


 


参照元


struct PullToRefresh: UIViewRepresentable {
...
}

 


原因


このエラーは、関数やコンポーネントが想定外のクロージャ(無名関数やブロック)を渡された時に起きます。


 


変更前のPullToRefreshコンポーネントは、onRefresh以外のクロージャを受け取る能力がありませんでした。しかし、実際の利用時に、内部で表示すべきコンテンツを表すクロージャ(ListなどのSwiftUIのView)も渡そうとしていたため、このエラーが発生していました。


 


 


変更後


struct PullToRefresh<Content: View>: UIViewRepresentable {
var content: () -> Content

func makeUIView(context: Context) -> UIScrollView {
...
let hostingController = UIHostingController(rootView: content())
scrollView.addSubview(hostingController.view)
...
return scrollView
}
...
}

 


変更点の概要:
1. PullToRefreshの定義にジェネリック<Content: View>を追加。
2. 新しいプロパティcontent: () -> Contentを追加。
3. makeUIView(context:)内で、SwiftUIのView内容を表示するためのUIHostingControllerを作成し、そのViewをUIScrollViewに追加。





 変更点の解説:




  1. PullToRefreshの汎用性を高める: PullToRefresh<Content: View>というジェネリックを追加しました。これは、この部品が様々な種類のコンテンツ(画面の部分)を扱えるようにするためのものです。




  2. コンテンツの指定を可能に: content: () -> Contentという新しい変数を追加しました。これは関数のようなもので、呼び出されたときに何のコンテンツを表示するかを返します。この部分で、どんな画面の内容をPullToRefreshに表示するかを指定できます。




  3. 実際のコンテンツを表示する処理を追加: UIHostingControllerを使って、SwiftUIのコンテンツ(画面の部分)を実際に表示するようにしました。これは、SwiftUIのデザインを、通常のiOSの部品の中に取り入れるための特別なツールです。そして、このツールを使って作成したコンテンツを、スクロール可能な領域(UIScrollView)に追加しています。