- Replace Core Data with SwiftData for iOS 18+ - Create MoodEntryModel as @Model class replacing MoodEntry entity - Create SharedModelContainer for App Group container sharing - Create DataController with CRUD extensions replacing PersistenceController - Update all views and view models to use MoodEntryModel - Update widget extension to use SwiftData - Remove old Core Data files (Persistence*.swift, .xcdatamodeld) - Add EntryType enum with all entry type cases - Fix widget label truncation with proper spacing and text scaling 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
136 lines
4.4 KiB
Swift
136 lines
4.4 KiB
Swift
//
|
|
// HeaderStatsView.swift
|
|
// Feels
|
|
//
|
|
// Created by Trey Tartt on 1/8/22.
|
|
//
|
|
|
|
import SwiftUI
|
|
import Charts
|
|
|
|
struct HeaderStatsView : UIViewRepresentable {
|
|
//Bar chart accepts data as array of BarChartDataEntry objects
|
|
var entries : [BarChartDataEntry]
|
|
var moodTints: [Color]
|
|
var textColor: Color
|
|
|
|
var tmpHolderToMakeViewDiffefrent: Color
|
|
|
|
init(fakeData: Bool, backDays: Int, moodTint: [Color], textColor: Color) {
|
|
self.moodTints = moodTint
|
|
self.textColor = textColor
|
|
guard moodTints.count == 5 else {
|
|
fatalError("mood tint count dont match")
|
|
}
|
|
self.tmpHolderToMakeViewDiffefrent = Color.random()
|
|
entries = [BarChartDataEntry]()
|
|
|
|
var moodEntries: [MoodEntryModel]?
|
|
|
|
if fakeData {
|
|
moodEntries = DataController.shared.randomEntries(count: 10)
|
|
} else {
|
|
var daysAgo = Calendar.current.date(byAdding: .day, value: -backDays, to: Date())!
|
|
daysAgo = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: daysAgo)!
|
|
|
|
moodEntries = DataController.shared.getData(startDate: daysAgo, endDate: Date(), includedDays: [1,2,3,4,5,6,7])
|
|
}
|
|
if let moodEntries = moodEntries {
|
|
for (index, mood) in Mood.allValues.enumerated() {
|
|
entries.append(
|
|
BarChartDataEntry(x: Double(index + 1),
|
|
y: Double(moodEntries.filter({
|
|
Int($0.moodValue) == mood.rawValue
|
|
}).count))
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
// this func is required to conform to UIViewRepresentable protocol
|
|
func makeUIView(context: Context) -> BarChartView {
|
|
//crate new chart
|
|
let chart = BarChartView()
|
|
chart.drawGridBackgroundEnabled = false
|
|
chart.drawValueAboveBarEnabled = false
|
|
|
|
chart.xAxis.drawAxisLineEnabled = false
|
|
chart.xAxis.labelTextColor = .clear
|
|
|
|
chart.rightAxis.drawAxisLineEnabled = false
|
|
chart.rightAxis.labelTextColor = .clear
|
|
|
|
chart.leftAxis.drawAxisLineEnabled = false
|
|
chart.leftAxis.labelTextColor = .clear
|
|
|
|
chart.xAxis.drawGridLinesEnabled = false
|
|
chart.leftAxis.drawGridLinesEnabled = false
|
|
chart.rightAxis.drawGridLinesEnabled = false
|
|
|
|
chart.leftAxis.axisLineColor = .clear
|
|
chart.rightAxis.axisLineColor = .clear
|
|
|
|
chart.legend.textColor = .clear
|
|
chart.legend.enabled = false
|
|
|
|
chart.drawBordersEnabled = false
|
|
chart.drawMarkers = false
|
|
chart.borderColor = .clear
|
|
|
|
chart.doubleTapToZoomEnabled = false
|
|
chart.leftAxis.axisMinimum = 0
|
|
|
|
chart.minOffset = 0
|
|
|
|
let data = BarChartData()
|
|
let dataSet = dataSet()
|
|
data.append(dataSet)
|
|
|
|
chart.data = data
|
|
dataSet.valueFormatter = DefaultValueFormatter(decimals: 0)
|
|
|
|
return chart
|
|
}
|
|
|
|
// this func is required to conform to UIViewRepresentable protocol
|
|
func updateUIView(_ uiView: BarChartView, context: Context) {
|
|
let data = BarChartData()
|
|
let dataSet = dataSet()
|
|
data.append(dataSet)
|
|
uiView.data = data
|
|
|
|
dataSet.valueFormatter = DefaultValueFormatter(decimals: 0)
|
|
}
|
|
|
|
func dataSet() -> BarChartDataSet {
|
|
let dataSet = BarChartDataSet(entries: entries)
|
|
|
|
// change bars color to green
|
|
dataSet.colors = moodTints.map({ NSUIColor( $0 ) })
|
|
dataSet.secondaryTextColor = UIColor(textColor)
|
|
dataSet.valueColors = [UIColor(textColor)]
|
|
dataSet.highlightAlpha = 0.0
|
|
dataSet.roundedCornerValue = 10
|
|
|
|
if let descriptor = UIFontDescriptor.preferredFontDescriptor(
|
|
withTextStyle: .title1).withSymbolicTraits([.traitBold]) {
|
|
dataSet.valueFont = UIFont(descriptor: descriptor, size: 0)
|
|
} else {
|
|
dataSet.valueFont = UIFont.preferredFont(forTextStyle: .title1)
|
|
}
|
|
|
|
return dataSet
|
|
}
|
|
|
|
typealias UIViewType = BarChartView
|
|
|
|
}
|
|
|
|
|
|
|
|
struct HeaderStatsView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
HeaderStatsView(fakeData: true, backDays: 30, moodTint: [Color.green, Color.blue, Color.yellow, Color.red, Color.orange], textColor: .white).frame(minHeight: 85, maxHeight: 90)
|
|
}
|
|
}
|