Post

Replies

Boosts

Views

Activity

Reply to TabView and Swift Charts giving inconsistent behaviour when swiping between pages
Ok. I have paired it all the way back to a single page of code. You can see the text at the top of the graph is the Y coords and it doesn't match the chart. If I had included interactivity then tapping on the graph would make it show the correct chart. Code: import SwiftUI import Charts struct Point: Identifiable { var x: Int var y: Int let id = UUID() } struct PointData: Identifiable { var points: [Point] let id = UUID() } struct TabSelectorView: View { var pointDataArray: [PointData] = [] init() { self.pointDataArray = initData() } var body: some View { let data = pointDataArray VStack { TabView { ForEach((0..<data.count), id: \.self) { index in VStack { let graphData = pointDataArray[index] Text (graphData.points.map { String($0.y) }.joined(separator: ",")) Chart(graphData.points) { item in LineMark( x: .value("X", item.x), y: .value("Y", item.y) ) .symbol { Circle() .fill(Color.orange) .frame(width: 10) } } } .tag((index)) } } .tabViewStyle(.page) .indexViewStyle(.page(backgroundDisplayMode: .always)) } } func initData() -> [PointData] { var ret: [PointData] = [] for chartNum in 0...6 { var pointArray: [Point] = [] for point in 0...5 { pointArray.append(Point(x: point, y: point + chartNum)) } ret.append(PointData(points: pointArray)) } return ret } } #Preview { return TabSelectorView() .frame(height: 400) .padding(50) } Am I doing something obviously wrong?! Note that some tab pages are correct and others are incorrect, and it changes as you swipe through.
Mar ’24
Reply to TabView and Swift Charts giving inconsistent behaviour when swiping between pages
Ok.....so I made the change to my live app to add the ID to the chart with a UUID. Good news is that the swiping bug is now cleared. Bad news is now interactivity is broken! Without the .id(UUID()) modifier to the chart then when I interact with the chart it behaves normally insofar as when I tap the chart then up comes the annotation view that I have coded . When I scroll with my finger then the annotation updates to the closest point in the chart. When I remove my finger then the annotation disappears. However if I add the .id(UUID()) modifier to the chart then interactions go awry. I cannot keep my finger down and scroll through the points and, worse, the annotation does not remove itself after I have lifted my finger. Therefore there doesn't seem to be a way to remove the annotation. I have updated my MVP code to illustrate. If you keep the '.id' line in then the swiping works but the interaction doesn't work. If you comment out the '.id' line then the original swiping problem comes back but the interaction works as expected. I have updated this in the feedback item I raised. Updated code: import SwiftUI import Charts struct Point: Identifiable { var x: Int var y: Int let id = UUID() } struct PointData: Identifiable { var points: [Point] let id = UUID() } struct TabSelectorView: View { @State private var selectedIndex: Int? // NEW var pointDataArray: [PointData] = [] init() { self.pointDataArray = initData() } var body: some View { VStack { TabView { ForEach((0..<pointDataArray.count), id: \.self) { index in VStack { let graphData = pointDataArray[index] Text ("Selected index: \(selectedIndex == nil ? "None" : String(selectedIndex!) )") // NEW Text (graphData.points.map { String($0.y) }.joined(separator: ",")) Chart(graphData.points) { item in LineMark( x: .value("X", item.x), y: .value("Y", item.y) ) .symbol { Circle() .fill(Color.orange) .frame(width: 10) } } .id(UUID()) // NEW. Comment out to fix interaction but break swiping .chartXSelection(value: $selectedIndex) // NEW } .tag((index)) } } .tabViewStyle(.page) .indexViewStyle(.page(backgroundDisplayMode: .always)) } } func initData() -> [PointData] { var ret: [PointData] = [] for chartNum in 0...6 { var pointArray: [Point] = [] for point in 0...5 { pointArray.append(Point(x: point, y: point + chartNum)) } ret.append(PointData(points: pointArray)) } return ret } } #Preview { return TabSelectorView() .frame(height: 400) .padding(50) }
Mar ’24