Post

Replies

Boosts

Views

Activity

Reply to Using .glassEffect in Charts
Adopting Liquid Glass goes over some best practices for Liquid Glass effects. Please file an enhancement request and include your use case. Post the FB number here once you file the request. Thanks! I have watched the session, and I'll have a think about if over the next couple of weeks. If it feels like it makes sense I'll make sure to file an enhancement request. Still figuring out where to best take advantage of .glassEffect. Generally speaking, Liquid Glass is not a part of Swift Charts. Thank you very much for the clarification! I suspected that would be the case, but still wanted to double check.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jun ’25
Reply to .chartXScale not scaling domain of Chart as expected
[quote='795150022, AppleCare Staff, /thread/759244?answerId=795150022#795150022'] So just a few lines of code would be enough, I think it should fit in 20 lines or less. For data, you can inline an array of tuples as I described. No need for preview, extensions, structs etc. just a single Chart. [/quote] Apologies, I thought perhaps an example with a Preview would be beneficial for demonstration purposes. I'm happy to reduce the amount of code a bit. No more extra structs, previews or extensions! However, I can't really get it down to 20 lines if I am to simulate my issue. I need a month of measurements and I'm not sure I can even create the array of ~30 items (with plenty of Calendar.current operations) in 20 lines of code. I hope about 40 lines of code is okay! let cal: Calendar = .current struct ChartWithNilValues2: View { let start: Date = cal.date(from: cal.dateComponents([.year, .month], from: .now))! let end: Date init() { end = cal.date(byAdding: .month, value: 1, to: start)! } var body: some View { Chart(generateMeasurements(start: start, end: end), id: \.0) { measurement in if let total = measurement.1 { BarMark( x: .value("", measurement.0, unit: .weekOfYear, calendar: cal), y: .value("", total) ) } } .chartXAxis { AxisMarks(values: .stride(by: .weekOfYear)) { value in AxisValueLabel("\(value.index)", centered: true) } } .padding() .chartXScale(domain: start...end) } func generateMeasurements(start: Date, end: Date) -> [(Date, Double?)] { var measurements: [(Date, Double?)] = [] let dateComponents = cal.dateComponents([.day], from: start, to: end) guard let count = dateComponents.value(for: .day) else { return [] } for i in 0 ..< count { if let time = cal.date(byAdding: .day, value: i, to: start), time <= end { let production = i > count - 10 ? nil : Double.random(in: 0 ... 50) let measurement = (time, production) measurements.append(measurement) } } return measurements } } One thing that I observed trimming this down, is that if I move the definition of the end date from the init function to the struct definition, the problem seems to go away. 🤔 Hope that can be of some kind of assistance! Final note: I'm in Stockholm, Sweden. So Calendar.current is Central European Time for me, if that makes a difference in your assessment.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’24
Reply to .chartXScale not scaling domain of Chart as expected
[quote='794978022, AppleCare Staff, /thread/759244?answerId=794978022#794978022'] No need for an entire repo, just a minimal, but runnable example that exhibits the issue. [/quote] Alright! This should do: import SwiftUI import Charts struct ChartWithoutNilValues: View { let firstDayOfMonth: Date let firstDayOfNextMonth: Date let measurements: [PerformanceMeasurement] init() { firstDayOfMonth = Date.now.firstDayOfMonth()! firstDayOfNextMonth = Calendar.current.date(byAdding: .month, value: 1, to: firstDayOfMonth)! measurements = DataGenerator.generateMeasurements( interval: DateInterval(start: firstDayOfMonth, end: firstDayOfNextMonth), component: .day ) } var body: some View { Chart(measurements, id: \.timestamp) { measurement in BarMark( x: .value( "Timestamp", measurement.timestamp, unit: .weekOfYear, calendar: .current ), y: .value( "Solar production", measurement.production?.total ?? 0 ) ) } .chartXAxis { AxisMarks(values: .stride(by: .weekOfYear)) { value in AxisValueLabel("\(value.index)", centered: true) } } .padding() } } struct ChartWithNilValues: View { let firstDayOfMonth: Date let firstDayOfNextMonth: Date let measurements: [PerformanceMeasurement] init() { firstDayOfMonth = Date.now.firstDayOfMonth()! firstDayOfNextMonth = Calendar.current.date(byAdding: .month, value: 1, to: firstDayOfMonth)! measurements = DataGenerator.generateMeasurements( interval: DateInterval(start: firstDayOfMonth, end: firstDayOfNextMonth), component: .day ) } var body: some View { Chart(measurements, id: \.timestamp) { measurement in if let total = measurement.production?.total { BarMark( x: .value( "Timestamp", measurement.timestamp, unit: .weekOfYear, calendar: .current ), y: .value( "Solar production", total ) ) } } .chartXAxis { AxisMarks(values: .stride(by: .weekOfYear)) { value in AxisValueLabel("\(value.index)", centered: true) } } .padding() .chartXScale(domain: firstDayOfMonth...firstDayOfNextMonth) } } #Preview { VStack { ChartWithoutNilValues() ChartWithNilValues() } .padding() } struct DataGenerator { let currentYear = Calendar.current.component(.year, from: .now) let startOfDay = Calendar.current.startOfDay(for: .now) static func generateMeasurements(interval: DateInterval, component: Calendar.Component) -> [PerformanceMeasurement] { var measurements: [PerformanceMeasurement] = [] let calendar = Calendar.current let dateComponents = calendar.dateComponents([component], from: interval.start, to: interval.end) guard let count = dateComponents.value(for: component) else { return [] } for i in 0 ..< count { if let time = calendar.date(byAdding: component, value: i, to: interval.start), time <= interval.end { let production = createProduction(from: i > count - 10 ? nil : randomNumber) let measurement = PerformanceMeasurement( timestamp: time, production: production ) measurements.append(measurement) } } return measurements } static private var randomNumber: Double? { Double.random(in: 0 ... 50) } static private func createProduction(from total: Double?) -> PerformanceMeasurement.Production { guard let total else { return PerformanceMeasurement.Production(total: nil, sold: nil, consumed: nil) } let sold = Double.random(in: 0 ... total) let consumed = total - sold return PerformanceMeasurement.Production(total: total, sold: sold, consumed: consumed) } } struct PerformanceMeasurement: Codable, Equatable { let timestamp: Date let production: Production? struct Production: Codable, Equatable { let total: Double? let sold: Double? let consumed: Double? } } extension Date { func firstDayOfMonth(in calendar: Calendar = .current) -> Date? { calendar.date(from: calendar.dateComponents([.year, .month], from: self)) } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’24
Reply to .chartXScale not scaling domain of Chart as expected
[quote='794844022, AppleCare Staff, /thread/759244?answerId=794844022#794844022'] Got it, I see what you want. But I'm not sure I understand the full setup. The code on the top uses .weekOfYear and then the domain is not set to week boundaries but to month boundaries, and it's not clear to me how the two relate in your use. Have you a small, single self-contained example with data in place? You can even use tuples in an array like [(date0, value0), ...] [/quote] I apologize if things are not clear. It might simply be because I don't have a full understanding of how I'm supposed to use the modifier. Let me try and break it down. My data set is an array of one measurement per day in a month (so I have about ~30 entries per array, naturally). This is the reason I try to set the domain of the chart from the first day in a month, to the last day in a month. I figured with that, the Chart would understand the timespan I'm trying to plot (no matter if I sort it all by .weekOfYear or not). Is that not the case? Should I set the domain in some different way when sorting the data by weekOfYear? I'm not sure I get the last sentence? Tuples for the domain? I do have an Xcode project with a minimum reproducible example, but I guess I can't share it here directly. Should I file a feedback with it, or share it in some other way?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’24
Reply to .chartXScale not scaling domain of Chart as expected
[quote='794848022, AppleCare Staff, /thread/759244?answerId=794848022#794848022'] Currently, the bar placement is conditional (non-nil total). Can you make it unconditional, such that nils get mapped to zero values? [/quote] My intention is to differentiate between nil and 0. nil would mean there's data missing, and 0 would mean there technically is data present, the total value of the measurements is just 0. So if I understand your question correctly, my answer would be: No, sadly not.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’24
Reply to Apple Watch not showing in XCode
Same issue. Xcode 15.3 (tried downloading 15.2 as well, no luck). watchOS 10.4. Here's how I got into this state: Xcode would never be able to build to my watch, so I figured I'd try and unpair the Watch from the devices list in Xcode and then pair it again. Should probably never have done that, because even after unpairing the Watch from my iPhone and resetting it, turning on and off developer mode, cleaning out all sorts of caches... I've tried everything and it never shows up anywhere. It's not even listed when using xcrun devicectl list devices. It's now taken about 24 hours of dev time away from me, which is unacceptable for something this basic.
Apr ’24
Reply to Using .glassEffect in Charts
Adopting Liquid Glass goes over some best practices for Liquid Glass effects. Please file an enhancement request and include your use case. Post the FB number here once you file the request. Thanks! I have watched the session, and I'll have a think about if over the next couple of weeks. If it feels like it makes sense I'll make sure to file an enhancement request. Still figuring out where to best take advantage of .glassEffect. Generally speaking, Liquid Glass is not a part of Swift Charts. Thank you very much for the clarification! I suspected that would be the case, but still wanted to double check.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’25
Reply to onPreferenceChange closure is now nonIsolated?
How are you getting around this? My spontaneous thought was to use a Task to dispatch to the MainActor, but that seems to introduce visual glitches that weren't there previously.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Nov ’24
Reply to .chartXScale not scaling domain of Chart as expected
[quote='795150022, AppleCare Staff, /thread/759244?answerId=795150022#795150022'] So just a few lines of code would be enough, I think it should fit in 20 lines or less. For data, you can inline an array of tuples as I described. No need for preview, extensions, structs etc. just a single Chart. [/quote] Apologies, I thought perhaps an example with a Preview would be beneficial for demonstration purposes. I'm happy to reduce the amount of code a bit. No more extra structs, previews or extensions! However, I can't really get it down to 20 lines if I am to simulate my issue. I need a month of measurements and I'm not sure I can even create the array of ~30 items (with plenty of Calendar.current operations) in 20 lines of code. I hope about 40 lines of code is okay! let cal: Calendar = .current struct ChartWithNilValues2: View { let start: Date = cal.date(from: cal.dateComponents([.year, .month], from: .now))! let end: Date init() { end = cal.date(byAdding: .month, value: 1, to: start)! } var body: some View { Chart(generateMeasurements(start: start, end: end), id: \.0) { measurement in if let total = measurement.1 { BarMark( x: .value("", measurement.0, unit: .weekOfYear, calendar: cal), y: .value("", total) ) } } .chartXAxis { AxisMarks(values: .stride(by: .weekOfYear)) { value in AxisValueLabel("\(value.index)", centered: true) } } .padding() .chartXScale(domain: start...end) } func generateMeasurements(start: Date, end: Date) -> [(Date, Double?)] { var measurements: [(Date, Double?)] = [] let dateComponents = cal.dateComponents([.day], from: start, to: end) guard let count = dateComponents.value(for: .day) else { return [] } for i in 0 ..< count { if let time = cal.date(byAdding: .day, value: i, to: start), time <= end { let production = i > count - 10 ? nil : Double.random(in: 0 ... 50) let measurement = (time, production) measurements.append(measurement) } } return measurements } } One thing that I observed trimming this down, is that if I move the definition of the end date from the init function to the struct definition, the problem seems to go away. 🤔 Hope that can be of some kind of assistance! Final note: I'm in Stockholm, Sweden. So Calendar.current is Central European Time for me, if that makes a difference in your assessment.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’24
Reply to .chartXScale not scaling domain of Chart as expected
[quote='794978022, AppleCare Staff, /thread/759244?answerId=794978022#794978022'] No need for an entire repo, just a minimal, but runnable example that exhibits the issue. [/quote] Alright! This should do: import SwiftUI import Charts struct ChartWithoutNilValues: View { let firstDayOfMonth: Date let firstDayOfNextMonth: Date let measurements: [PerformanceMeasurement] init() { firstDayOfMonth = Date.now.firstDayOfMonth()! firstDayOfNextMonth = Calendar.current.date(byAdding: .month, value: 1, to: firstDayOfMonth)! measurements = DataGenerator.generateMeasurements( interval: DateInterval(start: firstDayOfMonth, end: firstDayOfNextMonth), component: .day ) } var body: some View { Chart(measurements, id: \.timestamp) { measurement in BarMark( x: .value( "Timestamp", measurement.timestamp, unit: .weekOfYear, calendar: .current ), y: .value( "Solar production", measurement.production?.total ?? 0 ) ) } .chartXAxis { AxisMarks(values: .stride(by: .weekOfYear)) { value in AxisValueLabel("\(value.index)", centered: true) } } .padding() } } struct ChartWithNilValues: View { let firstDayOfMonth: Date let firstDayOfNextMonth: Date let measurements: [PerformanceMeasurement] init() { firstDayOfMonth = Date.now.firstDayOfMonth()! firstDayOfNextMonth = Calendar.current.date(byAdding: .month, value: 1, to: firstDayOfMonth)! measurements = DataGenerator.generateMeasurements( interval: DateInterval(start: firstDayOfMonth, end: firstDayOfNextMonth), component: .day ) } var body: some View { Chart(measurements, id: \.timestamp) { measurement in if let total = measurement.production?.total { BarMark( x: .value( "Timestamp", measurement.timestamp, unit: .weekOfYear, calendar: .current ), y: .value( "Solar production", total ) ) } } .chartXAxis { AxisMarks(values: .stride(by: .weekOfYear)) { value in AxisValueLabel("\(value.index)", centered: true) } } .padding() .chartXScale(domain: firstDayOfMonth...firstDayOfNextMonth) } } #Preview { VStack { ChartWithoutNilValues() ChartWithNilValues() } .padding() } struct DataGenerator { let currentYear = Calendar.current.component(.year, from: .now) let startOfDay = Calendar.current.startOfDay(for: .now) static func generateMeasurements(interval: DateInterval, component: Calendar.Component) -> [PerformanceMeasurement] { var measurements: [PerformanceMeasurement] = [] let calendar = Calendar.current let dateComponents = calendar.dateComponents([component], from: interval.start, to: interval.end) guard let count = dateComponents.value(for: component) else { return [] } for i in 0 ..< count { if let time = calendar.date(byAdding: component, value: i, to: interval.start), time <= interval.end { let production = createProduction(from: i > count - 10 ? nil : randomNumber) let measurement = PerformanceMeasurement( timestamp: time, production: production ) measurements.append(measurement) } } return measurements } static private var randomNumber: Double? { Double.random(in: 0 ... 50) } static private func createProduction(from total: Double?) -> PerformanceMeasurement.Production { guard let total else { return PerformanceMeasurement.Production(total: nil, sold: nil, consumed: nil) } let sold = Double.random(in: 0 ... total) let consumed = total - sold return PerformanceMeasurement.Production(total: total, sold: sold, consumed: consumed) } } struct PerformanceMeasurement: Codable, Equatable { let timestamp: Date let production: Production? struct Production: Codable, Equatable { let total: Double? let sold: Double? let consumed: Double? } } extension Date { func firstDayOfMonth(in calendar: Calendar = .current) -> Date? { calendar.date(from: calendar.dateComponents([.year, .month], from: self)) } }
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’24
Reply to .chartXScale not scaling domain of Chart as expected
[quote='794844022, AppleCare Staff, /thread/759244?answerId=794844022#794844022'] Got it, I see what you want. But I'm not sure I understand the full setup. The code on the top uses .weekOfYear and then the domain is not set to week boundaries but to month boundaries, and it's not clear to me how the two relate in your use. Have you a small, single self-contained example with data in place? You can even use tuples in an array like [(date0, value0), ...] [/quote] I apologize if things are not clear. It might simply be because I don't have a full understanding of how I'm supposed to use the modifier. Let me try and break it down. My data set is an array of one measurement per day in a month (so I have about ~30 entries per array, naturally). This is the reason I try to set the domain of the chart from the first day in a month, to the last day in a month. I figured with that, the Chart would understand the timespan I'm trying to plot (no matter if I sort it all by .weekOfYear or not). Is that not the case? Should I set the domain in some different way when sorting the data by weekOfYear? I'm not sure I get the last sentence? Tuples for the domain? I do have an Xcode project with a minimum reproducible example, but I guess I can't share it here directly. Should I file a feedback with it, or share it in some other way?
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’24
Reply to .chartXScale not scaling domain of Chart as expected
[quote='794848022, AppleCare Staff, /thread/759244?answerId=794848022#794848022'] Currently, the bar placement is conditional (non-nil total). Can you make it unconditional, such that nils get mapped to zero values? [/quote] My intention is to differentiate between nil and 0. nil would mean there's data missing, and 0 would mean there technically is data present, the total value of the measurements is just 0. So if I understand your question correctly, my answer would be: No, sadly not.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’24
Reply to Swift Charts animation woes using centered AxisValueLabel
Done! FB13888781.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jun ’24
Reply to Apple Watch won't show in device list on Xcode after 10.4 upgrade
I have the same issue. Cannot even see the watch listed when I use xcrun devicectl list devices in the Terminal. Tried unpairing the Watch from my iPhone and pairing it again, cleaning out all sorts of caches, turning on and off developer mode. watchOS 10.4, Xcode 15.3 (15.2 doesn't work either).
Replies
Boosts
Views
Activity
Apr ’24
Reply to Apple Watch not showing in XCode
Same issue. Xcode 15.3 (tried downloading 15.2 as well, no luck). watchOS 10.4. Here's how I got into this state: Xcode would never be able to build to my watch, so I figured I'd try and unpair the Watch from the devices list in Xcode and then pair it again. Should probably never have done that, because even after unpairing the Watch from my iPhone and resetting it, turning on and off developer mode, cleaning out all sorts of caches... I've tried everything and it never shows up anywhere. It's not even listed when using xcrun devicectl list devices. It's now taken about 24 hours of dev time away from me, which is unacceptable for something this basic.
Replies
Boosts
Views
Activity
Apr ’24
Reply to Xcode 14 try to build all SPM when building swiftUI preview
Since I'm still experiencing the same issue in Xcode 15.1, I've now also submitted feedback for this issue (FB13467714). It's quite ridiculous this hasn't been fixed yet.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Dec ’23
Reply to Xcode 14 try to build all SPM when building swiftUI preview
I have the same issue using the latest Xcode 15.0.1 (15A507). Previews stop working if any dependency imported using the Swift Package Manager doesn't support watchOS, even if those frameworks (in my case Datadog and Lottie) are not directly linked or used in the watchOS target.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Nov ’23
Reply to Dynamically modifying the configuration properties of a widget?
I'm wondering the same thing. It does seem like it's only run once though, as you said. :/
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Jul ’21