mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-25 02:41:24 +01:00
WIP: new demo app
This commit is contained in:
58
Demo/Sources/Helpers/InstructionsView.swift
Normal file
58
Demo/Sources/Helpers/InstructionsView.swift
Normal file
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - InstructionsView
|
||||
|
||||
struct InstructionsView: View {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
init(_ rows: (header: String, description: String)...) {
|
||||
|
||||
self.rows = rows.map({ .init(header: $0, description: $1) })
|
||||
}
|
||||
|
||||
|
||||
// MARK: View
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .center) {
|
||||
Color.white
|
||||
.cornerRadius(10)
|
||||
.shadow(color: Color(.sRGB, white: 0.5, opacity: 0.3), radius: 2, x: 1, y: 1)
|
||||
VStack(alignment: .leading, spacing: 3) {
|
||||
ForEach(self.rows, id: \.header) { row in
|
||||
HStack(alignment: .firstTextBaseline, spacing: 5) {
|
||||
Text(row.header)
|
||||
.font(.callout)
|
||||
.fontWeight(.bold)
|
||||
Text(row.description)
|
||||
.font(.footnote)
|
||||
}
|
||||
}
|
||||
}
|
||||
.foregroundColor(Color(.sRGB, white: 0, opacity: 0.8))
|
||||
.padding(.horizontal, 10)
|
||||
.padding(.vertical, 4)
|
||||
}
|
||||
.fixedSize()
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let rows: [InstructionsView.Row]
|
||||
|
||||
|
||||
// MARK: - Row
|
||||
|
||||
struct Row: Hashable {
|
||||
|
||||
// MARK: Internal
|
||||
let header: String
|
||||
let description: String
|
||||
}
|
||||
}
|
||||
|
||||
29
Demo/Sources/Helpers/LazyView.swift
Normal file
29
Demo/Sources/Helpers/LazyView.swift
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - LazyView
|
||||
|
||||
struct LazyView<Content: View>: View {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
init(_ load: @escaping () -> Content) {
|
||||
|
||||
self.load = load
|
||||
}
|
||||
|
||||
|
||||
// MARK: View
|
||||
|
||||
var body: Content {
|
||||
|
||||
self.load()
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let load: () -> Content
|
||||
}
|
||||
71
Demo/Sources/Helpers/Menu/Menu.ItemView.swift
Normal file
71
Demo/Sources/Helpers/Menu/Menu.ItemView.swift
Normal file
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - Menu
|
||||
|
||||
extension Menu {
|
||||
|
||||
// MARK: - Menu.ItemView
|
||||
|
||||
struct ItemView<Destination: View>: View {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
init(
|
||||
title: String,
|
||||
subtitle: String? = nil,
|
||||
destination: @escaping () -> Destination
|
||||
) {
|
||||
self.title = title
|
||||
self.subtitle = subtitle
|
||||
self.destination = destination
|
||||
}
|
||||
|
||||
|
||||
// MARK: View
|
||||
|
||||
var body: some View {
|
||||
NavigationLink(destination: LazyView(self.destination)) {
|
||||
VStack(alignment: .leading) {
|
||||
Text(self.title)
|
||||
.font(.headline)
|
||||
.foregroundColor(.primary)
|
||||
self.subtitle.map {
|
||||
Text($0)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate let title: String
|
||||
fileprivate let subtitle: String?
|
||||
fileprivate let destination: () -> Destination
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
||||
struct _Demo_Menu_ItemView_Preview: PreviewProvider {
|
||||
|
||||
// MARK: PreviewProvider
|
||||
|
||||
static var previews: some View {
|
||||
Menu.ItemView(
|
||||
title: "Item Title",
|
||||
subtitle: "A subtitle caption for this item",
|
||||
destination: {
|
||||
Color.blue
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
161
Demo/Sources/Helpers/Menu/Menu.MainView.swift
Normal file
161
Demo/Sources/Helpers/Menu/Menu.MainView.swift
Normal file
@@ -0,0 +1,161 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
|
||||
// MARK: - Menu
|
||||
|
||||
extension Menu {
|
||||
|
||||
// MARK: - Menu.MainView
|
||||
|
||||
struct MainView: View {
|
||||
|
||||
// MARK: View
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
List {
|
||||
Section(header: Text("Modern (CoreStoreObject subclasses)")) {
|
||||
Menu.ItemView(
|
||||
title: "Placemarks",
|
||||
subtitle: "Making changes using Transactions",
|
||||
destination: {
|
||||
Modern.PlacemarksDemo.MainView()
|
||||
}
|
||||
)
|
||||
Menu.ItemView(
|
||||
title: "Time Zones",
|
||||
subtitle: "Fetching objects and Querying raw values",
|
||||
destination: {
|
||||
Modern.TimeZonesDemo.MainView()
|
||||
}
|
||||
)
|
||||
Menu.ItemView(
|
||||
title: "Colors (UIKit)",
|
||||
subtitle: "Observing list changes and single-object changes using DiffableDataSources",
|
||||
destination: {
|
||||
Modern.ColorsDemo.MainView(
|
||||
listView: { listPublisher, onPaletteTapped in
|
||||
Modern.ColorsDemo.UIKit.ListView(
|
||||
listPublisher: listPublisher,
|
||||
onPaletteTapped: onPaletteTapped
|
||||
)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
},
|
||||
detailView: { objectPublisher in
|
||||
Modern.ColorsDemo.UIKit.DetailView(objectPublisher)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
Menu.ItemView(
|
||||
title: "Colors (SwiftUI)",
|
||||
subtitle: "Observing list changes and single-object changes using SwiftUI bindings",
|
||||
destination: {
|
||||
Modern.ColorsDemo.MainView(
|
||||
listView: { listPublisher, onPaletteTapped in
|
||||
Modern.ColorsDemo.SwiftUI.ListView(
|
||||
listPublisher: listPublisher,
|
||||
onPaletteTapped: onPaletteTapped
|
||||
)
|
||||
},
|
||||
detailView: { objectPublisher in
|
||||
Modern.ColorsDemo.SwiftUI.DetailView(objectPublisher)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
Menu.ItemView(
|
||||
title: "Pokedex API",
|
||||
subtitle: "Importing JSON data from external source",
|
||||
destination: { EmptyView() }
|
||||
)
|
||||
}
|
||||
Section(header: Text("Classic (NSManagedObject subclasses)")) {
|
||||
Menu.ItemView(
|
||||
title: "Placemarks (Swift)",
|
||||
subtitle: "Making changes using transactions in Swift",
|
||||
destination: { EmptyView() }
|
||||
)
|
||||
Menu.ItemView(
|
||||
title: "Placemarks (Objective-C)",
|
||||
subtitle: "Making changes using transactions in Objective-C",
|
||||
destination: { EmptyView() }
|
||||
)
|
||||
Menu.ItemView(
|
||||
title: "Time Zones",
|
||||
subtitle: "Fetching objects and Querying raw values",
|
||||
destination: { EmptyView() }
|
||||
)
|
||||
Menu.ItemView(
|
||||
title: "Colors (Swift)",
|
||||
subtitle: "Observing list changes and single-object changes in Swift",
|
||||
destination: { EmptyView() }
|
||||
)
|
||||
Menu.ItemView(
|
||||
title: "Colors (Objective-C)",
|
||||
subtitle: "Observing list changes and single-object changes in Objective-C",
|
||||
destination: { EmptyView() }
|
||||
)
|
||||
Menu.ItemView(
|
||||
title: "Pokedex API",
|
||||
subtitle: "Importing JSON data from external source",
|
||||
destination: { EmptyView() }
|
||||
)
|
||||
}
|
||||
Section(header: Text("Advanced")) {
|
||||
Menu.ItemView(
|
||||
title: "Accounts",
|
||||
subtitle: "Switching between multiple persistent stores",
|
||||
destination: { EmptyView() }
|
||||
)
|
||||
Menu.ItemView(
|
||||
title: "Evolution",
|
||||
subtitle: "Migrating and reverse-migrating stores",
|
||||
destination: { EmptyView() }
|
||||
)
|
||||
Menu.ItemView(
|
||||
title: "Logger",
|
||||
subtitle: "Implementing a custom logger",
|
||||
destination: { EmptyView() }
|
||||
)
|
||||
}
|
||||
}
|
||||
.listStyle(GroupedListStyle())
|
||||
.navigationBarTitle("CoreStore Demos")
|
||||
Menu.DetailView()
|
||||
}
|
||||
.navigationViewStyle(DoubleColumnNavigationViewStyle())
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate struct DetailView: View {
|
||||
|
||||
var selectedDate: Date?
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
Text("Detail view content goes here")
|
||||
}
|
||||
.navigationBarTitle(Text("Detail"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
||||
struct _Demo_Menu_MainView_Preview: PreviewProvider {
|
||||
|
||||
// MARK: PreviewProvider
|
||||
|
||||
static var previews: some View {
|
||||
|
||||
Menu.MainView()
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
10
Demo/Sources/Helpers/Menu/Menu.swift
Normal file
10
Demo/Sources/Helpers/Menu/Menu.swift
Normal file
@@ -0,0 +1,10 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
// MARK: - Menu
|
||||
|
||||
enum Menu {}
|
||||
43
Demo/Sources/Helpers/UIImage+Extensions.swift
Normal file
43
Demo/Sources/Helpers/UIImage+Extensions.swift
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
// MARK: - UIImage
|
||||
|
||||
extension UIImage {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
convenience init(
|
||||
color: UIColor,
|
||||
size: CGSize = CGSize(width: 1, height: 1),
|
||||
cornerRadius: CGFloat = 0
|
||||
) {
|
||||
let rect = CGRect(origin: .zero, size: size)
|
||||
let scale = UIScreen.main.scale
|
||||
UIGraphicsBeginImageContextWithOptions(rect.size, false, scale)
|
||||
defer {
|
||||
UIGraphicsEndImageContext()
|
||||
}
|
||||
let context = UIGraphicsGetCurrentContext()!
|
||||
|
||||
if cornerRadius > 0 {
|
||||
UIBezierPath(
|
||||
roundedRect: rect,
|
||||
cornerRadius: cornerRadius
|
||||
)
|
||||
.addClip()
|
||||
}
|
||||
color.setFill()
|
||||
context.fill(rect)
|
||||
|
||||
self.init(
|
||||
cgImage: UIGraphicsGetImageFromCurrentImageContext()!.cgImage!,
|
||||
scale: scale,
|
||||
orientation: .up
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user