Skip to content

Commit

Permalink
Navigation demo
Browse files Browse the repository at this point in the history
  • Loading branch information
eLud committed May 30, 2024
1 parent bc6374a commit a554680
Show file tree
Hide file tree
Showing 36 changed files with 1,491 additions and 28 deletions.
58 changes: 53 additions & 5 deletions Projects/First contact/First contact.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
331CFF922C07358F00DC7D78 /* AppStoreButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331CFF912C07358F00DC7D78 /* AppStoreButtonStyle.swift */; };
331CFF942C0739E100DC7D78 /* AppStoreInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331CFF932C0739E100DC7D78 /* AppStoreInfoView.swift */; };
331CFF962C0770BC00DC7D78 /* ImagedToggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331CFF952C0770BC00DC7D78 /* ImagedToggle.swift */; };
331CFF9B2C0860AB00DC7D78 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331CFF9A2C0860AB00DC7D78 /* Application.swift */; };
331CFF9D2C0860F500DC7D78 /* AppData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331CFF9C2C0860F500DC7D78 /* AppData.swift */; };
331CFF9F2C0863FE00DC7D78 /* ApplicationListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331CFF9E2C0863FE00DC7D78 /* ApplicationListView.swift */; };
331CFFA12C08766D00DC7D78 /* AppIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331CFFA02C08766D00DC7D78 /* AppIconView.swift */; };
331CFFA32C08782300DC7D78 /* AppCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331CFFA22C08782300DC7D78 /* AppCellView.swift */; };
331CFFA52C087C3A00DC7D78 /* AppInstallButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331CFFA42C087C3A00DC7D78 /* AppInstallButton.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -28,6 +34,12 @@
331CFF912C07358F00DC7D78 /* AppStoreButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStoreButtonStyle.swift; sourceTree = "<group>"; };
331CFF932C0739E100DC7D78 /* AppStoreInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStoreInfoView.swift; sourceTree = "<group>"; };
331CFF952C0770BC00DC7D78 /* ImagedToggle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImagedToggle.swift; sourceTree = "<group>"; };
331CFF9A2C0860AB00DC7D78 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
331CFF9C2C0860F500DC7D78 /* AppData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppData.swift; sourceTree = "<group>"; };
331CFF9E2C0863FE00DC7D78 /* ApplicationListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationListView.swift; sourceTree = "<group>"; };
331CFFA02C08766D00DC7D78 /* AppIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIconView.swift; sourceTree = "<group>"; };
331CFFA22C08782300DC7D78 /* AppCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCellView.swift; sourceTree = "<group>"; };
331CFFA42C087C3A00DC7D78 /* AppInstallButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppInstallButton.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -61,11 +73,9 @@
isa = PBXGroup;
children = (
331CFF802C07201E00DC7D78 /* First_contactApp.swift */,
331CFF822C07201E00DC7D78 /* ContentView.swift */,
331CFF8F2C07300300DC7D78 /* AppStoreView.swift */,
331CFF912C07358F00DC7D78 /* AppStoreButtonStyle.swift */,
331CFF932C0739E100DC7D78 /* AppStoreInfoView.swift */,
331CFF952C0770BC00DC7D78 /* ImagedToggle.swift */,
331CFF992C08608900DC7D78 /* Models */,
331CFF972C08607400DC7D78 /* Views */,
331CFF982C08607A00DC7D78 /* Styles */,
331CFF842C07201F00DC7D78 /* Assets.xcassets */,
331CFF862C07201F00DC7D78 /* First_contact.entitlements */,
331CFF872C07201F00DC7D78 /* Preview Content */,
Expand All @@ -81,6 +91,38 @@
path = "Preview Content";
sourceTree = "<group>";
};
331CFF972C08607400DC7D78 /* Views */ = {
isa = PBXGroup;
children = (
331CFF822C07201E00DC7D78 /* ContentView.swift */,
331CFF8F2C07300300DC7D78 /* AppStoreView.swift */,
331CFF932C0739E100DC7D78 /* AppStoreInfoView.swift */,
331CFF952C0770BC00DC7D78 /* ImagedToggle.swift */,
331CFF9E2C0863FE00DC7D78 /* ApplicationListView.swift */,
331CFFA02C08766D00DC7D78 /* AppIconView.swift */,
331CFFA22C08782300DC7D78 /* AppCellView.swift */,
331CFFA42C087C3A00DC7D78 /* AppInstallButton.swift */,
);
path = Views;
sourceTree = "<group>";
};
331CFF982C08607A00DC7D78 /* Styles */ = {
isa = PBXGroup;
children = (
331CFF912C07358F00DC7D78 /* AppStoreButtonStyle.swift */,
);
path = Styles;
sourceTree = "<group>";
};
331CFF992C08608900DC7D78 /* Models */ = {
isa = PBXGroup;
children = (
331CFF9A2C0860AB00DC7D78 /* Application.swift */,
331CFF9C2C0860F500DC7D78 /* AppData.swift */,
);
path = Models;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -151,12 +193,18 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331CFF9B2C0860AB00DC7D78 /* Application.swift in Sources */,
331CFFA52C087C3A00DC7D78 /* AppInstallButton.swift in Sources */,
331CFF962C0770BC00DC7D78 /* ImagedToggle.swift in Sources */,
331CFF832C07201E00DC7D78 /* ContentView.swift in Sources */,
331CFF9D2C0860F500DC7D78 /* AppData.swift in Sources */,
331CFF902C07300300DC7D78 /* AppStoreView.swift in Sources */,
331CFF812C07201E00DC7D78 /* First_contactApp.swift in Sources */,
331CFF9F2C0863FE00DC7D78 /* ApplicationListView.swift in Sources */,
331CFFA32C08782300DC7D78 /* AppCellView.swift in Sources */,
331CFF922C07358F00DC7D78 /* AppStoreButtonStyle.swift in Sources */,
331CFF942C0739E100DC7D78 /* AppStoreInfoView.swift in Sources */,
331CFFA12C08766D00DC7D78 /* AppIconView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
uuid = "5845566B-65CB-4070-B27C-8C4B040B8DAF"
type = "1"
version = "2.0">
</Bucket>
36 changes: 35 additions & 1 deletion Projects/First contact/First contact/First_contactApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,43 @@ import SwiftUI
@main
struct First_contactApp: App {

//Old way before iOS 17
// @StateObject private var data = AppData(applications: [])

@State private var data: AppData = AppData(applications: Application.demoApps)

var body: some Scene {
WindowGroup {
AppStoreView(appName: "Duolingo", editorName: "Duolingo")
TabView {
NavigationStack(path: $data.todayPath) {
ApplicationListView()
.navigationDestination(for: Application.self) { app in
AppStoreView(app: app)
}
}
.tabItem {
Label("Aujourd'hui", systemImage: "list.bullet.rectangle.portrait")
}
NavigationStack {
ApplicationListView()
}
.tabItem {
Label("Jeux", systemImage: "gamecontroller")
}
ApplicationListView()
.tabItem {
Label("Apps", systemImage: "square.stack.3d.up")
}
ApplicationListView()
.tabItem {
Label("Arcade", systemImage: "arcade.stick.console")
}
ApplicationListView()
.tabItem {
Label("Recherche", systemImage: "magnifyingglass")
}
}
.environment(data)
}
}
}
49 changes: 49 additions & 0 deletions Projects/First contact/First contact/Models/AppData.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// AppData.swift
// First contact
//
// Created by Ludovic Ollagnier on 30/05/2024.
//

import Foundation

@Observable
class AppData {

var showDivider: Bool
var applications: [Application]

var installedApp: Set<Application>

var todayPath: [Application]

init(applications: [Application]) {
self.applications = applications
installedApp = []
showDivider = true
todayPath = []
}

func install(app: Application) {
installedApp.insert(app)
}

func isAppInstalled(_ app: Application) -> Bool {
installedApp.contains(app)
}
}

// Old way, before iOS 17
//class AppData: ObservableObject {
//
// @Published var showDivider: Bool
// @Published var applications: [Application]
//
// init(applications: [Application]) {
// self.applications = applications
// showDivider = true
//
//// Alternative à Published
//// objectWillChange.send()
// }
//}
27 changes: 27 additions & 0 deletions Projects/First contact/First contact/Models/Application.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// Application.swift
// First contact
//
// Created by Ludovic Ollagnier on 30/05/2024.
//

import Foundation

struct Application: Identifiable, Hashable {

let id = UUID()
let name: String
let appIconName: String
let developerName: String

let price: Double?
let hasInAppPurchase: Bool

static var demoApps: [Application] {
[Application(name: "Duolingo", appIconName: "eyes", developerName: "Duolingo", price: nil, hasInAppPurchase: true),
Application(name: "Procreate Pocket", appIconName: "pencil.and.scribble", developerName: "Savage Interactive", price: 6.99, hasInAppPurchase: false),
Application(name: "Filca - SLR Film Camera", appIconName: "camera", developerName: "Cheol Kim", price: 1.99, hasInAppPurchase: true),
Application(name: "Monopoly Go!", appIconName: "banknote", developerName: "Scopely", price: nil, hasInAppPurchase: true)
]
}
}
44 changes: 44 additions & 0 deletions Projects/First contact/First contact/Views/AppCellView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// AppCellView.swift
// First contact
//
// Created by Ludovic Ollagnier on 30/05/2024.
//

import SwiftUI

struct AppCellView: View {

let app: Application

var body: some View {
HStack {
AppIconView(iconName: app.appIconName, radius: 8)
.frame(width: 40, height: 40)
VStack(alignment: .leading) {
Text(app.name)
Text(app.developerName)
.font(.caption2)
.foregroundStyle(.secondary)
}
Spacer()
VStack {
AppInstallButton(app: app)
if app.hasInAppPurchase {
Text("Achats intégrés")
.font(.system(size: 8))
.fontWeight(.light)
.foregroundStyle(.secondary)
}
}
}
}
}

#Preview {
AppCellView(app: Application.demoApps.first!)
}

#Preview {
AppCellView(app: Application.demoApps.first!)
}
28 changes: 28 additions & 0 deletions Projects/First contact/First contact/Views/AppIconView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// AppIconView.swift
// First contact
//
// Created by Ludovic Ollagnier on 30/05/2024.
//

import SwiftUI

struct AppIconView: View {

let iconName: String
var radius = 20.0

var body: some View {
RoundedRectangle(cornerRadius: radius, style: .continuous)
.foregroundStyle(.gray)
.overlay {
Image(systemName: iconName)
.resizable()
.padding()
} }
}

#Preview {
AppIconView(iconName: "leaf")
.frame(width: 128, height: 128)
}
50 changes: 50 additions & 0 deletions Projects/First contact/First contact/Views/AppInstallButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// AppInstallButton.swift
// First contact
//
// Created by Ludovic Ollagnier on 30/05/2024.
//

import SwiftUI

struct AppInstallButton: View {

let app: Application

@Environment(\.locale) var locale
@Environment(AppData.self) var data: AppData

var body: some View {
Button(action: {
data.install(app: app)
}) {
if data.isAppInstalled(app) {
Image(systemName: "icloud.and.arrow.down")
.padding(.horizontal)
} else {
buttonText
.lineLimit(1)
.minimumScaleFactor(0.8)
.frame(width: 50)
}
}
.buttonStyle(AppStoreButtonStyle())
}

@ViewBuilder
private var buttonText: some View {
if let price = app.price {
Text(price, format: .currency(code: locale.currency?.identifier ?? "EUR"))
} else {
Text("Obtenir")
}
}
}

#Preview {
AppInstallButton(app: Application.demoApps.first!)
}

#Preview {
AppInstallButton(app: Application.demoApps.last!)
}
Loading

0 comments on commit a554680

Please sign in to comment.