Building a Restaurant Menu App in SwiftUI

SwiftUI offers a declarative way to build user interfaces across all Apple platforms. Creating a restaurant menu app is an excellent project to learn and showcase SwiftUI’s capabilities. This tutorial provides a comprehensive guide to building a restaurant menu app in SwiftUI, covering UI design, data handling, and interactive features.

Why Use SwiftUI?

  • Declarative Syntax: SwiftUI simplifies UI development with its clear and concise declarative syntax.
  • Cross-Platform Compatibility: Build apps that run seamlessly on iOS, macOS, watchOS, and tvOS from a single codebase.
  • Live Preview: Xcode’s live preview feature allows for real-time UI updates, speeding up development.
  • Integration with Combine: SwiftUI works perfectly with the Combine framework for reactive programming, making data handling efficient and manageable.

Project Setup

Start by creating a new Xcode project:

  1. Open Xcode and select Create a new Xcode project.
  2. Choose iOS and select the App template.
  3. Enter the product name (e.g., “RestaurantMenu”), select SwiftUI as the interface, and click Next.
  4. Choose a location to save the project and click Create.

Data Model

Define the data model for the menu items. Create a new Swift file named MenuItem.swift:

import SwiftUI

struct MenuItem: Identifiable {
    let id = UUID()
    let name: String
    let description: String
    let price: Double
    let imageName: String
    let category: String
    let isVegetarian: Bool
    let isPopular: Bool
}

// Example Data
extension MenuItem {
    static let sampleMenuItems: [MenuItem] = [
        MenuItem(name: "Margherita Pizza", description: "Classic pizza with tomato, mozzarella, and basil", price: 12.99, imageName: "margherita", category: "Pizza", isVegetarian: true, isPopular: true),
        MenuItem(name: "Beef Burger", description: "Juicy beef burger with lettuce, tomato, and cheese", price: 14.99, imageName: "burger", category: "Burgers", isVegetarian: false, isPopular: true),
        MenuItem(name: "Caesar Salad", description: "Fresh romaine lettuce, croutons, and Caesar dressing", price: 9.99, imageName: "caesar", category: "Salads", isVegetarian: true, isPopular: false),
        MenuItem(name: "Chocolate Cake", description: "Rich chocolate cake with chocolate frosting", price: 7.99, imageName: "chocolatecake", category: "Desserts", isVegetarian: true, isPopular: true),
        MenuItem(name: "Iced Latte", description: "Refreshing iced latte with espresso and milk", price: 4.99, imageName: "icedlatte", category: "Drinks", isVegetarian: true, isPopular: false)
    ]
}

Ensure you add image assets named as defined in imageName field of sample data (e.g., margherita.jpg) to your project’s Assets.xcassets.

Menu Item Row View

Create a reusable view for displaying each menu item. Create a new Swift file named MenuItemRow.swift:

import SwiftUI

struct MenuItemRow: View {
    let menuItem: MenuItem

    var body: some View {
        HStack {
            Image(menuItem.imageName)
                .resizable()
                .scaledToFit()
                .frame(width: 80, height: 80)
                .clipShape(RoundedRectangle(cornerRadius: 10))

            VStack(alignment: .leading) {
                Text(menuItem.name)
                    .font(.headline)
                Text(menuItem.description)
                    .font(.subheadline)
                    .foregroundColor(.gray)
                Text("$\(menuItem.price, specifier: "%.2f")")
                    .font(.callout)
            }

            Spacer()

            if menuItem.isVegetarian {
                Image(systemName: "leaf.fill")
                    .foregroundColor(.green)
            }

            if menuItem.isPopular {
                Image(systemName: "star.fill")
                    .foregroundColor(.yellow)
            }
        }
        .padding(.vertical, 4)
    }
}

struct MenuItemRow_Previews: PreviewProvider {
    static var previews: some View {
        MenuItemRow(menuItem: MenuItem.sampleMenuItems[0])
            .previewLayout(.sizeThatFits)
    }
}

Menu Category View

Add menu category based list with relevant menu items.


import SwiftUI

struct MenuCategoryView: View {
    let category: String
    let menuItems: [MenuItem]
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(category)
                .font(.title2)
                .padding(.leading)
            
            ForEach(menuItems) { item in
                MenuItemRow(menuItem: item)
                    .padding(.horizontal)
            }
        }
    }
}

struct MenuCategoryView_Previews: PreviewProvider {
    static var previews: some View {
        MenuCategoryView(category: "Pizza", menuItems: MenuItem.sampleMenuItems.filter { $0.category == "Pizza" })
            .previewLayout(.sizeThatFits)
    }
}

Main Menu View

Implement the main menu view to display a list of menu items. Modify ContentView.swift:

import SwiftUI

struct ContentView: View {
    let menuItems = MenuItem.sampleMenuItems
    
    var groupedMenuItems: [String: [MenuItem]] {
        Dictionary(grouping: menuItems, by: { $0.category })
    }
    
    var body: some View {
        NavigationView {
            ScrollView {
                VStack(alignment: .leading) {
                    ForEach(groupedMenuItems.sorted(by: { $0.key < $1.key }), id: \.key) { category, items in
                        MenuCategoryView(category: category, menuItems: items)
                    }
                }
                .padding(.top)
            }
            .navigationTitle("Restaurant Menu")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Enhancements

  • Add Order Placement Functionality: Implement functionality for users to select menu items and place orders.
  • Networking: Load menu items from a remote API instead of using sample data.
  • Search: Add a search bar to filter menu items.

Conclusion

This tutorial provides a comprehensive guide to building a restaurant menu app in SwiftUI, covering data modeling, UI design, and interactive features. By leveraging SwiftUI’s declarative syntax and real-time preview, you can create engaging and functional apps efficiently. Use this foundation to explore advanced SwiftUI concepts and build even more sophisticated apps.