she*_*ebi 11 iphone xcode objective-c core-plot
我正在开发一个带有核心图表的iPhone应用程序.在一些教程的帮助下,我设法通过单点触摸和拖动来完成.如何通过多次触摸和拖动来实现?有人请帮帮我吗?

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];
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
我很可能最终会通过多个答复来回答这个问题,但我现在将从以下开始:
您可能会认为 Apple 会在其手势识别对象中提供 API 来辅助多种手指跟踪算法等,但到目前为止还没有。在我开发的游戏中,我还需要有多个手指,最多 4 个或更多,所有手指都在屏幕上并同时移动/跟踪。我发现我必须实现自己的手指跟踪/向下/向上算法来完成除了简单的单指滑动和捏合缩放操作之外的其他操作。让我们深入研究一下:
我相信您的 EskLinePlot.m 文件“应该处理按下事件”,您将需要实现“按下了多少根手指”的增量器。这样,如果您在另一根手指已经按下时再按下另一根手指,您就可以计数。类似地,您将需要在“应该处理事件”例程中实现一个减量器。在这一切的中间,还需要一个(尽管)小型触摸数据库(可能是 NSMutableArray)。该数据库将用于将拖动事件与手指相关联。那么这项工作最终如何进行呢?在发生按下事件时,您将: 1) 在触摸数据库中创建一条新记录(数组编号可以作为您的唯一标识符 2) 将新触摸的当前位置记录到您在步骤 1 中创建的(新)触摸记录中,作为最新(或数组位置 0)位置。触摸数据库中的每个触摸项目都应具有手指最后所处位置的 4 到 10 个之间的历史记录(我倾向于将位置记录为 0 = 最新到 3 或 9 作为最旧的位置)。3) 不要简单地打开您创建的单条(图形)线,而是在发生按下事件时添加一条新的(图形)线(执行与当前屏幕手指位置与图形数字位置相同的关联操作)
对于“应该处理拖动事件”: 1)查看在拖动事件中中继的手指的屏幕位置,并将其与内部保存的触摸数据库中的触摸相关联(触摸数据库中的哪个触摸最接近于触摸)此时提出)。2) 将相关触地的所有先前位置点移动 1。0 变为 1,1 变为 2,等等...遍历所有,当然删除最后一个。3) 将新点添加到关联触摸的先前点列表中作为最新点。4) 适当移动与该手指相关的(图形)线
对于向上事件:1) 将触摸数据库中手指呈现的位置关联起来。2) 从触摸数据库中删除相关触摸。3) 从屏幕上删除您分配给该手指的(图形)线
我希望这有帮助,我应该能够在某处找到一些示例代码,但我目前不在我的开发机器前。
| 归档时间: |
|
| 查看次数: |
2468 次 |
| 最近记录: |