Skip to content

Instantly share code, notes, and snippets.

@Wilsonilo
Created August 23, 2022 19:01
Show Gist options
  • Save Wilsonilo/309600c62c9e27385dfa5296e696b668 to your computer and use it in GitHub Desktop.
Save Wilsonilo/309600c62c9e27385dfa5296e696b668 to your computer and use it in GitHub Desktop.
Refreshable View / ScrollView with a custom UIView
//
// SwiftUICustomRefreshControl.swift
// SwiftUICustomRefreshControl
//
// Created by Wilson Munoz on 23/08/22.
//
import SwiftUI
import UIKit
struct ContentView: View {
var body: some View {
RefreshableScrollView {
Text("Scrollable content")
.padding()
} onRefresh: {
//Call a refresh, usually a ViewModel
print("refresh called")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
//Make a ScrollView or any content refreshable, putting inside a List (iOS15+), follow links for the source of the code
//https://stackoverflow.com/questions/71562594/swiftui-refreshable-pull-to-refresh-is-not-working-at-scrollview
//https://github.com/globulus/swiftui-pull-to-refresh
struct RefreshableScrollView<Content: View>: View {
// MARK: - Properties
var content: Content
var onRefresh: () -> Void
//MARK: - Init
public init(content: @escaping () -> Content, onRefresh: @escaping () -> Void) {
self.content = content()
self.onRefresh = onRefresh
}
// MARK: - body
public var body: some View {
List {
content
.listRowSeparatorTint(.clear)
.listRowBackground(Color.clear)
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))
}
.listStyle(.plain)
.refreshable {
onRefresh()
}
.onAppear{
//Hide the default refresh controller, attach our uiView
//Because is a singleton it wont be added several times
//You can always expand your singleton to be hidden, animated, removed, etc.
UIRefreshControl.appearance().tintColor = .clear
UIRefreshControl.appearance().addSubview(SingletonView.shared)
}
}
}
//Singleton Class View
class SingletonView: UIView {
// Singleton instance
static let shared : UIView = SingletonView.sharedInstance(size: CGSize(width: 20, height: 20))
// You can modify argument list as per your need.
class private func sharedInstance(size : CGSize)->UIView {
//Putting the view in the middle, but the details falls on you.
let view = UIView(frame: CGRect(x: (UIScreen.main.bounds.width / 2) - size.width/2, y: 0, width: size.width, height: size.height))
//just so you can see something
view.layer.backgroundColor = UIColor.red.cgColor
return view
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment