ivnsch / SwiftCharts

Easy to use and highly customizable charts library for iOS
Apache License 2.0
2.53k stars 410 forks source link

Can't trigger touch handler in Simulator or device(iPhone 6 plus) #320

Closed hopy11 closed 6 years ago

hopy11 commented 6 years ago

hello guys :) I download SwiftCharts Demo and run it in Simulator and Device.

But in example "Notification (interactive)" and "Show touch coords (interactive)" , I touch screen at some point can't trigger any touch handler.(e.g. popup a view and etc...)

simulator screen shot - iphone 6 - 2017-12-03 at 21 13 03

I look into the source code for those example :NotificationExample.swift and CoordsExample.swift , I think it should be trigger some touch handler ...

What's wrong with it? thanks ;)

ivnsch commented 6 years ago

I uploaded a fix, please update master!

Will also do a release soon.

hopy11 commented 6 years ago

thanks! but could you tell me why can't touch before in brief :)?

hopy11 commented 6 years ago

ok.I zoomed chart 2x before show it:

chart.delegate = self chart.zoom(scaleX: 2, scaleY: 1, centerX: 0, centerY: 0)

and I also set chart's zoom setting:

chartSettings.zoomPan.maxZoomX = 20 chartSettings.zoomPan.minZoomX = 1

when I run app it show like that:

simulator screen shot - iphone 6 - 2017-12-04 at 14 44 40

you can see points in the chart have some offset to left,I expect it show like that:

simulator screen shot - iphone 6 - 2017-12-04 at 14 48 00

In my code , the points layer is : layerPP = ChartPointsViewsLayer(xAxis: xAxisLayer.axis, yAxis: yAxisLayer.axis, chartPoints: chartPoints, viewGenerator: circleViewGenerator, displayDelay: 0.9, delayBetweenItems: 0.5, mode: .translate)

Do I need do something with layerPP? thanks again ;)

ivnsch commented 6 years ago

The touch was because there's a view on top of the container to handle a special type of transform which was consuming the taps. This view shouldn't be always interactive.

The problem you're experiencing is a relatively new area, that needs some improvements. Theoretically the solution would be to set delayInit: true on the layer and call myViewsLayer.initViews(chart) after the chart has been initialized, such that it gets the correct transforms, the same way it's done with the line layer in the example you're using. But it turns that this doesn't work on the view layer when you use min/max zooming.

A partial workaround for this would be to set the initial zoom programmatically instead of using min/max, of course you lose min/max, but other than that works as expected. So after creation of the chart you call

chart.zoom(deltaX: 2, deltaY: 1)

(You probably also want to pass 0, 0 anchor such that it starts at the origin, or call pan to start with a specific offset).

And then after the chart has been added as subview myViewsLayer.initViews(chart).

(And don't forget to pass delayInit: true to the views layer).

It may also work with min/max depending on the values you pass, you could experiment a little with that.

Let me know if that works for you.

hopy11 commented 6 years ago

It's look like not work for me :(

    //chartSettings.zoomPan.maxZoomX = 20
    //chartSettings.zoomPan.minZoomX = 1
    //chartSettings.zoomPan.minZoomY = 1
    //chartSettings.zoomPan.maxZoomY = 1

    let chartPointsCircleLayer = ChartPointsViewsLayer(xAxis: xAxisLayer.axis, yAxis: yAxisLayer.axis, chartPoints: chartPoints, viewGenerator: circleViewGenerator, conflictSolver: nil, displayDelay: 1.0, delayBetweenItems: 0.3, mode: .translate, keepOnFront: true, delayInit: true, clipViews: true)

    let chart = Chart(
        frame: chartFrame,
        innerFrame: innerFrame,
        settings: chartSettings,
        layers: [
            xAxisLayer,
            yAxisLayer,
            guidelinesLayer,
            chartPointsLineLayer,
            chartPointsCircleLayer
            ]
    )

    view.addSubview(chart.view)
    chart.zoom(scaleX: 2, scaleY: 1, centerX: 0, centerY: 0)

    chartPointsLineLayer.initScreenLines(chart)
    chartPointsCircleLayer.initViews(chart)

    chart.delegate = self
    self.chart = chart

It's that what you mean?

demo is below :

1

you can see in the demo gif,when first into view, the points's position is wrong,but when I pan on the chart view ,their positions back to right!

what should I do?thanks :)

hopy11 commented 6 years ago

update :

when I change code to below , It's seem like to work:

chart.zoom(scaleX: 2, scaleY: 1, centerX: 0, centerY: 0)
chartPointsLineLayer.initScreenLines(chart)

chartPointsCircleLayer.initViews(chart)
chartPointsCircleLayer.zoom(2, y: 1, centerX: 0, centerY: 0)

chart.delegate = self
self.chart = chart

I insert code chartPointsCircleLayer.zoom() after chartPointsCircleLayer.initViews(chart)

hopy11 commented 6 years ago

But I have another question : How can I hide the guidelinesLayer in chart programmatically???

I can't find method like layer.isHide() or chart.hideLayer() in SwiftCharts

I read carefully from your example code in : MultipleAxesInteractiveExample.swift

but it's too complicated to me,I try according it to modify my code,but it's not successed ;( I think it's must have some easy way to do that!

I just want hide some layer in chart programmatically.

Is there any easy way to make it works? thanks a lot ;)

If I need to make new issue to ask it , please let me know. :)

ivnsch commented 6 years ago

No worries. Most of SwiftCharts is immutable, so to hide layers you have to recreate the chart.

You'd have something like createChart(hasGuidelines: Bool) and depending on the parameter add or not add the guidelines.

hopy11 commented 6 years ago

ok! I will try it ,thanks