SwiftUI Generi c Pull для обновления sh просмотр - PullRequest
1 голос
/ 22 апреля 2020

У меня есть этот CustomScrollView, который оборачивает мой HomeView, и если вы опускаете его, он получает новые данные. Это работает нормально, но дело в том, что я хочу использовать это в нескольких представлениях, и я не хочу создавать копию этого для каждого из моих представлений. Я пытался сделать это var rootView: View, но выдает ошибку, говорящую View is not convertible to HomeView.

Так что есть две вещи, которые должны быть обобщены c. HomeView() и HomeViewModel.

Есть идеи, как этого добиться?

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()
        }
    }
}

1 Ответ

1 голос
/ 22 апреля 2020

Здесь возможен подход (скомпилировано с Xcode 11.4)

Использование:

CustomScrollView(width: 100, height: 100, 
   viewModel: HomeViewMode()) {
      HomeView()
}

Generi c тип:

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()
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...