This question is in reference to DanielGindi/Charts but I think some knowledge of NSView rendering might help even if you're not familiar with the Charts library.
I'm using Charts in a MacOS project, and having trouble with getting MarkerView to display correctly. I've copied RadarMarkerView from the ChartsDemo-iOS project to ChartsDemo-macOS in order to use it in the MacOS RadarDemoViewController. But the marker never appears in the view when I click on a value in the chart.
Here is the full implementation of RadarMarkerViewMac:
public class RadarMarkerViewMac: MarkerView {
@IBOutlet var label: NSTextField!
public override func awakeFromNib() {
self.offset.x = -self.frame.size.width / 2.0
self.offset.y = -self.frame.size.height - 7.0
}
public override func refreshContent(entry: ChartDataEntry, highlight: Highlight) {
label.stringValue = String.init(format: "%.3f %%", (entry.y))
_ = self // see note 2
layout() // see note 1
}
}
As you can see if you look at the original RadarMarkerView, there are only two notable changes:
layoutIfNeeded()is changed tolayout()because the former function doesn't exist inNSView.- I put this line in there so that I could add a breakpoint to see if
selfwas being drawn correctly (when paused for a breakpoint, hover mouse overself, then click the eyeball button to see the view).
The weird thing I discovered was this: Clicking on the chart highlights the selected value but doesn't show the marker. However, when I put a breakpoint on the layout() line, then viewed self with the preview popup, I saw the view just fine... and then once I continued the app running, the marker appeared as it should in the chart in all subsequent selections, even with the breakpoint disabled.
Also important to note, I think, is that if I put the breakpoint in and DIDN'T show the preview, the marker would not display on the chart.
I assume this has something to do with the NSView rendering, but I haven't been able to make the app behave correctly here. Can you help?
It is not sufficient to only copy
RadarMarkerView.You need to create a corresponding xib for macOS. In
RadarDemoViewControllerinviewDidLoadload the view from xib and add it as a subview outside of visible area, so that it can be rendered:As one can see in MarkerView a property
nsuiLayeris used, which basically corresponds toself.layer.Therefore you need to specify that you want the view to use a layer as its backing store.
You can define an offset (depending on the size of your view):
And in
refreshContentyou specify that the view needs a layout pass before it can be drawn withSo the complete
RadarMarkerViewlooks something like this:Note the override of
draw(context:point:). To make debugging easier, you can programmatically draw a red rectangle (just uncomment the two lines).Test
As you can see the marker is then shown.