Created basic main view, dates missing
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
6C264FB22B51D59B002CBE12 /* CalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C264FB12B51D59B002CBE12 /* CalendarView.swift */; };
|
6C264FB22B51D59B002CBE12 /* CalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C264FB12B51D59B002CBE12 /* CalendarView.swift */; };
|
||||||
6C264FB42B51DA90002CBE12 /* ElegantCalendar.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6C264FB32B51DA90002CBE12 /* ElegantCalendar.xcassets */; };
|
6C264FB42B51DA90002CBE12 /* ElegantCalendar.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6C264FB32B51DA90002CBE12 /* ElegantCalendar.xcassets */; };
|
||||||
6C264FB62B51EFDB002CBE12 /* DayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C264FB52B51EFDB002CBE12 /* DayView.swift */; };
|
6C264FB62B51EFDB002CBE12 /* DayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C264FB52B51EFDB002CBE12 /* DayView.swift */; };
|
||||||
|
6C264FB82B5209F8002CBE12 /* AspectVGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C264FB72B5209F8002CBE12 /* AspectVGrid.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
6C264FB12B51D59B002CBE12 /* CalendarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarView.swift; sourceTree = "<group>"; };
|
6C264FB12B51D59B002CBE12 /* CalendarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarView.swift; sourceTree = "<group>"; };
|
||||||
6C264FB32B51DA90002CBE12 /* ElegantCalendar.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = ElegantCalendar.xcassets; path = "../../../SourcePackages/checkouts/ElegantCalendar?tab=readme-ov-file#basic-usage/ElegantCalendar.xcassets"; sourceTree = BUILT_PRODUCTS_DIR; };
|
6C264FB32B51DA90002CBE12 /* ElegantCalendar.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = ElegantCalendar.xcassets; path = "../../../SourcePackages/checkouts/ElegantCalendar?tab=readme-ov-file#basic-usage/ElegantCalendar.xcassets"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
6C264FB52B51EFDB002CBE12 /* DayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DayView.swift; sourceTree = "<group>"; };
|
6C264FB52B51EFDB002CBE12 /* DayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DayView.swift; sourceTree = "<group>"; };
|
||||||
|
6C264FB72B5209F8002CBE12 /* AspectVGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AspectVGrid.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -66,6 +68,7 @@
|
|||||||
6C264F9C2B51A22F002CBE12 /* TrashTrackApp.swift */,
|
6C264F9C2B51A22F002CBE12 /* TrashTrackApp.swift */,
|
||||||
6C264FB52B51EFDB002CBE12 /* DayView.swift */,
|
6C264FB52B51EFDB002CBE12 /* DayView.swift */,
|
||||||
6C264F9E2B51A22F002CBE12 /* MainView.swift */,
|
6C264F9E2B51A22F002CBE12 /* MainView.swift */,
|
||||||
|
6C264FB72B5209F8002CBE12 /* AspectVGrid.swift */,
|
||||||
6C264FB12B51D59B002CBE12 /* CalendarView.swift */,
|
6C264FB12B51D59B002CBE12 /* CalendarView.swift */,
|
||||||
6C264FAA2B51A255002CBE12 /* TrashModel.swift */,
|
6C264FAA2B51A255002CBE12 /* TrashModel.swift */,
|
||||||
6C264FB32B51DA90002CBE12 /* ElegantCalendar.xcassets */,
|
6C264FB32B51DA90002CBE12 /* ElegantCalendar.xcassets */,
|
||||||
@@ -163,6 +166,7 @@
|
|||||||
files = (
|
files = (
|
||||||
6C264FB22B51D59B002CBE12 /* CalendarView.swift in Sources */,
|
6C264FB22B51D59B002CBE12 /* CalendarView.swift in Sources */,
|
||||||
6C264FB62B51EFDB002CBE12 /* DayView.swift in Sources */,
|
6C264FB62B51EFDB002CBE12 /* DayView.swift in Sources */,
|
||||||
|
6C264FB82B5209F8002CBE12 /* AspectVGrid.swift in Sources */,
|
||||||
6C264F9F2B51A22F002CBE12 /* MainView.swift in Sources */,
|
6C264F9F2B51A22F002CBE12 /* MainView.swift in Sources */,
|
||||||
6C264FAD2B51A26F002CBE12 /* TrashModelView.swift in Sources */,
|
6C264FAD2B51A26F002CBE12 /* TrashModelView.swift in Sources */,
|
||||||
6C264FAB2B51A255002CBE12 /* TrashModel.swift in Sources */,
|
6C264FAB2B51A255002CBE12 /* TrashModel.swift in Sources */,
|
||||||
|
|||||||
64
TrashTrack/AspectVGrid.swift
Normal file
64
TrashTrack/AspectVGrid.swift
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// AspectVGrid.swift
|
||||||
|
// TrashTrack
|
||||||
|
//
|
||||||
|
// Created by Oliver Hnát on 13.01.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct AspectVGrid<Item, ItemView>: View where ItemView: View, Item: Identifiable {
|
||||||
|
var items: [Item]
|
||||||
|
var aspectRatio: CGFloat
|
||||||
|
var content: (Item) -> ItemView
|
||||||
|
|
||||||
|
init(items: [Item], aspectRatio: CGFloat, @ViewBuilder content: @escaping (Item) -> ItemView) {
|
||||||
|
self.items = items
|
||||||
|
self.aspectRatio = aspectRatio
|
||||||
|
self.content = content
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
GeometryReader { geometry in
|
||||||
|
VStack {
|
||||||
|
let width: CGFloat = widthThatFits(itemCount: items.count, in: geometry.size, itemAspectRatio: aspectRatio)
|
||||||
|
LazyVGrid(columns: [adaptiveGridItem(width: width)], spacing: 0) {
|
||||||
|
ForEach(items) { item in
|
||||||
|
content(item).aspectRatio(aspectRatio, contentMode: .fit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer(minLength: 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func adaptiveGridItem(width: CGFloat) -> GridItem {
|
||||||
|
var gridItem = GridItem(.adaptive(minimum: width))
|
||||||
|
gridItem.spacing = 0
|
||||||
|
return gridItem
|
||||||
|
}
|
||||||
|
|
||||||
|
private func widthThatFits(itemCount: Int, in size: CGSize, itemAspectRatio: CGFloat) -> CGFloat {
|
||||||
|
var columnCount = 1
|
||||||
|
var rowCount = itemCount
|
||||||
|
repeat {
|
||||||
|
let itemWidth = size.width / CGFloat(columnCount)
|
||||||
|
let itemHeight = itemWidth / itemAspectRatio
|
||||||
|
if CGFloat(rowCount) * itemHeight < size.height {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
columnCount += 1
|
||||||
|
rowCount = (itemCount + (columnCount-1)) / columnCount
|
||||||
|
} while columnCount < itemCount
|
||||||
|
if columnCount > itemCount {
|
||||||
|
columnCount = itemCount
|
||||||
|
}
|
||||||
|
return floor(size.width / CGFloat(columnCount))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//struct AspectVGrid_Previews: PreviewProvider {
|
||||||
|
// static var previews: some View {
|
||||||
|
// AspectVGrid()
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@@ -8,11 +8,33 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct CalendarView: View {
|
struct CalendarView: View {
|
||||||
|
var events: [TrashEvent]
|
||||||
|
let columns: [GridItem] = Array(repeating: .init(.adaptive(minimum: 50, maximum: 50)), count: 7)
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
|
GeometryReader { geometry in
|
||||||
|
VStack {
|
||||||
|
let width: CGFloat = geometry.size.width / 8
|
||||||
|
LazyVGrid(columns: [adaptiveGridItem(width: width)], spacing: 0) {
|
||||||
|
ForEach(0..<events.count) { i in
|
||||||
|
let event = events[i]
|
||||||
|
DayView(image: event.trash.image, dayOfTheWeek: "TBD", date: event.id, color: event.trash.color)
|
||||||
|
// Text(String(event.id))
|
||||||
|
.frame(minWidth: 50, minHeight: 50)
|
||||||
|
.border(.black, width: 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Spacer(minLength: 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func adaptiveGridItem(width: CGFloat) -> GridItem {
|
||||||
|
var gridItem = GridItem(.adaptive(minimum: width))
|
||||||
|
gridItem.spacing = 0
|
||||||
|
return gridItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
CalendarView()
|
CalendarView(events: TrashModel().getTrashEvents().sorted(by: {$0.id < $1.id}))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,14 +21,13 @@ struct DayView: View {
|
|||||||
.cornerRadius(10)
|
.cornerRadius(10)
|
||||||
.scaledToFit()
|
.scaledToFit()
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
VStack {
|
|
||||||
Text("\(dayOfTheWeek)")
|
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
Text("\(date).")
|
|
||||||
.font(.headline)
|
|
||||||
Image(systemName: image)
|
Image(systemName: image)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
}
|
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||||
|
.padding(.trailing, 6)
|
||||||
|
.padding(.top, 30)
|
||||||
|
Text("\(date).")
|
||||||
|
.font(.headline)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,20 +10,29 @@ import SwiftUI
|
|||||||
struct MainView: View {
|
struct MainView: View {
|
||||||
var model = TrashModelView()
|
var model = TrashModelView()
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack {
|
GeometryReader { geometry in
|
||||||
ForEach(model.getTrashEvents()) { trashEvent in
|
VStack {
|
||||||
HStack {
|
CalendarView(events: model.getTrashEvents())
|
||||||
Image(systemName: trashEvent.trash.image)
|
.padding()
|
||||||
.imageScale(.large)
|
let width: CGFloat = geometry.size.width / 2
|
||||||
.foregroundStyle(.tint)
|
LazyVGrid(columns: [adaptiveGridItem(width: width)], spacing: 0) {
|
||||||
VStack {
|
DayView(image: "tree", dayOfTheWeek: "Mon", date: 31, color: .green)
|
||||||
Text(trashEvent.trash.type)
|
.padding()
|
||||||
Text(trashEvent.date.ISO8601Format())
|
DayView(image: "newspaper", dayOfTheWeek: "Tue", date: 31, color: .blue)
|
||||||
}
|
.padding()
|
||||||
|
DayView(image: "waterbottle", dayOfTheWeek: "Wed", date: 31, color: .orange)
|
||||||
|
.padding()
|
||||||
|
DayView(image: "trash", dayOfTheWeek: "Thu", date: 31, color: .gray)
|
||||||
|
.padding()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding()
|
}
|
||||||
|
|
||||||
|
private func adaptiveGridItem(width: CGFloat) -> GridItem {
|
||||||
|
var gridItem = GridItem(.adaptive(minimum: width))
|
||||||
|
gridItem.spacing = 0
|
||||||
|
return gridItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,15 +26,16 @@ struct TrashModel {
|
|||||||
|
|
||||||
init() {
|
init() {
|
||||||
self.trashTypes = [
|
self.trashTypes = [
|
||||||
Trash(type: "plastic", color: Color.orange, image: "waterbottle"),
|
Trash(type: "plastic", color: .orange, image: "waterbottle"),
|
||||||
Trash(type: "paper", color: Color.orange, image: "newspaper"),
|
Trash(type: "paper", color: .blue, image: "newspaper"),
|
||||||
Trash(type: "bio", color: Color.orange, image: "tree"),
|
Trash(type: "bio", color: .green, image: "tree"),
|
||||||
Trash(type: "residual", color: Color.orange, image: "trash")
|
Trash(type: "residual", color: .gray, image: "trash")
|
||||||
]
|
]
|
||||||
|
|
||||||
self.trashEvents = []
|
self.trashEvents = []
|
||||||
let numberOfEvents = 3
|
let numberOfEvents = 10
|
||||||
for i in 0..<numberOfEvents {
|
let start = 1
|
||||||
|
for i in start..<numberOfEvents {
|
||||||
self.trashEvents.append(
|
self.trashEvents.append(
|
||||||
TrashEvent(
|
TrashEvent(
|
||||||
id: i,
|
id: i,
|
||||||
@@ -44,7 +45,7 @@ struct TrashModel {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..<numberOfEvents {
|
for i in start..<numberOfEvents {
|
||||||
self.trashEvents.append(
|
self.trashEvents.append(
|
||||||
TrashEvent(
|
TrashEvent(
|
||||||
id: i + 4 + 7,
|
id: i + 4 + 7,
|
||||||
@@ -54,7 +55,7 @@ struct TrashModel {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..<numberOfEvents {
|
for i in start..<numberOfEvents {
|
||||||
self.trashEvents.append(
|
self.trashEvents.append(
|
||||||
TrashEvent(
|
TrashEvent(
|
||||||
id: i + 5,
|
id: i + 5,
|
||||||
@@ -64,7 +65,7 @@ struct TrashModel {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0..<numberOfEvents {
|
for i in start..<numberOfEvents {
|
||||||
self.trashEvents.append(
|
self.trashEvents.append(
|
||||||
TrashEvent(
|
TrashEvent(
|
||||||
id: i + 6 + 7,
|
id: i + 6 + 7,
|
||||||
@@ -74,7 +75,18 @@ struct TrashModel {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
print(self.trashEvents)
|
for i in 1..<30 {
|
||||||
|
if !self.trashEvents.contains(where: { $0.id == i }) {
|
||||||
|
self.trashEvents.append(
|
||||||
|
TrashEvent(
|
||||||
|
id: i,
|
||||||
|
trash: self.trashTypes[3],
|
||||||
|
date: Calendar.current.date(byAdding: .day, value: 6 + 7 + 7*i, to: Date())!
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.trashEvents.sort(by: { $0.id < $1.id })
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTrashEvents() -> [TrashEvent] {
|
func getTrashEvents() -> [TrashEvent] {
|
||||||
|
|||||||
Reference in New Issue
Block a user