// // UnavailableView.swift // ReviewsUIKit // // Created by Javier Cicchelli on 22/03/2024. // Copyright © 2024 Röck+Cöde VoF. All rights reserved. // import SwiftUI public struct UnavailableView: View { // MARK: Constants private let description: String private let systemImage: String private let title: String private let action: (() -> Void)? private let button: String? // MARK: Initialisers public init( systemImage: String, title: String, description: String, button: String? = nil, action: (() -> Void)? = nil ) { self.action = action self.button = button self.description = description self.systemImage = systemImage self.title = title } // MARK: Body public var body: some View { if #available(iOS 17.0, *) { if let button, let action { ContentUnavailableView { Label(title, systemImage: systemImage) } description: { Text(description) } actions: { Button(action: action) { Text(button) } } } else { ContentUnavailableView( title, systemImage: systemImage, description: Text(description) ) } } else { VStack(spacing: 24) { Image(systemName: systemImage) .resizable() .frame(width: 52, height: 52) .foregroundColor(.secondary) VStack { Text(title) .font(.title2.bold()) .foregroundColor(.primary) Text(description) .font(.subheadline) .foregroundColor(.secondary) } .multilineTextAlignment(.center) if let button, let action { Button(action: action) { Text(button) .font(.subheadline) } } } .padding(.horizontal, 52) } } } // MARK: - Previews #Preview("Unavailable View with image, title, and description") { UnavailableView( systemImage: "star", title: "Some title goes here...", description: "Some long, explanatory description goes in here..." ) } #Preview("Unavailable View with image, title, description, button, and action") { UnavailableView( systemImage: "star", title: "Some title goes here...", description: "Some long, explanatory description goes in here...", button: "Some button text here..." ) { // On action closure. } }