From d94351a8f16abde2596a6c5d364c797de79f1ba2 Mon Sep 17 00:00:00 2001 From: Kiryl Kaveryn Date: Mon, 18 Aug 2025 13:07:15 +0400 Subject: [PATCH] [ios] Skip excessive elevation point updates When the user drags the elevation chart it runs chart's `selected point` update mechanism by calling the `onSelectedPointChanged` inside the `ChartView`'s ` func chartPreviewView(_ view: ChartPreviewView, didChangeMinX minX: Int, maxX: Int)`. This updates may be quite often (tens/hundreds per sec) and may cause the `on point update` callback **recursion** and overloads the `layoutSubviews` method on the _short track_ because the ChartView doesnt have mechanism to skip excessive updates when the parameters the same. This situation produces fail with internal error `(null) in -[NSISEngine _flushPendingRemovals] ().` The fix include: 1. skip updates when the current point isn't changed 2. remove layoutSubviews overloading (this method should recalc the layout immediately and should not be called too frequent, the `setNeedsLayout` allows to batch the layout updates and redraw the view on the next runtime cycle) Signed-off-by: Kiryl Kaveryn --- iphone/Chart/Chart/Views/ChartInfo/ChartPointInfoView.swift | 2 +- iphone/Chart/Chart/Views/ChartView.swift | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/iphone/Chart/Chart/Views/ChartInfo/ChartPointInfoView.swift b/iphone/Chart/Chart/Views/ChartInfo/ChartPointInfoView.swift index 87a2f4dc8..feda061a1 100644 --- a/iphone/Chart/Chart/Views/ChartInfo/ChartPointInfoView.swift +++ b/iphone/Chart/Chart/Views/ChartInfo/ChartPointInfoView.swift @@ -94,7 +94,7 @@ final class ChartPointInfoView: UIView { func update(x: CGFloat, label: String, points: [ChartLineInfo]) { distanceLabel.text = label altitudeLabel.text = altitudeText(points[0]) - layoutIfNeeded() + setNeedsLayout() } private func altitudeText(_ point: ChartLineInfo) -> String { diff --git a/iphone/Chart/Chart/Views/ChartView.swift b/iphone/Chart/Chart/Views/ChartView.swift index 682b62124..90678cde7 100644 --- a/iphone/Chart/Chart/Views/ChartView.swift +++ b/iphone/Chart/Chart/Views/ChartView.swift @@ -16,6 +16,7 @@ public class ChartView: UIView { var showPreview: Bool = false // Set true to show the preview private var tapGR: UITapGestureRecognizer! + private var selectedPointDistance: Double = 0 private var panStartPoint = 0 private var panGR: UIPanGestureRecognizer! private var pinchStartLower = 0 @@ -170,6 +171,8 @@ public class ChartView: UIView { } public func setSelectedPoint(_ x: Double) { + guard selectedPointDistance != x else { return } + selectedPointDistance = x let routeLength = chartData.xAxisValueAt(CGFloat(chartData.pointsCount - 1)) let upper = chartData.xAxisValueAt(CGFloat(chartPreviewView.maxX)) var lower = chartData.xAxisValueAt(CGFloat(chartPreviewView.minX))