-
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
ac48542
commit 28c7f2a
Showing
12 changed files
with
952 additions
and
0 deletions.
There are no files selected for viewing
510 changes: 510 additions & 0 deletions
510
0161-navigation-pt2/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
...t2/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
...-pt2/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
0161-navigation-pt2/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
0161-navigation-pt2/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("Inventory") } | ||
.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)) | ||
} | ||
} |
153 changes: 153 additions & 0 deletions
153
0161-navigation-pt2/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,153 @@ | ||
import IdentifiedCollections | ||
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: IdentifiedArrayOf<Item> | ||
@Published var itemToDelete: Item? | ||
|
||
init( | ||
inventory: IdentifiedArrayOf<Item> = [], | ||
itemToDelete: Item? = nil | ||
) { | ||
self.itemToDelete = itemToDelete | ||
self.inventory = inventory | ||
} | ||
|
||
func delete(item: Item) { | ||
withAnimation { | ||
_ = self.inventory.remove(id: item.id) | ||
//self.inventory.removeAll(where: { $0.id == item.id }) | ||
} | ||
} | ||
|
||
func deleteButtonTapped(item: Item) { | ||
self.itemToDelete = item | ||
} | ||
} | ||
|
||
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.viewModel.deleteButtonTapped(item: item) }) { | ||
Image(systemName: "trash.fill") | ||
} | ||
.padding(.leading) | ||
} | ||
.buttonStyle(.plain) | ||
.foregroundColor(item.status.isInStock ? nil : Color.gray) | ||
} | ||
} | ||
.alert( | ||
title: { Text($0.name) }, | ||
presenting: self.$viewModel.itemToDelete, | ||
actions: { item in | ||
Button("Delete", role: .destructive) { | ||
self.viewModel.delete(item: item) | ||
} | ||
}, | ||
message: { _ in | ||
Text("Are you sure you want to delete this item?") | ||
} | ||
) | ||
// .alert(item: self.$viewModel.itemToDelete) { item in | ||
// Alert( | ||
// title: Text(item.name), | ||
// message: Text("Are you sure you want to delete this item?"), | ||
// primaryButton: .destructive(Text("Delete")) { | ||
// self.viewModel.delete(item: item) | ||
// }, | ||
// secondaryButton: .cancel() | ||
// ) | ||
// } | ||
} | ||
} | ||
|
||
struct InventoryView_Previews: PreviewProvider { | ||
static var previews: some View { | ||
let keyboard = Item(name: "Keyboard", color: .blue, status: .inStock(quantity: 100)) | ||
|
||
InventoryView( | ||
viewModel: .init( | ||
inventory: [ | ||
keyboard, | ||
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)), | ||
], | ||
itemToDelete: keyboard | ||
) | ||
) | ||
} | ||
} |
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 | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
0161-navigation-pt2/SwiftUINavigation/SwiftUINavigation/SwiftUIHelpers.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,49 @@ | ||
import SwiftUI | ||
|
||
extension Binding { | ||
func isPresent<Wrapped>() -> Binding<Bool> | ||
where Value == Wrapped? { | ||
.init( | ||
get: { self.wrappedValue != nil }, | ||
set: { isPresented in | ||
if !isPresented { | ||
self.wrappedValue = nil | ||
} | ||
} | ||
) | ||
} | ||
} | ||
|
||
extension View { | ||
func alert<A: View, M: View, T>( | ||
title: (T) -> Text, | ||
presenting data: Binding<T?>, | ||
@ViewBuilder actions: @escaping (T) -> A, | ||
@ViewBuilder message: @escaping (T) -> M | ||
) -> some View { | ||
self.alert( | ||
data.wrappedValue.map(title) ?? Text(""), | ||
isPresented: data.isPresent(), | ||
presenting: data.wrappedValue, | ||
actions: actions, | ||
message: message | ||
) | ||
} | ||
|
||
func confirmationDialog<A: View, M: View, T>( | ||
title: (T) -> Text, | ||
titleVisibility: Visibility = .automatic, | ||
presenting data: Binding<T?>, | ||
@ViewBuilder actions: @escaping (T) -> A, | ||
@ViewBuilder message: @escaping (T) -> M | ||
) -> some View { | ||
self.confirmationDialog( | ||
data.wrappedValue.map(title) ?? Text(""), | ||
isPresented: data.isPresent(), | ||
titleVisibility: titleVisibility, | ||
presenting: data.wrappedValue, | ||
actions: actions, | ||
message: message | ||
) | ||
} | ||
} |
Oops, something went wrong.