Anytime I have 1 item, then add another, the app crashes with the following error:
Swift/IntegerTypes.swift:8835: Fatal error: Double value cannot be converted to Int because it is either infinite or NaN
I'm not working with Int values though, so I'm not sure why this is happening. It's also not point me towards any specific line. I've printed out all of the values being used for the chart and none of them are showing as infinite or NaN.
The data being used is created in a View.
@State private var pieChartData: [PieChartDataPoint] = []
Then in the onAppear and onChange its gets loaded using the following function:
func getPieChartDataPoints() -> [PieChartDataPoint] {
self.map({ PieChartDataPoint(label: $0.name, value: $0.monthlyAmount()) })
}
That's an extension on a SwiftData model type I have called Recurring.
@Model
final class Recurring {
var id = UUID()
enum Kind: String, CaseIterable, Codable {
case income = "Income"
case bill = "Bill"
func plural() -> String {
switch self {
case .income:
"Income"
case .bill:
"Bills"
}
}
}
enum Frequency: String, CaseIterable, Codable, Identifiable {
var id: Frequency { self }
case weekly = "Weekly"
case biweekly = "Biweekly"
case monthly = "Monthly"
case quarterly = "Quarterly"
case annually = "Annually"
}
var name: String = ""
var kind: Kind = Kind.income
var frequency: Frequency = Frequency.biweekly
var amount: Double = 0
init(name: String, kind: Kind, frequency: Frequency, amount: Double) {
self.name = name
self.kind = kind
self.frequency = frequency
self.amount = amount
}
func amount(from cycle: Cycle) -> Double {
switch cycle {
case .weekly:
monthlyAmount() * 12 / 52
case .biweekly:
monthlyAmount() * 12 / 26
case .monthly:
monthlyAmount()
}
}
func monthlyAmount() -> Double {
switch frequency {
case .weekly:
amount * 52 / 12
case .biweekly:
amount * 26 / 12
case .monthly:
amount
case .quarterly:
amount * 4 / 12
case .annually:
amount / 12
}
}
}
Here is the DataPoint structure.
struct PieChartDataPoint: Identifiable, Equatable {
var id = UUID()
var label: String
var value: Double
}
Finally here is the chart.
Chart(sorted, content: { dataPoint in
SectorMark(
angle: .value(dataPoint.label, getValue(from: dataPoint)),
innerRadius: 50,
angularInset: 5
)
.foregroundStyle(by: .value("Label", dataPoint.label))
.cornerRadius(10)
.opacity(getSectorMarkOpacity(for: dataPoint))
})
.scaledToFill()
.chartLegend(.hidden)
.chartAngleSelection(value: $chartSelection)
.onChange(of: chartSelection, checkSelection)
For testing purposes, I have removed all of the modifiers and only had a simple SectorMark in the Chart, however, that was still crashing.
Does anyone know why this is happening?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm trying to have a RoundedRectangle with a slightly different color border (stroke in this case) with a shadow behind it. The issue I'm having is that the shadow itself is being drawn overtop the stroke. I've tried using a ZStack with another RoundedRectangle in the background with a shadow, but I kept running into the same issue.
Anyone have any better ideas?
Section {
VStack {
RoundedRectangle(cornerRadius: 11)
.fill(color.shadow(.drop(color: .gray, radius: 2, x: 2, y: 2)))
.stroke(color.opacity(0.5), lineWidth: 5)
}
.frame(height: 200)
.padding()
}
.listRowInsets(EdgeInsets()) // Remove padding inside section, but causes clipping on the RoundedRectangle stroke
.listRowBackground(Color.clear) // Remove background color
Is this not possible? I have a simple text view that shows the time, but it doesn't stay in sync with the time. I've tried to use a timer like I do inside the app, but that didn't work. I tried TimelineView with it set to every minute, and that didn't work. I tried to use the dynamic date using Text(date, style: ) and that didn't work. I looked it up and apparently it's a limitation to WidgetKit, however, I don't understand how the Apple Clock widget can have a moving second hand that updates properly.
Do I just need to add a bunch of entries in the TimelineProvider? Right now, it's just the default that gets loaded when you create a Widget extension.
func timeline(for configuration: SingleClockIntent, in context: Context) async -> Timeline<SingleClockEntry> {
var entries: [SingleClockEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SingleClockEntry(date: entryDate, configuration: configuration)
entries.append(entry)
}
return Timeline(entries: entries, policy: .atEnd)
}
EDIT: This code below seems to be working. Can someone confirm if it will continue to work, or will it eventually stop updating?
func timeline(for configuration: SingleClockIntent, in context: Context) async -> Timeline<SingleClockEntry> {
var entries: [SingleClockEntry] = []
let calendar = Calendar.current
let current = Date()
// Get the next minute
let secondEntryDate = calendar.nextDate(after: current, matching: DateComponents(second: 0), matchingPolicy: .strict, direction: .forward)!
entries.append(SingleClockEntry(date: current, configuration: configuration)) // Adds current time
entries.append(SingleClockEntry(date: secondEntryDate, configuration: configuration)) // Adds next minute after current time
// Add an entry every min for the next 30 minutes
for offset in 0..<30 {
let entryDate = Calendar.current.date(byAdding: .minute, value: offset, to: secondEntryDate)!
let entry = SingleClockEntry(date: entryDate, configuration: configuration)
entries.append(entry)
}
return Timeline(entries: entries, policy: .atEnd)
}