问题描述
我有这个 CustomScrollView,它包装了我的 HomeView,如果你拉下它,它会获取新数据.它工作正常,但问题是我想在多个视图中重用它,我不想为我的每个视图创建一个副本.我试图这样做 var rootView: View
但它抛出一个错误说 View is not convertible to HomeView
.
I have this CustomScrollView which wraps my HomeView and if you pull down it fetches new data.
It works fine but the thing is that I want to reuse this in multiple views and I do not want to create a copy of this for each of my views.
I have tried to do this var rootView: View
but it throws an error saying View is not convertible to HomeView
.
所以有两件事女巫应该是通用的.HomeView()
和 HomeViewModel
.
So there are two thing witch should be generic. HomeView()
and HomeViewModel
.
知道如何实现这一目标吗?
Any idea how to achieve that?
struct CustomScrollView : UIViewRepresentable {
var width : CGFloat
var height : CGFloat
let viewModel = HomeViewModel()
func makeCoordinator() -> Coordinator {
Coordinator(self, homeViewModel: viewModel)
}
func makeUIView(context: Context) -> UIScrollView {
let control = UIScrollView()
control.refreshControl = UIRefreshControl()
control.refreshControl?.addTarget(context.coordinator, action: #selector(Coordinator.handleRefreshControl), for: .valueChanged)
let childView = UIHostingController(rootView: HomeView())
childView.view.frame = CGRect(x: 0, y: 0, width: width, height: height)
control.addSubview(childView.view)
return control
}
func updateUIView(_ uiView: UIScrollView, context: Context) { }
class Coordinator: NSObject {
var control: CustomScrollView
var homeViewModel: HomeViewModel
init(_ control: CustomScrollView, homeViewModel: HomeViewModel) {
self.control = control
self.homeViewModel = homeViewModel
}
@objc func handleRefreshControl(sender: UIRefreshControl) {
sender.endRefreshing()
homeViewModel.loadPackages()
}
}
}
推荐答案
这是可能的方法(使用 Xcode 11.4 编译)
Here is possible approach (compiled with Xcode 11.4)
用法:
CustomScrollView(width: 100, height: 100,
viewModel: HomeViewMode()) {
HomeView()
}
通用类型:
protocol CustomViewModel {
func loadPackages()
}
// It is used generic ViewBuilder pattern for content
struct CustomScrollView<Content: View, VM: CustomViewModel> : UIViewRepresentable {
var width : CGFloat
var height : CGFloat
let viewModel: VM
let content: () -> Content
init(width: CGFloat, height: CGFloat, viewModel: VM, @ViewBuilder content: @escaping () -> Content) {
self.width = width
self.height = height
self.viewModel = viewModel
self.content = content
}
func makeUIView(context: Context) -> UIScrollView {
let control = UIScrollView()
control.refreshControl = UIRefreshControl()
control.refreshControl?.addTarget(context.coordinator, action: #selector(Coordinator.handleRefreshControl), for: .valueChanged)
let childView = UIHostingController(rootView: content())
childView.view.frame = CGRect(x: 0, y: 0, width: width, height: height)
control.addSubview(childView.view)
return control
}
func updateUIView(_ uiView: UIScrollView, context: Context) { }
class Coordinator: NSObject {
var control: CustomScrollView<Content, VM>
var viewModel: VM
init(_ control: CustomScrollView, viewModel: VM) {
self.control = control
self.viewModel = viewModel
}
@objc func handleRefreshControl(sender: UIRefreshControl) {
sender.endRefreshing()
viewModel.loadPackages()
}
}
}
这篇关于SwiftUI 通用下拉刷新视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论