「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に追加。
変更点の解説:
PullToRefreshの汎用性を高める:PullToRefreshに<Content: View>というジェネリックを追加しました。これは、この部品が様々な種類のコンテンツ(画面の部分)を扱えるようにするためのものです。
コンテンツの指定を可能に:
content: () -> Contentという新しい変数を追加しました。これは関数のようなもので、呼び出されたときに何のコンテンツを表示するかを返します。この部分で、どんな画面の内容をPullToRefreshに表示するかを指定できます。
実際のコンテンツを表示する処理を追加:
UIHostingControllerを使って、SwiftUIのコンテンツ(画面の部分)を実際に表示するようにしました。これは、SwiftUIのデザインを、通常のiOSの部品の中に取り入れるための特別なツールです。そして、このツールを使って作成したコンテンツを、スクロール可能な領域(UIScrollView)に追加しています。