-
Notifications
You must be signed in to change notification settings - Fork 299
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
35ff143
commit ac48542
Showing
11 changed files
with
838 additions
and
0 deletions.
There are no files selected for viewing
479 changes: 479 additions & 0 deletions
479
0160-navigation-pt1/SwiftUINavigation/SwiftUINavigation.xcodeproj/project.pbxproj
Large diffs are not rendered by default.
Oops, something went wrong.
7 changes: 7 additions & 0 deletions
7
...wiftUINavigation/SwiftUINavigation.xcodeproj/project.xcworkspace/contents.xcworkspacedata
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
8 changes: 8 additions & 0 deletions
8
...ion/SwiftUINavigation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>IDEDidComputeMac32BitWarning</key> | ||
<true/> | ||
</dict> | ||
</plist> |
11 changes: 11 additions & 0 deletions
11
...t1/SwiftUINavigation/SwiftUINavigation/Assets.xcassets/AccentColor.colorset/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"colors" : [ | ||
{ | ||
"idiom" : "universal" | ||
} | ||
], | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
} | ||
} |
98 changes: 98 additions & 0 deletions
98
...-pt1/SwiftUINavigation/SwiftUINavigation/Assets.xcassets/AppIcon.appiconset/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
{ | ||
"images" : [ | ||
{ | ||
"idiom" : "iphone", | ||
"scale" : "2x", | ||
"size" : "20x20" | ||
}, | ||
{ | ||
"idiom" : "iphone", | ||
"scale" : "3x", | ||
"size" : "20x20" | ||
}, | ||
{ | ||
"idiom" : "iphone", | ||
"scale" : "2x", | ||
"size" : "29x29" | ||
}, | ||
{ | ||
"idiom" : "iphone", | ||
"scale" : "3x", | ||
"size" : "29x29" | ||
}, | ||
{ | ||
"idiom" : "iphone", | ||
"scale" : "2x", | ||
"size" : "40x40" | ||
}, | ||
{ | ||
"idiom" : "iphone", | ||
"scale" : "3x", | ||
"size" : "40x40" | ||
}, | ||
{ | ||
"idiom" : "iphone", | ||
"scale" : "2x", | ||
"size" : "60x60" | ||
}, | ||
{ | ||
"idiom" : "iphone", | ||
"scale" : "3x", | ||
"size" : "60x60" | ||
}, | ||
{ | ||
"idiom" : "ipad", | ||
"scale" : "1x", | ||
"size" : "20x20" | ||
}, | ||
{ | ||
"idiom" : "ipad", | ||
"scale" : "2x", | ||
"size" : "20x20" | ||
}, | ||
{ | ||
"idiom" : "ipad", | ||
"scale" : "1x", | ||
"size" : "29x29" | ||
}, | ||
{ | ||
"idiom" : "ipad", | ||
"scale" : "2x", | ||
"size" : "29x29" | ||
}, | ||
{ | ||
"idiom" : "ipad", | ||
"scale" : "1x", | ||
"size" : "40x40" | ||
}, | ||
{ | ||
"idiom" : "ipad", | ||
"scale" : "2x", | ||
"size" : "40x40" | ||
}, | ||
{ | ||
"idiom" : "ipad", | ||
"scale" : "1x", | ||
"size" : "76x76" | ||
}, | ||
{ | ||
"idiom" : "ipad", | ||
"scale" : "2x", | ||
"size" : "76x76" | ||
}, | ||
{ | ||
"idiom" : "ipad", | ||
"scale" : "2x", | ||
"size" : "83.5x83.5" | ||
}, | ||
{ | ||
"idiom" : "ios-marketing", | ||
"scale" : "1x", | ||
"size" : "1024x1024" | ||
} | ||
], | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
0160-navigation-pt1/SwiftUINavigation/SwiftUINavigation/Assets.xcassets/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
0160-navigation-pt1/SwiftUINavigation/SwiftUINavigation/ContentView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import SwiftUI | ||
|
||
enum Tab { | ||
case one, inventory, three | ||
} | ||
|
||
class AppViewModel: ObservableObject { | ||
@Published var inventoryViewModel: InventoryViewModel | ||
@Published var selectedTab: Tab | ||
|
||
init( | ||
inventoryViewModel: InventoryViewModel = .init(), | ||
selectedTab: Tab = .one | ||
) { | ||
self.inventoryViewModel = inventoryViewModel | ||
self.selectedTab = selectedTab | ||
} | ||
} | ||
|
||
struct ContentView: View { | ||
@ObservedObject var viewModel: AppViewModel | ||
|
||
var body: some View { | ||
TabView(selection: self.$viewModel.selectedTab) { | ||
Button("Go to 2nd tab") { | ||
self.viewModel.selectedTab = .inventory | ||
} | ||
.tabItem { Text("One") } | ||
.tag(Tab.one) | ||
|
||
InventoryView(viewModel: self.viewModel.inventoryViewModel) | ||
.tabItem { Text("Two") } | ||
.tag(Tab.inventory) | ||
|
||
Text("Three") | ||
.tabItem { Text("Three") } | ||
.tag(Tab.three) | ||
} | ||
} | ||
} | ||
|
||
struct ContentView_Previews: PreviewProvider { | ||
static var previews: some View { | ||
ContentView(viewModel: .init(selectedTab: .inventory)) | ||
} | ||
} |
134 changes: 134 additions & 0 deletions
134
0160-navigation-pt1/SwiftUINavigation/SwiftUINavigation/Inventory.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
import SwiftUI | ||
|
||
struct Item: Equatable, Identifiable { | ||
let id = UUID() | ||
var name: String | ||
var color: Color? | ||
var status: Status | ||
// var quantity: Int | ||
// var isOnBackOrder: Bool | ||
|
||
enum Status: Equatable { | ||
case inStock(quantity: Int) | ||
case outOfStock(isOnBackOrder: Bool) | ||
|
||
var isInStock: Bool { | ||
guard case .inStock = self else { return false } | ||
return true | ||
} | ||
} | ||
|
||
struct Color: Equatable, Hashable { | ||
var name: String | ||
var red: CGFloat = 0 | ||
var green: CGFloat = 0 | ||
var blue: CGFloat = 0 | ||
|
||
static var defaults: [Self] = [ | ||
.red, | ||
.green, | ||
.blue, | ||
.black, | ||
.yellow, | ||
.white, | ||
] | ||
|
||
static let red = Self(name: "Red", red: 1) | ||
static let green = Self(name: "Green", green: 1) | ||
static let blue = Self(name: "Blue", blue: 1) | ||
static let black = Self(name: "Black") | ||
static let yellow = Self(name: "Yellow", red: 1, green: 1) | ||
static let white = Self(name: "White", red: 1, green: 1, blue: 1) | ||
|
||
var swiftUIColor: SwiftUI.Color { | ||
.init(red: self.red, green: self.green, blue: self.blue) | ||
} | ||
} | ||
} | ||
|
||
class InventoryViewModel: ObservableObject { | ||
@Published var inventory: [Item] | ||
|
||
init(inventory: [Item] = []) { | ||
self.inventory = inventory | ||
} | ||
|
||
func delete(item: Item) { | ||
withAnimation { | ||
self.inventory.removeAll(where: { $0.id == item.id }) | ||
} | ||
} | ||
} | ||
|
||
struct InventoryView: View { | ||
@ObservedObject var viewModel: InventoryViewModel | ||
@State var deleteItemAlertIsPresented = false | ||
@State var itemToDelete: Item? | ||
|
||
var body: some View { | ||
List { | ||
ForEach(self.viewModel.inventory) { item in | ||
HStack { | ||
VStack(alignment: .leading) { | ||
Text(item.name) | ||
|
||
switch item.status { | ||
case let .inStock(quantity): | ||
Text("In stock: \(quantity)") | ||
case let .outOfStock(isOnBackOrder): | ||
Text("Out of stock" + (isOnBackOrder ? ": on back order" : "")) | ||
} | ||
} | ||
|
||
Spacer() | ||
|
||
if let color = item.color { | ||
Rectangle() | ||
.frame(width: 30, height: 30) | ||
.foregroundColor(color.swiftUIColor) | ||
.border(Color.black, width: 1) | ||
} | ||
|
||
Button( | ||
action: { | ||
self.deleteItemAlertIsPresented = true | ||
self.itemToDelete = item | ||
} | ||
) { | ||
Image(systemName: "trash.fill") | ||
} | ||
.padding(.leading) | ||
} | ||
.buttonStyle(.plain) | ||
.foregroundColor(item.status.isInStock ? nil : Color.gray) | ||
} | ||
} | ||
.alert(isPresented: self.$deleteItemAlertIsPresented) { | ||
Alert( | ||
title: Text(self.itemToDelete?.name ?? "Delete"), | ||
message: Text("Are you sure you want to delete this item?"), | ||
primaryButton: .destructive(Text("Delete")) { | ||
if let item = self.itemToDelete { | ||
self.viewModel.delete(item: item) | ||
} | ||
}, | ||
secondaryButton: .cancel() | ||
) | ||
} | ||
} | ||
} | ||
|
||
struct InventoryView_Previews: PreviewProvider { | ||
static var previews: some View { | ||
InventoryView( | ||
viewModel: .init( | ||
inventory: [ | ||
Item(name: "Keyboard", color: .blue, status: .inStock(quantity: 100)), | ||
Item(name: "Charger", color: .yellow, status: .inStock(quantity: 20)), | ||
Item(name: "Phone", color: .green, status: .outOfStock(isOnBackOrder: true)), | ||
Item(name: "Headphones", color: .green, status: .outOfStock(isOnBackOrder: false)), | ||
] | ||
) | ||
) | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
...SwiftUINavigation/SwiftUINavigation/Preview Content/Preview Assets.xcassets/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"info" : { | ||
"author" : "xcode", | ||
"version" : 1 | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
0160-navigation-pt1/SwiftUINavigation/SwiftUINavigation/SwiftUINavigationApp.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import SwiftUI | ||
|
||
@main | ||
struct SwiftUINavigationApp: App { | ||
var body: some Scene { | ||
WindowGroup { | ||
ContentView(viewModel: .init()) | ||
} | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
0160-navigation-pt1/SwiftUINavigation/SwiftUINavigationTests/SwiftUINavigationTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// | ||
// SwiftUINavigationTests.swift | ||
// SwiftUINavigationTests | ||
// | ||
// Created by Point-Free on 9/13/21. | ||
// | ||
|
||
import XCTest | ||
@testable import SwiftUINavigation | ||
|
||
class SwiftUINavigationTests: XCTestCase { | ||
|
||
override func setUpWithError() throws { | ||
// Put setup code here. This method is called before the invocation of each test method in the class. | ||
} | ||
|
||
override func tearDownWithError() throws { | ||
// Put teardown code here. This method is called after the invocation of each test method in the class. | ||
} | ||
|
||
func testExample() throws { | ||
// This is an example of a functional test case. | ||
// Use XCTAssert and related functions to verify your tests produce the correct results. | ||
} | ||
|
||
func testPerformanceExample() throws { | ||
// This is an example of a performance test case. | ||
self.measure { | ||
// Put the code you want to measure the time of here. | ||
} | ||
} | ||
|
||
} |