SwiftUI 通用下拉刷新视图

编程入门 行业动态 更新时间:2024-10-09 16:29:37
本文介绍了SwiftUI 通用下拉刷新视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个 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:关键词]

本文发布于:2023-03-30 21:56:28,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/787970.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:视图   SwiftUI

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!