问题描述
我正在开发一个带有核心图表的iPhone应用程序。在一些教程的帮助下,我设法通过单点触摸和拖动来完成。如何通过多次触摸和拖动来实现?有人请帮帮我吗?
I'm developing an iPhone application with core-plot chart. With the help of some tutorials, i managed to do it with single touch and drag. How can I make it with multiple touch and drag? Anybody please help me?
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
EskPlotTheme *defaultTheme = [[EskPlotTheme alloc] init];
linePlot = [[EskLinePlot alloc] init];
linePlot.delegate = self;
[linePlot renderInLayer:lineHostingView withTheme:defaultTheme];
[defaultTheme release];
}
EskLinePlot.m
- (id)init
{
self = [super init];
if (self)
{
// setting up the sample data here.
sampleData = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:6000],
[NSNumber numberWithInt:3000],
[NSNumber numberWithInt:2000],
[NSNumber numberWithInt:5000],
[NSNumber numberWithInt:7000],
[NSNumber numberWithInt:8500],
[NSNumber numberWithInt:6500], nil];
}
return self;
}
- (void)renderInLayer:(CPTGraphHostingView *)layerHostingView withTheme:(CPTTheme *)theme
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
CGRect bounds = layerHostingView.bounds;
// Create the graph and assign the hosting view.
graph = [[CPTXYGraph alloc] initWithFrame:bounds];
layerHostingView.hostedGraph = graph;
[graph applyTheme:theme];
graph.plotAreaFrame.masksToBorder = NO;
// chang the chart layer orders so the axis line is on top of the bar in the chart.
NSArray *chartLayers = [[NSArray alloc] initWithObjects:[NSNumber numberWithInt:CPTGraphLayerTypePlots],
[NSNumber numberWithInt:CPTGraphLayerTypeMajorGridLines],
[NSNumber numberWithInt:CPTGraphLayerTypeMinorGridLines],
[NSNumber numberWithInt:CPTGraphLayerTypeAxisLines],
[NSNumber numberWithInt:CPTGraphLayerTypeAxisLabels],
[NSNumber numberWithInt:CPTGraphLayerTypeAxisTitles],
nil];
graph.topDownLayerOrder = chartLayers;
[chartLayers release];
// Add plot space for horizontal charts
graph.paddingLeft = 60.0;
graph.paddingTop = 70.0;
graph.paddingRight = 20.0;
graph.paddingBottom = 20.0;
// Setup plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
plotSpace.delegate = self;
int sampleCount = [sampleData count]-1;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(sampleCount)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(10000)];
// Setup grid line style
CPTMutableLineStyle *majorXGridLineStyle = [CPTMutableLineStyle lineStyle];
majorXGridLineStyle.lineWidth = 1.0f;
majorXGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.25f];
CPTMutableTextStyle *whiteTextStyle = [[[CPTMutableTextStyle alloc] init] autorelease];
whiteTextStyle.color = [CPTColor whiteColor];
// Setup x-Axis.
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
x.majorGridLineStyle = majorXGridLineStyle;
x.labelTextStyle = whiteTextStyle;
x.majorIntervalLength = CPTDecimalFromString(@"1");
x.minorTicksPerInterval = 1;
NSArray *exclusionRanges = [NSArray arrayWithObjects:[CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(0) length:CPTDecimalFromInt(0)], nil];
x.labelExclusionRanges = exclusionRanges;
// Setup y-Axis.
CPTMutableLineStyle *majorYGridLineStyle = [CPTMutableLineStyle lineStyle];
majorYGridLineStyle.lineWidth = 1.0f;
majorYGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.25];
CPTMutableLineStyle *minorYGridLineStyle = [CPTMutableLineStyle lineStyle];
minorYGridLineStyle.lineWidth = 1.0f;
minorYGridLineStyle.lineColor = [[CPTColor blackColor] colorWithAlphaComponent:0.1];
CPTXYAxis *y = axisSet.yAxis;
y.majorGridLineStyle = majorYGridLineStyle;
y.minorGridLineStyle = minorYGridLineStyle;
y.labelTextStyle = whiteTextStyle;
y.majorIntervalLength = CPTDecimalFromString(@"1000");
y.minorTicksPerInterval = 1;
y.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0");
NSArray *yExlusionRanges = [NSArray arrayWithObjects:
[CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat(0.0)],
nil];
y.labelExclusionRanges = yExlusionRanges;
// Create a high plot area
CPTScatterPlot *highPlot = [[[CPTScatterPlot alloc] init] autorelease];
highPlot.identifier = kHighPlot;
CPTMutableLineStyle *highLineStyle = [[highPlot.dataLineStyle mutableCopy] autorelease];
highLineStyle.lineWidth = 2.f;
highLineStyle.miterLimit = 1.0f;
highLineStyle.lineColor = [CPTColor whiteColor];
highPlot.dataLineStyle = highLineStyle;
highPlot.dataSource = self;
CPTColor *areaColor1 = [[CPTColor whiteColor] colorWithAlphaComponent:0.8f];
CPTGradient *areaGradient1 = [CPTGradient gradientWithBeginningColor:areaColor1 endingColor:[[CPTColor whiteColor] colorWithAlphaComponent:0.2f]];
areaGradient1.angle = -90.0f;
CPTFill *areaGradientFill = [CPTFill fillWithGradient:areaGradient1];
highPlot.areaFill = areaGradientFill;
highPlot.areaBaseValue = [[NSDecimalNumber zero] decimalValue];
[graph addPlot:highPlot];
// Create the Savings Marker Plot
selectedCoordination = 2;
touchPlot = [[[CPTScatterPlot alloc] initWithFrame:CGRectNull] autorelease];
touchPlot.identifier = kLinePlot;
touchPlot.dataSource = self;
touchPlot.delegate = self;
[self hideTouchPlotColor];
[graph addPlot:touchPlot];
[pool drain];
}
- (void)hideTouchPlotColor
{
CPTColor *touchPlotColor = [CPTColor clearColor];
CPTMutableLineStyle *savingsPlotLineStyle = [CPTMutableLineStyle lineStyle];
savingsPlotLineStyle.lineColor = touchPlotColor;
CPTPlotSymbol *touchPlotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
touchPlotSymbol.fill = [CPTFill fillWithColor:touchPlotColor];
touchPlotSymbol.lineStyle = savingsPlotLineStyle;
touchPlotSymbol.size = CGSizeMake(12.0f, 12.0f);
CPTMutableLineStyle *touchLineStyle = [CPTMutableLineStyle lineStyle];
touchLineStyle.lineColor = [CPTColor clearColor];
touchLineStyle.lineWidth = 1.0f;
CPTMutableLineStyle *symbolLineStyle = [CPTMutableLineStyle lineStyle];
symbolLineStyle.lineColor = [CPTColor clearColor];
CPTPlotSymbol *plotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
plotSymbol.fill = [CPTFill fillWithColor:[CPTColor clearColor]];
plotSymbol.lineStyle = symbolLineStyle;
plotSymbol.size = CGSizeMake(10.0, 10.0);
touchPlot.plotSymbol = plotSymbol;
touchPlot.dataLineStyle = touchLineStyle;
}
// Assign different color to the touchable line symbol.
- (void)showTouchPlotColor
{
CPTColor *touchPlotColor = [CPTColor orangeColor];
CPTMutableLineStyle *savingsPlotLineStyle = [CPTMutableLineStyle lineStyle];
savingsPlotLineStyle.lineColor = touchPlotColor;
CPTPlotSymbol *touchPlotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
touchPlotSymbol.fill = [CPTFill fillWithColor:touchPlotColor];
touchPlotSymbol.lineStyle = savingsPlotLineStyle;
touchPlotSymbol.size = CGSizeMake(12.0f, 12.0f);
CPTMutableLineStyle *touchLineStyle = [CPTMutableLineStyle lineStyle];
touchLineStyle.lineColor = [CPTColor orangeColor];
touchLineStyle.lineWidth = 1.0f;
CPTMutableLineStyle *symbolLineStyle = [CPTMutableLineStyle lineStyle];
symbolLineStyle.lineColor = [CPTColor blackColor];
CPTPlotSymbol *plotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
plotSymbol.fill = [CPTFill fillWithColor:[CPTColor orangeColor]];
plotSymbol.lineStyle = symbolLineStyle;
plotSymbol.size = CGSizeMake(10.0, 10.0);
touchPlot.plotSymbol = plotSymbol;
touchPlot.dataLineStyle = touchLineStyle;
}
// This method is call when user touch & drag on the plot space.
- (BOOL)plotSpace:(CPTPlotSpace *)space shouldHandlePointingDeviceDraggedEvent:(id)event atPoint:(CGPoint)point
{
// Convert the touch point to plot area frame location
CGPoint pointInPlotArea = [graph convertPoint:point toLayer:graph.plotAreaFrame];
NSDecimal newPoint[2];
[graph.defaultPlotSpace plotPoint:newPoint forPlotAreaViewPoint:pointInPlotArea];
NSDecimalRound(&newPoint[0], &newPoint[0], 0, NSRoundPlain);
int x = [[NSDecimalNumber decimalNumberWithDecimal:newPoint[0]] intValue];
if (x < 0)
{
x = 0;
}
else if (x > [sampleData count])
{
x = [sampleData count];
}
selectedCoordination = x;
if ([delegate respondsToSelector:@selector(linePlot:indexLocation:)])
[delegate linePlot:self indexLocation:x];
[touchPlot reloadData];
return YES;
}
- (BOOL)plotSpace:(CPTPlotSpace *)space shouldHandlePointingDeviceDownEvent:(id)event
atPoint:(CGPoint)point
{
[self showTouchPlotColor];
return YES;
}
- (BOOL)plotSpace:(CPTPlotSpace *)space shouldHandlePointingDeviceUpEvent:(id)event atPoint:(CGPoint)point
{
[self hideTouchPlotColor];
touchPlotSelected = NO;
return YES;
}
#pragma mark -
#pragma mark Scatter plot delegate methods
- (void)scatterPlot:(CPTScatterPlot *)plot plotSymbolWasSelectedAtRecordIndex:(NSUInteger)index
{
if ([(NSString *)plot.identifier isEqualToString:kLinePlot])
{
touchPlotSelected = YES;
[self applyHighLightPlotColor:plot];
if ([delegate respondsToSelector:@selector(linePlot:indexLocation:)])
[delegate linePlot:self indexLocation:index];
}
}
#pragma mark -
#pragma mark Plot Data Source Methods
- (NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
if ([(NSString *)plot.identifier isEqualToString:kLinePlot])
{
return kNumberOfMarkerPlotSymbols;
}
else {
return [sampleData count];
}
}
- (NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSNumber *num = nil;
if ( [(NSString *)plot.identifier isEqualToString:kHighPlot] )
{
if ( fieldEnum == CPTScatterPlotFieldY )
{
num = [sampleData objectAtIndex:index];
}
else if (fieldEnum == CPTScatterPlotFieldX)
{
num = [NSNumber numberWithInt:index];
}
}
else if ([(NSString *)plot.identifier isEqualToString:kLinePlot])
{
if ( fieldEnum == CPTScatterPlotFieldY )
{
switch (index) {
case 0:
num = [NSNumber numberWithInt:-1000];
break;
case 2:
num = [NSNumber numberWithInt:12700];
break;
default:
num = [sampleData objectAtIndex:selectedCoordination];
break;
}
}
else if (fieldEnum == CPTScatterPlotFieldX)
{
num = [NSNumber numberWithInt:selectedCoordination];
}
}
return num;
}
推荐答案
我遇到了同样的问题最近,找不到任何解决方案。经过一段时间的研究和编码后,我找到了一些解决方案,想要分享一个,非常简单,所以它可以帮助你了解如何处理这个问题。
I came across the same problem recently and couldn't find any solution. After some time researching and coding I found some solutions and want to share one, quite easy one, so it may help you get an idea how to approach this.
我有创建透明的UIView,我把它放在CPTGraphHostingView之上。
此视图正在处理所需的触摸事件。
我们将它命名为TestView
I have created transparent UIView, which I've put on top of CPTGraphHostingView. This view was handling needed touch events.Let's name it TestView
TestView.h文件看起来像
TestView.h file looks like
@protocol TestViewDelegate <NSObject>
- (void)myTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)myTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)myTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
@end
@interface TestView : UIView
@property (nonatomic, weak) id <TestViewDelegate>delegate;
@end
TestView.m
TestView.m
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.delegate myTouchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
[self.delegate myTouchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[self.delegate myTouchesEnded:touches withEvent:event];
}
TestView委托,在我的案例中,viewController,包括corePlot主机视图,将实现那些方法,并看到下面的代码示例
TestView delegate, in my case viewController, which includes corePlot hosting view, will implement those methods and see the sample of the code below
- (void)myTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
if (touches.count == 1) {
UITouch *touch = (UITouch *)[[touches allObjects] objectAtIndex:0];
CGPoint point = [touch locationInView:nil];
[self plotSpace:self.plotSpace shouldHandlePointingDeviceDraggedEvent:event atPoint:point];
}
if (touches.count == 2) {
UITouch *touch = (UITouch *)[[touches allObjects] objectAtIndex:1];
CGPoint point = [touch locationInView:nil];
[self plotSpace:self.plotSpace shouldHandlePointingDeviceDraggedEvent:event atPoint:point];
}
}
viewController中的CPTPlotSpace委托方法看起来像
CPTPlotSpace delegate method in viewController will look like
- (BOOL)plotSpace:(CPTPlotSpace *)space shouldHandlePointingDeviceDraggedEvent:(id)event atPoint:(CGPoint)point{
NSSet *allTouches = [event allTouches];
if ([allTouches count] >0 ) {
UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];
if (touch1){
CGPoint pointInPlotArea = [self.graph convertPoint:[touch1 locationInView:self.view] toLayer:self.graph.plotAreaFrame];
// padding
pointInPlotArea.x -=10;
NSDecimal newPoint[2];
[self.graph.defaultPlotSpace plotPoint:newPoint forPlotAreaViewPoint:pointInPlotArea];
NSDecimalRound(&newPoint[0], &newPoint[0], 0, NSRoundPlain);
int x = [[NSDecimalNumber decimalNumberWithDecimal:newPoint[0]] intValue];
x--;
if (x <= 0)
x = 0;
else if (x >= [self.currentDatapoints count])
x = [self.currentDatapoints count] - 1;
selectedCoordination = x;
self.label.text = [NSString stringWithFormat:@"%@", [self.currentDatapoints objectAtIndex:x]];
self.differenceLabel.text = @"";
[touchPlot reloadData];
}
if ([allTouches count] > 1){
secondTouchPlot.hidden = NO;
UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1];
if (touch2) {
CGPoint pointInPlotArea = [self.graph convertPoint:[touch2 locationInView:self.view] toLayer:self.graph.plotAreaFrame];
pointInPlotArea.x -= 10;
NSDecimal newPoint[2];
[self.graph.defaultPlotSpace plotPoint:newPoint forPlotAreaViewPoint:pointInPlotArea];
NSDecimalRound(&newPoint[0], &newPoint[0], 0, NSRoundPlain);
int x = [[NSDecimalNumber decimalNumberWithDecimal:newPoint[0]] intValue];
x--;
if (x <= 0)
x = 0;
else if (x >= [self.currentDatapoints count])
x = [self.currentDatapoints count] - 1;
selectedCoordination2 = x;
self.secondLabel.text = [NSString stringWithFormat:@"%@", [self.currentDatapoints objectAtIndex:x]];
[secondTouchPlot reloadData];
float first = [self.label.text floatValue];
float second = [[self.currentDatapoints objectAtIndex:x] floatValue];
self.differenceLabel.textColor = (first - second) > 0 ? [UIColor greenColor] : [UIColor redColor];
self.differenceLabel.text = [NSString stringWithFormat:@"%f", first - second];
}
}
}
return YES;
}
这就是结果......
And that's the result...
这不是优化代码,正如我上面提到的,如何处理这个问题只是这个想法。
This is not optimized code, it's just the idea, as I mentioned above, how to approach this problem.
希望它有所帮助......
Hope it helps...
这篇关于iPhone多点触控互动到CorePlot的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!