Skip to content

Instantly share code, notes, and snippets.

@damodarnamala
Created January 15, 2022 08:26
Show Gist options
  • Save damodarnamala/720567e7333137703d03d4286082a01e to your computer and use it in GitHub Desktop.
Save damodarnamala/720567e7333137703d03d4286082a01e to your computer and use it in GitHub Desktop.
Wrapping UIRepresentable
class ProductViewModel: ObservableObject {
@Published var state: State = .isLoading
@Published var productName = "Sample"
@Published var formattedPrice = "100"
enum State {
case isLoading
case finishedLoading
}
init() {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.state = .finishedLoading
}
}
}
struct ListItems: View {
@ObservedObject var viewModel: ProductViewModel = ProductViewModel()
@ViewBuilder var body: some View {
if viewModel.state == .isLoading {
LoaderView{}
} else {
TextView(
title: viewModel.productName,
subtitle: viewModel.formattedPrice
)
}
}
}
struct TextView: View {
var title: String
var subtitle: String
var body: some View {
VStack(alignment: .leading) {
Text(title).bold()
Text(subtitle).foregroundColor(.secondary)
}
}
}
struct LoaderView<Content: View>: View {
var content: Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content()
}
var body: some View {
VStack {
content.disabled(true)
Wrap(UIActivityIndicatorView()) {
$0.color = .red
$0.startAnimating()
}
}
}
}
struct Wrap<Wrapped: UIView>: UIViewRepresentable {
typealias Updater = (Wrapped, Context) -> Void
var makeView: () -> Wrapped
var update: (Wrapped, Context) -> Void
init(_ makeView: @escaping @autoclosure () -> Wrapped,
updater update: @escaping Updater) {
self.makeView = makeView
self.update = update
}
func makeUIView(context: Context) -> Wrapped {
makeView()
}
func updateUIView(_ view: Wrapped, context: Context) {
update(view, context)
}
}
extension Wrap {
init(_ makeView: @escaping @autoclosure () -> Wrapped,
updater update: @escaping (Wrapped) -> Void) {
self.makeView = makeView
self.update = { view, _ in update(view) }
}
init(_ makeView: @escaping @autoclosure () -> Wrapped) {
self.makeView = makeView
self.update = { _, _ in }
}
}
//https://www.swiftbysundell.com/articles/opaque-return-types-in-swift/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment