ios_app/Shared/Components/RefreshableScrollView.swift
2025-09-19 01:52:24 +03:00

77 lines
2.8 KiB
Swift

import SwiftUI
import UIKit
struct RefreshableScrollView<Content: View>: UIViewRepresentable {
var content: Content
var onRefresh: () -> Void
var onScroll: ((CGPoint) -> Void)?
var isRefreshing: Binding<Bool>
init(isRefreshing: Binding<Bool>, onRefresh: @escaping () -> Void, onScroll: ((CGPoint) -> Void)? = nil, @ViewBuilder content: () -> Content) {
self.content = content()
self.onRefresh = onRefresh
self.onScroll = onScroll
self.isRefreshing = isRefreshing
}
func makeUIView(context: Context) -> UIScrollView {
let scrollView = UIScrollView()
scrollView.delaysContentTouches = false
scrollView.delegate = context.coordinator
let refreshControl = UIRefreshControl()
refreshControl.addTarget(context.coordinator, action: #selector(Coordinator.handleRefresh), for: .valueChanged)
scrollView.refreshControl = refreshControl
let hostingController = UIHostingController(rootView: content)
hostingController.view.backgroundColor = .clear
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(hostingController.view)
NSLayoutConstraint.activate([
hostingController.view.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
hostingController.view.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
hostingController.view.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
hostingController.view.bottomAnchor.constraint(equalTo: scrollView.contentLayoutGuide.bottomAnchor),
hostingController.view.widthAnchor.constraint(equalTo: scrollView.frameLayoutGuide.widthAnchor)
])
context.coordinator.hostingController = hostingController
return scrollView
}
func updateUIView(_ uiView: UIScrollView, context: Context) {
if isRefreshing.wrappedValue {
uiView.refreshControl?.beginRefreshing()
} else {
DispatchQueue.main.async {
uiView.refreshControl?.endRefreshing()
}
}
context.coordinator.hostingController?.rootView = content
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UIScrollViewDelegate {
var parent: RefreshableScrollView
var hostingController: UIHostingController<Content>?
init(_ parent: RefreshableScrollView) {
self.parent = parent
}
@objc func handleRefresh() {
parent.onRefresh()
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
parent.onScroll?(scrollView.contentOffset)
}
}
}