Sure. I am working from this tutorial: https://www.hackingwithswift.com/quick-start/swiftui/swiftui-tutorial-building-a-complete-project
And am stuck on adding the tab view https://www.hackingwithswift.com/quick-start/swiftui/adding-tabview-and-tabitem
My main app code
@main
struct iDineApp: App {
@EnvironmentObject var order: Order
var body: some Scene {
WindowGroup {
AppView()
}
}
}
struct iDineApp_Previews: PreviewProvider {
static let order = Order()
static var previews: some View {
AppView().environmentObject(order)
}
}
The order
import SwiftUI
class Order: ObservableObject {
@Published var items = [MenuItem]()
var total: Int {
if items.count > 0 {
return items.reduce(0) { $0 + $1.price }
} else {
return 0
}
}
func add(item: MenuItem) {
items.append(item)
}
func remove(item: MenuItem) {
if let index = items.firstIndex(of: item) {
items.remove(at: index)
}
}
}
ContentView
struct ContentView: View {
let menu = Bundle.main.decode([MenuSection].self, from: "menu.json")
var body: some View {
NavigationView{
List {
ForEach(menu) { section in
Section(header: Text(section.name)) {
ForEach(section.items) { item in
ItemRow(item: item)
}
}
}
}
.navigationBarTitle("Menu")
.listStyle(InsetGroupedListStyle())
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
ItemDetail
struct ItemDetail: View {
@EnvironmentObject var order: Order
var item: MenuItem
var body: some View {
VStack {
ZStack(alignment: .bottomTrailing) {
Image(item.mainImage)
Text("Photo: \(item.photoCredit)")
.padding(4)
.background(Color.black)
.font(.caption)
.foregroundColor(.white)
.offset(x: -5, y: -5)
.opacity(0.75)
}
Text(item.description).padding()
Button("Order This") {
self.order.add(item: self.item)
}.font(.headline)
Spacer()
}.navigationBarTitle(Text(item.name), displayMode: .inline)
}
}
struct ItemDetail_Previews: PreviewProvider {
static let order = Order()
static var previews: some View {
NavigationView
{ ItemDetail(item: MenuItem.example).environmentObject(order)
}
}
}
OrderView
struct OrderView: View {
@EnvironmentObject var order: Order
var body: some View {
NavigationView {
List {
Section {
ForEach(order.items) { item in
HStack {
Text(item.name)
Spacer()
Text("$\(item.price)")
}
}
}
Section {
NavigationLink(destination: Text("Check out")) {
Text("Place Order")
}
}
}
.navigationBarTitle("Order")
.listStyle(GroupedListStyle())
}
}
}
struct OrderView_Previews: PreviewProvider {
static let order = Order()
static var previews: some View {
OrderView().environmentObject(order)
}
}
AppView
struct ItemRow: View {
static let colors: [String: Color] = ["D": .gray, "G": .yellow, "N": .orange, "S": .red, "V": .green]
var item: MenuItem
var body: some View {
NavigationLink(destination: ItemDetail(item: item))
{
HStack {
Image(item.thumbnailImage)
.clipShape(Circle())
.overlay(Circle().stroke(Color.gray, lineWidth: 2.0))
VStack(alignment: .leading) {
Text(item.name)
.font(.headline)
Text("$\(item.price)")
}
Spacer()
ForEach(item.restrictions, id: \.self) {
restriction in Text(restriction)
.font(.caption)
.fontWeight(.black)
.padding(5)
.background(Self.colors[restriction, default: .black])
.clipShape(Circle())
.foregroundColor(.white)
}
}
}
}
}
struct ItemRow_Previews: PreviewProvider {
static var previews: some View {
ItemRow(item: MenuItem.example)
}
}
Item Row
struct ItemRow: View {
static let colors: [String: Color] = ["D": .gray, "G": .yellow, "N": .orange, "S": .red, "V": .green]
var item: MenuItem
var body: some View {
NavigationLink(destination: ItemDetail(item: item))
{
HStack {
Image(item.thumbnailImage)
.clipShape(Circle())
.overlay(Circle().stroke(Color.gray, lineWidth: 2.0))
VStack(alignment: .leading) {
Text(item.name)
.font(.headline)
Text("$\(item.price)")
}
Spacer()
ForEach(item.restrictions, id: \.self) {
restriction in Text(restriction)
.font(.caption)
.fontWeight(.black)
.padding(5)
.background(Self.colors[restriction, default: .black])
.clipShape(Circle())
.foregroundColor(.white)
}
}
}
}
}
struct ItemRow_Previews: PreviewProvider {
static var previews: some View {
ItemRow(item: MenuItem.example)
}
}