core plot x axis labels vertical - xcode

I have a very crowded xy graph and I'm trying to display the x-axis labels vertically instead of the default horizontal. I can't find documentation on how to do this. Can anyone explain how to do this or point me to the right documentation? I have adjusted the x.labelrotation but it does rotate the x axis label
thanks.
#pragma mark - Chart behavior
-(void)initPlotThree {
[self configureHostThree];
[self configureGraphThree];
[self configurePlotsThree];
[self configureAxesThree];
}
-(void)configureHostThree {
self.hostView = [(CPTGraphHostingView *) [CPTGraphHostingView alloc] initWithFrame:self.view.bounds];
self.hostView.allowPinchScaling = YES;
[self.myViewThree addSubview:self.hostView];
CPTGraphHostingView *BarGraphView = [[CPTGraphHostingView alloc] init];
self.hostView.frame = CGRectMake(self.myViewThree.bounds.origin.x, self.myViewThree.bounds.origin.y, self.myViewThree.bounds.size.width, self.myViewThree.bounds.size.height);
[self.hostView addSubview:BarGraphView];
}
-(void)configureGraphThree {
// 1 - Create the graph
CPTGraph *graph = [[CPTXYGraph alloc] initWithFrame:self.hostView.bounds];
// [graph applyTheme:[CPTTheme themeNamed:kCPTSlateTheme]];
[graph applyTheme:[CPTTheme themeNamed:kCPTPlainWhiteTheme]];
self.hostView.hostedGraph = graph;
// 2 - Set graph title
NSString *title = #"Tremor";
graph.title = title;
// 3 - Create and set text style
CPTMutableTextStyle *titleStyle = [CPTMutableTextStyle textStyle];
titleStyle.color = [CPTColor blackColor];
titleStyle.fontName = #"Helvetica-Bold";
titleStyle.fontSize = 12.0f;
graph.titleTextStyle = titleStyle;
graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop;
graph.titleDisplacement = CGPointMake(0.0f, 17.0f);
// 4 - Set padding for plot area
[graph.plotAreaFrame setPaddingLeft:1.0f];
[graph.plotAreaFrame setPaddingBottom:1.0f];
// 5 - Enable user interactions for plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
plotSpace.allowsUserInteraction = YES;
}
-(void)configurePlotsThree {
// 1 - Get graph and plot space
CPTGraph *graph = self.hostView.hostedGraph;
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;
// 2 - Create the plots
CPTScatterPlot *tremorPlot = [[CPTScatterPlot alloc] init];
tremorPlot.dataSource = self;
tremorPlot.identifier = tremorSCORE;
CPTColor *tremorColor = [CPTColor blueColor];
[graph addPlot:tremorPlot toPlotSpace:plotSpace];
// 3 - Set up plot space
[plotSpace scaleToFitPlots:[NSArray arrayWithObjects:tremorPlot, nil]];
CPTMutablePlotRange *xRange = [plotSpace.xRange mutableCopy];
[xRange expandRangeByFactor:CPTDecimalFromCGFloat(1.1f)];
plotSpace.xRange = xRange;
CPTMutablePlotRange *yRange = [plotSpace.yRange mutableCopy];
[yRange expandRangeByFactor:CPTDecimalFromCGFloat(1.2f)];
plotSpace.yRange = yRange;
// 4 - Create styles and symbols
CPTMutableLineStyle *tremorLineStyle = [tremorPlot.dataLineStyle mutableCopy];
tremorLineStyle.lineWidth = 2.0;
tremorLineStyle.lineColor = tremorColor;
tremorPlot.dataLineStyle = tremorLineStyle;
CPTMutableLineStyle *tremorSymbolLineStyle = [CPTMutableLineStyle lineStyle];
tremorSymbolLineStyle.lineColor = tremorColor;}
-(void)configureAxesThree {
// 1 - Create styles
CPTMutableTextStyle *axisTitleStyle = [CPTMutableTextStyle textStyle];
axisTitleStyle.color = [CPTColor blackColor];
axisTitleStyle.fontName = #"Helvetica-Bold";
axisTitleStyle.fontSize = 10.0f;
CPTMutableLineStyle *axisLineStyle = [CPTMutableLineStyle lineStyle];
axisLineStyle.lineWidth = .01f;
axisLineStyle.lineColor = [CPTColor blackColor];
CPTMutableTextStyle *axisTextStyle = [[CPTMutableTextStyle alloc] init];
axisTextStyle.color = [CPTColor blackColor];
axisTextStyle.fontName = #"Helvetica-Bold";
axisTextStyle.fontSize = 9.0f;
CPTMutableLineStyle *tickLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineColor = [CPTColor blackColor];
tickLineStyle.lineWidth = 1.0f;
CPTMutableLineStyle *gridLineStyle = [CPTMutableLineStyle lineStyle];
tickLineStyle.lineColor = [CPTColor blackColor];
tickLineStyle.lineWidth = 1.0f;
// 2 - Get axis set
CPTXYAxisSet *axisSet = (CPTXYAxisSet *) self.hostView.hostedGraph.axisSet;
// 3 - Configure x-axis
CPTAxis *x = axisSet.xAxis;
x.title = #"";
x.titleTextStyle = axisTitleStyle;
x.titleOffset = 20.0f;
x.axisLineStyle = axisLineStyle;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.labelTextStyle = axisTextStyle;
x.majorTickLineStyle = axisLineStyle;
x.majorTickLength = 4.0f;
x.tickDirection = CPTSignNegative;
x.labelRotation = .6;
x.labelOffset = 15;
CGFloat dateCount = [self.dates count];
NSMutableSet *xLabels = [NSMutableSet setWithCapacity:dateCount];
NSMutableSet *xLocations = [NSMutableSet setWithCapacity:dateCount];
NSInteger i = 0;
for (NSString *date in self.dates) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:date textStyle:x.labelTextStyle];
CGFloat location = i++;
label.tickLocation = CPTDecimalFromCGFloat(location);
label.offset = x.majorTickLength;
if (label) {
[xLabels addObject:label];
[xLocations addObject:[NSNumber numberWithFloat:location]];
}
}
x.axisLabels = xLabels;
x.majorTickLocations = xLocations;
// CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
axisSet.xAxis.axisConstraints = [CPTConstraints constraintWithLowerOffset:15.0]; // 8-22
// 4 - Configure y-axis
CPTAxis *y = axisSet.yAxis;
y.title = #"";
y.titleTextStyle = axisTitleStyle;
y.titleOffset = -40.0f;
y.axisLineStyle = axisLineStyle;
y.majorGridLineStyle = nil;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
y.labelTextStyle = nil;
y.labelOffset = 16.0f;
y.majorTickLineStyle = nil;
y.majorTickLength = 4.0f;
y.minorTickLength = 1.0f;
y.tickDirection = CPTSignPositive;
NSInteger majorIncrement = 2;
NSInteger minorIncrement = 1;
CGFloat yMax = 700.0f; // should determine dynamically based on max price
NSMutableSet *yLabels = [NSMutableSet set];
NSMutableSet *yMajorLocations = [NSMutableSet set];
NSMutableSet *yMinorLocations = [NSMutableSet set];
for (NSInteger j = minorIncrement; j <= yMax; j += minorIncrement) {
NSUInteger mod = j % majorIncrement;
if (mod == 0) {
CPTAxisLabel *label = [[CPTAxisLabel alloc] initWithText:[NSString stringWithFormat:#"%li", (long)j] textStyle:y.labelTextStyle];
NSDecimal location = CPTDecimalFromInteger(j);
label.tickLocation = location;
label.offset = -y.majorTickLength - y.labelOffset;
if (label) {
[yLabels addObject:label];
}
[yMajorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:location]];
[yMajorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:location]];
} else {
[yMinorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:CPTDecimalFromInteger(j)]];
[yMinorLocations addObject:[NSDecimalNumber decimalNumberWithDecimal:CPTDecimalFromInteger(j)]];
}
}
y.axisLabels = yLabels;
y.majorTickLocations = yMajorLocations;
y.minorTickLocations = yMinorLocations;
}

Set the labelRotation on the x-axis to rotate the labels when using one of the automatic labelling policies. When creating custom labels, you need to set the rotation on each label directly.

Related

core-plot x-axis label not visible - bounding rects?

Using the vertical bar chart sample as a start, I created a chart whose y values are 0..1, x values 1..n but the x label index supplied for CPTBarPlotFieldBarLocation cell of my data source doesn't appear; I don't use y-axis labels.
I suspect I'm clipping them. Is there a way, like in the old IB, to draw the various graph region's bounding rect?
The x-axis plot labels are a non-numeric string as in the example. What did I break? Here's my setup
//
// InfoBarView.m
#import "InfoBarView.h"
// Item index to color mapping for legend symbols not item related
static NSUInteger fldMapping[] = { 5, 6, 7, 0 };
static const BOOL kUseHorizontalBars = NO;
static NSArray <__kindof NSString *> const* kTargets = nil;
static NSArray <__kindof NSString *> const* kGetters = nil;
#interface BarChart()
#property (nonatomic, readwrite, strong, nullable) CPTPlotSpaceAnnotation * symbolTextAnnotation;
#end
#implementation BarChart
#synthesize symbolTextAnnotation;
#synthesize plotData;
+ (void)initialize
{
kTargets = [#[ #"grpA" , #"grpB", #"grpC", #"grpD" ] retain];
kGetters = [#[ #"fldA", #"fldB", #"fldC", #"fldD" ] retain];
}
- (void)awakeFromNib
{
// Get our orig scaling
[super awakeFromNib];
}
- (void)killGraph
{
if ( self.graphs.count )
{
CPTGraph * graph = self.defaultGraph;
CPTPlotSpaceAnnotation *annotation = self.symbolTextAnnotation;
if ( annotation )
{
[graph.plotAreaFrame.plotArea removeAnnotation:annotation];
self.symbolTextAnnotation = nil;
}
}
[super killGraph];
}
- (void)generateData
{
InfoBarView * barView = (id)[[self defaultLayerHostingView] superview];
InfoController * controller = barView.controller;
NSUInteger rndx = controller.barDataRanking;
NSArray * rankings = #[ #"Rank", #"Runs" ];
GroupItem * group = controller.group;
CPTGraph * graph = [self defaultGraph];
CPTPlotSpaceAnnotation * annotation = self.symbolTextAnnotation;
if ( annotation )
{
if (graph)
{
[graph.plotAreaFrame.plotArea removeAnnotation:annotation];
self.symbolTextAnnotation = nil;
}
}
// Update X title with new controller index
if (graph)
{
graph.title = [NSString stringWithFormat:#"Past Performances by %#", rankings[rndx]];
}
// Figure out our rank selector
NSString * rankSelectorName = [NSString stringWithFormat:#"%#%#Compare:",
kTargets[controller.barDataIndex],
rankings[rndx]];
SEL dataRanking = NSSelectorFromString(rankSelectorName);
self.plotData = (id)[group.items sortedArrayUsingSelector:dataRanking];
}
- (void)renderInGraphHostingView:(nonnull CPTGraphHostingView *)hostingView
withTheme:(nullable CPTTheme *)theme
animated:(BOOL)animated
{
#if TARGET_OS_SIMULATOR || TARGET_OS_IPHONE
CGRect bounds = hostingView.bounds;
#else
CGRect bounds = NSRectToCGRect(hostingView.bounds);
#endif
InfoController * controller = ((InfoBarView *)hostingView.superview).controller;
CPTGraph * graph = [[[CPTXYGraph alloc] initWithFrame:bounds] autorelease];
NSString * titles = #"fldA fldB fldC fldD";
GroupItem * group = controller.group;
CPTBarPlot * barPlot;
// Initially we default by rank
self.title = #"Past Performances by Rank";
[self addGraph:graph toHostingView:hostingView];
graph.plotAreaFrame.masksToBorder = NO;
if ( kUseHorizontalBars )
{
graph.plotAreaFrame.paddingBottom += self.titleSize;
}
else
{
graph.plotAreaFrame.paddingLeft += self.titleSize;
}
// Add plot space for bar charts
CPTXYPlotSpace * barPlotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
[barPlotSpace setScaleType:CPTScaleTypeCategory forCoordinate:CPTCoordinateX];
if ( kUseHorizontalBars )
{
barPlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:#(-10.0) length:#120.0];
barPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:#(-1.0) length:#11.0];
}
else
{
barPlotSpace.xRange = [CPTPlotRange plotRangeWithLocation:#(-0.5) length:#(group.itemCount)];
barPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:#(-0.05) length:#1.0];
}
barPlotSpace.allowsUserInteraction = YES;
[graph addPlotSpace:barPlotSpace];
barPlotSpace.delegate = self;
// Create grid line styles
CPTMutableLineStyle * majorGridLineStyle = [CPTMutableLineStyle lineStyle];
majorGridLineStyle.lineWidth = 1.0;
majorGridLineStyle.lineColor = [[CPTColor grayColor] colorWithAlphaComponent:0.75];
CPTMutableLineStyle * minorGridLineStyle = [CPTMutableLineStyle lineStyle];
minorGridLineStyle.lineWidth = 1.0;
minorGridLineStyle.lineColor = [[CPTColor whiteColor] colorWithAlphaComponent:0.25];
// Create axes
CPTXYAxisSet * axisSet = (CPTXYAxisSet *)graph.axisSet;
CPTXYAxis * x = axisSet.xAxis;
{
x.majorIntervalLength = (kUseHorizontalBars ? #10.0 : #1.0);
x.minorTicksPerInterval = (kUseHorizontalBars ? 9 : 0);
x.orthogonalPosition = (kUseHorizontalBars ? #(-0.5) : #0.0);
x.majorGridLineStyle = majorGridLineStyle;
x.minorGridLineStyle = minorGridLineStyle;
x.axisLineStyle = nil;
x.majorTickLineStyle = nil;
x.minorTickLineStyle = nil;
x.labelOffset = self.titleSize * CPTFloat(2.5);
if ( kUseHorizontalBars )
{
x.visibleRange = [CPTPlotRange plotRangeWithLocation:#0.0 length:#10.0];
x.gridLinesRange = [CPTPlotRange plotRangeWithLocation:#(-0.5) length:#(group.itemCount)];
}
else
{
x.visibleRange = [CPTPlotRange plotRangeWithLocation:#(-0.5) length:#(group.itemCount)];
x.gridLinesRange = [CPTPlotRange plotRangeWithLocation:#0.0 length:#(1.0)];
}
x.plotSpace = barPlotSpace;
}
CPTXYAxis * y = axisSet.yAxis;
{
y.majorIntervalLength = (kUseHorizontalBars ? #1.0 : #10.0);
y.minorTicksPerInterval = (kUseHorizontalBars ? 0 : 9);
y.orthogonalPosition = (kUseHorizontalBars ? #0.0 : #(-0.5) );
y.preferredNumberOfMajorTicks = 8;
y.majorGridLineStyle = majorGridLineStyle;
y.minorGridLineStyle = minorGridLineStyle;
y.axisLineStyle = nil;
y.majorTickLineStyle = nil;
y.minorTickLineStyle = nil;
y.labelOffset = self.titleSize * CPTFloat(0.175);
y.titleLocation = (kUseHorizontalBars ? #55.0 : #(group.itemCount-1));
if ( kUseHorizontalBars )
{
y.visibleRange = [CPTPlotRange plotRangeWithLocation:#(-0.5) length:#10.0];
y.gridLinesRange = [CPTPlotRange plotRangeWithLocation:#0.0 length:#100.0];
}
else
{
y.visibleRange = [CPTPlotRange plotRangeWithLocation:#(-0.5) length:#(group.itemCount)];
y.gridLinesRange = [CPTPlotRange plotRangeWithLocation:#(-0.5) length:#(group.itemCount)];
}
y.title = titles;
y.titleOffset = self.titleSize * CPTFloat(0.25);
[barPlotSpace addCategory:title[seg] forCoordinate:CPTCoordinateY];
y.plotSpace = barPlotSpace;
}
// Set axes
graph.axisSet.axes = #[x, y];
// Create a shared bar line style
CPTMutableLineStyle * barLineStyle = [[[CPTMutableLineStyle alloc] init] autorelease];
barLineStyle.lineWidth = 1.0;
barLineStyle.lineColor = [CPTColor whiteColor];
// Marshall Y axis into individual plot identifiers
NSArray * title = [titles componentsSeparatedByString:#" "];
CPTMutableTextStyle * blackTextStyle = [CPTMutableTextStyle textStyle];
blackTextStyle.color = [CPTColor blackColor];
// Create bar plot(s)
for (int seg=0; seg<title.count; seg++)
{
barPlot = [[[CPTBarPlot alloc] init] autorelease];
barPlot.lineStyle = barLineStyle;
barPlot.fill = [CPTFill fillWithColor:[CPTColor colorAtIndex:seg]];
barPlot.barBasesVary = YES;
barPlot.barCornerRadius = 4.0;
barPlot.barWidth = #0.5;
barPlot.barsAreHorizontal = kUseHorizontalBars;
barPlot.dataSource = self;
barPlot.delegate = self;
barPlot.identifier = [NSString stringWithFormat:#"%#,%d",title[seg],seg],
barPlot.labelTextStyle = blackTextStyle;
barPlot.labelOffset = 0.0;
[graph addPlot:barPlot toPlotSpace:barPlotSpace];
NSLog(#"render:%#", barPlot.identifier);
}
// Add X category per slot
for (Item * item in plotData)
{
[barPlotSpace addCategory:item.numb forCoordinate:CPTCoordinateX];
}
}
#pragma mark -
#pragma mark Plot Delegate
- (void)Plot:(nonnull CPTPlot *)plot dataLabelWasSelectedAtRecordIndex:(NSUInteger)index
{
// NSString * barID = (NSString *)[[(id)plot.identifier componentsSeparatedByString:#","] lastObject];
NSLog(#"Data label for '%#' was selected at record %d.", plot.identifier, (int)index);
}
- (CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index;
{
InfoBarView * barView = (id)[[self defaultLayerHostingView] superview];
InfoController * controller = barView.controller;
GroupItem * group = controller.group;
int sndx = index % group.itemCount;
Item * item = (Item *)[self.plotData objectAtIndex:sndx];
CPTMutableTextStyle * textStyle = [CPTMutableTextStyle textStyle];
textStyle.color = [CPTColor colorAtIndex:item.foreRGB];
textStyle.textAlignment = CPTTextAlignmentCenter;
textStyle.fontSize = 24;
plot.labelOffset = 0;
CPTMutableShadow * shadow = [CPTMutableShadow shadow];
shadow.shadowColor = [CPTColor blackColor];//colorAtIndex:item.backRGB];
shadow.shadowOffset = CGSizeMake(1,-1);
shadow.shadowBlurRadius = 2.0f;
plot.labelShadow = shadow;
CPTTextLayer * textLayer = [[CPTTextLayer alloc] initWithText:item.numb.squish style:textStyle];
return [textLayer autorelease];
}
- (void)barPlot:(CPTBarPlot *)plot barWasSelectedAtRecordIndex:(NSUInteger)index
{
CGFloat floor = [[self valueForPlot:plot field:CPTBarPlotFieldBarBase recordIndex:index] doubleValue];
CGFloat value = [[self valueForPlot:plot field:CPTBarPlotFieldBarTip recordIndex:index] doubleValue];
CGFloat runs = 0;
NSString * barID = (NSString *)[[(id)plot.identifier
componentsSeparatedByString:#","] lastObject];
InfoBarView * barView = (id)[[self defaultLayerHostingView] superview];
InfoController * controller = barView.controller;
GroupItem * group = controller.group;
int fndx = [barID intValue];
int sndx = index % group.itemCount;
Item * item = (Item *)[self.plotData objectAtIndex:sndx];
SEL dataItem = NSSelectorFromString(kTargets[controller.barDataIndex]);
DataItem * data = [item performSelector:dataItem];
runs = [[data fldD] doubleValue];
NSLog(#"BarSelected %# %# record:%lu. base:%.2f value:%.2f",
plot.identifier, data.name, index, floor, value);
CPTGraph * graph = [self defaultGraph];
CPTPlotSpaceAnnotation * annotation = self.symbolTextAnnotation;
if ( annotation )
{
[graph.plotAreaFrame.plotArea removeAnnotation:annotation];
self.symbolTextAnnotation = nil;
}
// Setup a style for the annotation
CPTMutableTextStyle * hitAnnotationTextStyle = [CPTMutableTextStyle textStyle];
hitAnnotationTextStyle.color = [CPTColor colorAtIndex:fldMapping[fndx]];
hitAnnotationTextStyle.fontSize = 16.0;
hitAnnotationTextStyle.fontName = #"Helvetica-Bold";
// Determine point of symbol in plot coordinates
NSNumber * x = #(index);
NSNumber * y = #(0.03 + (floor / runs));
CPTNumberArray * anchorPoint = (kUseHorizontalBars ? #[y, x] : #[x, y]);
// Add annotation
// First make a string for the y value
NSString * yString = [[NSNumberFormatter withFormat:#"#,###"] stringFromNumber:#(value)];
// Now add the annotation to the plot area
CPTPlotSpace * space = plot.plotSpace;
if ( space )
{
CPTTextLayer * textLayer = [[CPTTextLayer alloc] initWithText:yString style:hitAnnotationTextStyle];
annotation = [[CPTPlotSpaceAnnotation alloc] initWithPlotSpace:space anchorPlotPoint:anchorPoint];
annotation.contentLayer = [textLayer autorelease];
annotation.displacement = CGPointMake(0.0, 0.0);
self.symbolTextAnnotation = annotation;
[graph.plotAreaFrame.plotArea addAnnotation:[annotation autorelease]];
}
}
#pragma mark Plot DataSource
- (NSUInteger)numberOfRecordsForPlot:(nonnull CPTPlot *)plot
{
InfoBarView * barView = (id)[[self defaultLayerHostingView] superview];
InfoController * controller = barView.controller;
GroupItem * group = controller.group;
return group.itemCount;
}
- (nullable id)numberForPlot:(nonnull CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSString * barID = (NSString *)[[(id)plot.identifier componentsSeparatedByString:#","] lastObject];
InfoBarView * barView = (id)[[self defaultLayerHostingView] superview];
InfoController * controller = barView.controller;
GroupItem * group = controller.group;
int fndx = [barID intValue];
int sndx = index % group.itemCount;
Item * item = (Item *)[self.plotData objectAtIndex:sndx];
SEL dataItem = NSSelectorFromString(kTargets[controller.barDataIndex]);
NSString * getName = kGetters[fndx];
SEL getter = NSSelectorFromString(getName);
SEL fldD = #selector(fldD);
CGFloat runs, base=0, value=0;
DataItem * data;
id num=nil;
// First get which data data item we're after
data = [item performSelector:dataItem];
runs = [[data performSelector:fldD] floatValue];
// Now fetch its getter
switch ( fieldEnum )
{
case CPTBarPlotFieldBarLocation:
num = item.numb;
break;
case CPTBarPlotFieldBarTip:
// Build base for this tip
for (int seg=0; seg < fndx; seg++)
{
value += [[data performSelector:NSSelectorFromString(kGetters[seg])] floatValue];
}
// Add this 'tip' value unless it's the total
if (fndx == 3)
num = #(1.0f);
else
{
value += [[data performSelector:getter] floatValue];
num = #(value/runs);
}
break;
case CPTBarPlotFieldBarBase:
// Calc base by sum prior fields
for (int seg=0; seg < fndx; seg++)
{
base += [[data performSelector:NSSelectorFromString(kGetters[seg])] floatValue];
}
num = #(base/runs);
}
return num;
}
- (nullable id)valueForPlot:(nonnull CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSString * barID = (NSString *)[[(id)plot.identifier componentsSeparatedByString:#","] lastObject];
InfoBarView * barView = (id)[[self defaultLayerHostingView] superview];
InfoController * controller = barView.controller;
GroupItem * group = controller.group;
int fndx = [barID intValue];
int sndx = index % group.itemCount;
Item * item = (Item *)[self.plotData objectAtIndex:sndx];
SEL dataItem = NSSelectorFromString(kTargets[controller.barDataIndex]);
NSString * getName = kGetters[fndx];
SEL getter = NSSelectorFromString(getName);
SEL fldD = #selector(fldD);
CGFloat runs, value=0;
DataItem * data;
id num=nil;
// First get which data block we're after
data = [item performSelector:dataItem];
runs = [[data performSelector:fldD] floatValue];
// Now fetch its getter
switch ( fieldEnum )
{
case CPTBarPlotFieldBarLocation:
num = item.numb.squish;
break;
case CPTBarPlotFieldBarTip:
value = [[data performSelector:getter] floatValue];
num = #(value);
break;
case CPTBarPlotFieldBarBase:
// Calc base by sum prior fields
for (int seg=0; seg < fndx; seg++)
{
value += [[data performSelector:NSSelectorFromString(kGetters[seg])] floatValue];
}
num = #(value);
}
return num;
}
- (nullable NSString *)legendTitleForBarPlot:(nonnull CPTBarPlot *)plot recordIndex:(NSUInteger)index
{
NSString * barID = (NSString *)[[(id)plot.identifier componentsSeparatedByString:#","] lastObject];
int fndx = [barID intValue];
return kGetters[fndx];
}
#pragma mark Plot Legend Delegate
- (void)legend:(CPTLegend *)legend legendEntryForPlot:(CPTPlot *)plot wasSelectedAtIndex:(NSUInteger)index
{
NSLog(#"legend:%# index:%lu", plot.identifier, index);
}
#pragma mark Plot Space Delegate
#pragma mark Plot Space Delegate
- (CPTPlotRange *)plotSpace:(CPTPlotSpace *)space
willChangePlotRangeTo:(CPTPlotRange *)newRange
forCoordinate:(CPTCoordinate)coordinate
{
CGFloat newLocation = newRange.location.floatValue;
// CGFloat newLength = newRange.length.floatValue;
// Range change to +2 point on data boundary
if (CPTCoordinateX == coordinate)
{
if (newLocation < -0.5)
{
return [CPTPlotRange plotRangeWithLocation:#(-0.5) length:newRange.length];
}
else
if (newLocation > (0.3))
{
return [CPTPlotRange plotRangeWithLocation:#(0.3) length:newRange.length];
}
}
if (CPTCoordinateY == coordinate)
{
if (newLocation < (-0.1))
{
return [CPTPlotRange plotRangeWithLocation:#(-0.1) length:newRange.length];
}
else
if (newLocation > (0.1))
{
return [CPTPlotRange plotRangeWithLocation:#(0.1) length:newRange.length];
}
}
// CGRect chartBounds = self.defaultGraph.bounds;
// NSLog(#"old:%#", NSStringFromRect(chartBounds));
// NSLog(#"new:%# %#", (coordinate == CPTCoordinateX ? #"X" : #"Y"),[newRange description]);
return newRange;
}
#end
#implementation InfoBarView
#synthesize barChart;
#synthesize x_title;
- (void)awakeFromNib
{
// Get our orig scaling
[super awakeFromNib];
self.barChart = [[[BarChart alloc] init] autorelease];
}
- (void)drawRect:(NSRect)clip
{
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
NSImage * webImage = controller.group.track.webImage;
GroupItem * group = controller.group;
NSRect rect = [self frame];
// Save state so we can restore later
CGContextSaveGState(context);
// Draw track image as our view's background
if (webImage)
{
[webImage drawInRect:rect fromRect:[webImage alignmentRect]
operation:NSCompositeSourceOver fraction:0.25];
}
if (group && !barChart.graphs.count)
{
[barChart renderInView:self withTheme:nil animated:YES];
}
CGContextRestoreGState(context);
}
#end
If there were visible clues - drawn bounding rects, I think a lot of us could benefit from them (I miss those from IB circa v3).
The statement x.labelFormatter = nil; eliminates the automatic axis labels. If you supply a label formatter and label text style, the axis will create ticks and labels automatically based on the labeling policy.

IOS: How to split an UIImage into parts

In one of my application I need to split UIImage into multiple parts. The following was the code I am using to split. Here my problem is I am unable to load the image view by adding the image to UIImageView.
- (void)viewDidLoad
{
UIImage* image = [UIImage imageNamed:#"monalisa.png"];
NSMutableArray* splitImages = [self splitImageIntoRects:(__bridge CGImageRef)(image)];
printf("\n count; %d",[splitImages count]);
CALayer *layer = [splitImages objectAtIndex:5];
CGImageRef imgRef = (__bridge CGImageRef)(layer.contents);
UIImage *img = [[UIImage alloc] initWithCGImage:imgRef];
UIImageView* imageview = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
imageview.image = img;
imageview.backgroundColor = [UIColor redColor];
[self.view addSubview:imageview];
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (NSMutableArray*)splitImageIntoRects:(CGImageRef)anImage
{
CGSize imageSize = CGSizeMake(CGImageGetWidth(anImage), CGImageGetHeight(anImage));
NSMutableArray *splitLayers = [NSMutableArray array];
int kXSlices = 3;
int kYSlices = 3;
for(int x = 0;x < kXSlices;x++) {
for(int y = 0;y < kYSlices;y++) {
CGRect frame = CGRectMake((imageSize.width / kXSlices) * x,
(imageSize.height / kYSlices) * y,
(imageSize.width / kXSlices),
(imageSize.height / kYSlices));
CALayer *layer = [CALayer layer];
layer.frame = frame;
CGImageRef subimage = CGImageCreateWithImageInRect(anImage, frame);
layer.contents = (__bridge id)subimage;
[splitLayers addObject:layer];
}
}
return splitLayers;
}
And the output is like follows,
Try This:
- (void)viewDidLoad
{
[super viewDidLoad];
[self getSplitImagesFromImage:[UIImage imageNamed:#"Image1.png"] withRow:4 withColumn:4];
}
-(NSMutableArray *)getSplitImagesFromImage:(UIImage *)image withRow:(NSInteger)rows withColumn:(NSInteger)columns
{
NSMutableArray *aMutArrImages = [NSMutableArray array];
CGSize imageSize = image.size;
CGFloat xPos = 0.0, yPos = 0.0;
CGFloat width = imageSize.width/rows;
CGFloat height = imageSize.height/columns;
for (int aIntY = 0; aIntY < columns; aIntY++)
{
xPos = 0.0;
for (int aIntX = 0; aIntX < rows; aIntX++)
{
CGRect rect = CGRectMake(xPos, yPos, width, height);
CGImageRef cImage = CGImageCreateWithImageInRect([image CGImage], rect);
UIImage *aImgRef = [[UIImage alloc] initWithCGImage:cImage];
UIImageView *aImgView = [[UIImageView alloc] initWithFrame:CGRectMake(aIntX*width, aIntY*height, width, height)];
[aImgView setImage:aImgRef];
[aImgView.layer setBorderColor:[[UIColor blackColor] CGColor]];
[aImgView.layer setBorderWidth:1.0];
[self.view addSubview:aImgView];
[aMutArrImages addObject:aImgRef];
xPos += width;
}
yPos += height;
}
return aMutArrImages;
}
for more info see this and you can also download demo from here.
We can enhance more the Yasika Patel Answer. Below function will give you exact peice of image which fits to your view.
- (void)splitImage :(UIImage *)image withColums:(int)columns WithRows: (int)rows ViewToIntegrate : (UIView *)view
{
CGSize imageSize = _imgSplit.image.size;
CGFloat xPos = 0.0, yPos = 0.0;
CGFloat width = imageSize.width/rows;
CGFloat height = imageSize.height/columns;
for (int aIntY = 0; aIntY < columns; aIntY++)
{
xPos = 0.0;
for (int aIntX = 0; aIntX < rows; aIntX++)
{
CGRect rect = CGRectMake(xPos, yPos, width, height);
CGImageRef cImage = CGImageCreateWithImageInRect([ image CGImage], rect);
UIImage *aImgRef = [[UIImage alloc] initWithCGImage:cImage];
UIImageView *aImgView = [[UIImageView alloc] initWithFrame:CGRectMake(aIntX*(view.frame.size.width/rows), aIntY*( view.frame.size.height/columns), view.frame.size.width/rows, view.frame.size.height/columns)];
[aImgView setImage:aImgRef];
[aImgView.layer setBorderColor:[[UIColor blackColor] CGColor]];
[aImgView.layer setBorderWidth:0.5];
[view addSubview:aImgView];
xPos += width;
}
yPos += height;
}
[self.view addSubview:view];
}
This will give you the image in 9parts . here you just need to pass the row and colums.

CorePlot hosting view and CPTXYGraph frame issues

I'm trying to set up a simple pie chart in my OSX project, in Xcode 5, following the tutorial at :http://www.raywenderlich.com/13269/how-to-draw-graphs-with-core-plot-part-1.
The problem is that the graph doesn't show and both the CPTGraphHostingView and the CPTXYGraph have a height and width of 0.00.
Here is the code I use, after which I should be able to see the title for the graph in the view. The hostView is a reference to an NSView in the xib file.
-(void)configureHost {
self.graphHostingView = [(CPTGraphHostingView *)[CPTGraphHostingView alloc] initWithFrame:CGRectMake(0, 0, 1103, 532)];
NSLog(#"%f", self.graphHostingView.frame.size.width);
[hostView addSubview:self.graphHostingView];
}
-(void)configureGraph {
NSRect parentRect = CGRectMake(0, 0, 1103, 532);
//create graph
CPTGraph *graph = [[CPTXYGraph alloc] init];
[graph setFrame:parentRect];
NSLog(#"%f", graph.frame.size.width);
self.graphHostingView.hostedGraph = graph;
graph.paddingBottom = 0.0f;
graph.paddingLeft = 0.0f;
graph.paddingTop = 0.0f;
graph.paddingRight = 0.0f;
graph.axisSet = nil;
//text in graph
CPTMutableTextStyle *textStlye = [CPTMutableTextStyle textStyle];
textStlye.color = [CPTColor grayColor];
textStlye.fontName = #"Helvetica-Bold";
textStlye.fontSize = 16.0f;
//graph title
graph.title = #"Title";
graph.titleTextStyle = textStlye;
graph.titlePlotAreaFrameAnchor = CPTRectAnchorTop;
graph.titleDisplacement = CGPointMake(0.0f, -12.0f);
self.theme = [CPTTheme themeNamed:kCPTPlainWhiteTheme];
}
Not as important, but I'm also getting an error when I use the kCPTPlainWhiteTheme const, or other theme consts. a thread 1:EXC_BAD_ACCESS(code=1, address=0x0).
It's probably an obvious issue but I just cant see it.
Thanks in advance.

scrollview stacks images on top of each other -xcode

I have a scrollview with subview as images.. when I made the pictures center to the scrollview they all appear on top of each other as a stack.. I need them to scroll horizontally.. how do I fix that? this is my code so far..
- (void)viewDidLoad
{
[super viewDidLoad];
for (int i = 1; i < 18; i++) {
UIImageView *images = [[UIImageView alloc] initWithImage:[UIImage imageNamed: [NSString stringWithFormat:#"%d.jpg", i]]];
images.frame = CGRectMake((i-1)*320, 0, 320, 330);
[scroller setContentOffset:CGPointMake(0, 0)];
[scroller addSubview:images];
[images setContentMode:UIViewContentModeScaleAspectFill];
[images sizeToFit];
//center image
CGSize boundsSize = scroller.bounds.size;
CGRect frameToCenter = images.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width) {
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
NSLog(#"%f", frameToCenter.origin.x);
}
else
frameToCenter.origin.x = 0;
// center vertically
if (frameToCenter.size.height < boundsSize.height)
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
frameToCenter.origin.y = 0;
images.frame = frameToCenter;
scroller.pagingEnabled = NO;
}
[scroller setContentMode:UIViewContentModeScaleAspectFit];
scroller.delegate =self;
scroller.contentSize = CGSizeMake(320*17, 330);
scroller.backgroundColor = [UIColor blackColor];
pageControl.numberOfPages =17;
pageControl.currentPage = 0;
To center the images horizontally just use the code below
float scrollHeight = 0;
for (int col = 0; col < index; ++col)
{
CGRect selectFrame = CGRectMake(0,0,kOvrW,kOvrH);
selectionIndicator = [[UIImageView alloc] initWithFrame:selectFrame];
selectionIndicator.contentMode = UIViewContentModeBottomRight;
[selectionIndicator setImage:[UIImage imageNamed:#"checked"]];
CGRect frame = CGRectMake(5,kOvrPreY+col*(kOvrPreH+kOvrH),kOvrW,kOvrH);
UIView *fr = [[UIView alloc] initWithFrame:frame];
CGRect imgFrame = CGRectMake(5, 4, 68, 55);
UIImageView *imgView = [[UIImageView alloc]initWithFrame:imgFrame];
imgView.image = [UIImage imageNamed:[[subCategories objectAtIndex:col] valueForKey:#"add"]];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapAction:)];
tapGesture.numberOfTapsRequired = 1;
tapGesture.numberOfTouchesRequired = 1;
[fr setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"small-thumb"]]];
[fr addGestureRecognizer:tapGesture];
[fr addSubview:imgView];
fr.tag = col;
[subCatScroll addSubview:fr];
[subCatScroll bringSubviewToFront:fr];
scrollHeight += kOvrPreH+kOvrH;
}
subCatScroll.contentSize = CGSizeMake(subCatScroll.frame.size.width, scrollHeight+kOvrPreH);

GL_STACK_OVERFLOW (0x503) error Cocos2d

So I have it set up so when the characters health is < 100 (for testing purposes) it stop the scene and goes to the game over scene.
if (playerDataManager.playerHealth < 100) {
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:3 scene: [GameLogic scene]]];
}
However when the players health drops below 100, it goes to the new scene, but the FPS drops dramatically from 60 to 5.
I get a list of OpenGL error 0x0503 in -[EAGLView swapBuffers] then it stays frozen like that for about 40 seconds, then the FPS unfreeze and goes back out to 60 and I get a list of 2012-07-13 10:37:50.234 Tilegame[93513:10a03] cocos2d: removeChildByTag: child not found!
Then I can continue with the app like normal, going back to the main menu, starting a new game, then recreate the error.
#import "HelloWorldLayer.h"
#import "Menu.h"
#import "SimpleAudioEngine.h"
#import "LogCabinMap.h"
#import "LogShedMap.h"
#import "SaveData.h"
#import "pauseM.h"
#import "Player.h"
#import "GameLogic.h"
CCSprite *player;
CGPoint newPos;
int joyDegrees;
// HelloWorldLayer implementation
#implementation HelloWorldLayer
#synthesize tileMap = _tileMap;
#synthesize background = _background;
#synthesize buildings = _buildings;
#synthesize meta = _meta;
#synthesize player = _player;
#synthesize foreground = _foreground;
#synthesize numCollected = _numCollected;
#synthesize hud = _hud;
-(void) animateEnemy:(CCSprite*)enemy {
//speed of the enemy
ccTime actualDuration = .2;
id actionMove;
int distanceFromPlayer = ccpDistance(player.position, enemy.position);
if (distanceFromPlayer < 200) { //Check whether enemy can "see" Ninja before moving towards him.
//rotate to face the player
CGPoint diff = ccpSub(player.position,enemy.position);
float angleRadians = atanf((float)diff.y / (float)diff.x);
float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
float cocosAngle = -1 * angleDegrees;
if (diff.x < 0) {
cocosAngle += 180;
}
enemy.rotation = cocosAngle;
actionMove = [CCMoveBy actionWithDuration:actualDuration
position:ccpMult(ccpNormalize(ccpSub(player.position,enemy.position)),10)];
} else {
actionMove = [CCMoveBy actionWithDuration:actualDuration
position:ccpMult(ccpNormalize(ccpSub(player.position,enemy.position)),0)];
}
id actionMoveDone = [CCCallFuncN actionWithTarget:self
selector:#selector(enemyMoveFinished:)];
[enemy runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
}
// callback. starts another iteration of enemy movement.
- (void) enemyMoveFinished:(id)sender {
CCSprite *enemy = (CCSprite *)sender;
[self animateEnemy: enemy];
}
-(void)addEnemyAtX:(int)x y:(int)y {
CCSprite *enemy = [CCSprite spriteWithFile:#"enemy1.png"];
enemy.position = ccp(x, y);
[self addChild:enemy];
[self animateEnemy:enemy];
}
-(void)setViewpointCenter:(CGPoint) position {
CGSize winSize = [[CCDirector sharedDirector] winSize];
int x = MAX(position.x, winSize.width / 2);
int y = MAX(position.y, winSize.height / 2);
x = MIN(x, (_tileMap.mapSize.width * _tileMap.tileSize.width)
- winSize.width / 2);
y = MIN(y, (_tileMap.mapSize.height * _tileMap.tileSize.height)
- winSize.height/2);
CGPoint actualPosition = ccp(x, y);
CGPoint centerOfView = ccp(winSize.width/2, winSize.height/2);
CGPoint viewPoint = ccpSub(centerOfView, actualPosition);
self.position = viewPoint;
}
-(id) init
{
if( (self=[super init] )) {
[[SimpleAudioEngine sharedEngine] preloadEffect:#"pickup.caf"];
[[SimpleAudioEngine sharedEngine] preloadEffect:#"hit.caf"];
[[SimpleAudioEngine sharedEngine] preloadEffect:#"move.caf"];
//[[SimpleAudioEngine sharedEngine] playBackgroundMusic:#"TileMap.caf"];
self.isTouchEnabled = YES;
self.tileMap = [CCTMXTiledMap tiledMapWithTMXFile:#"TileMap.tmx"];
self.background = [_tileMap layerNamed:#"Background"];
self.foreground = [_tileMap layerNamed:#"Foreground"];
self.buildings = [_tileMap layerNamed:#"Buildings"];
self.meta = [_tileMap layerNamed:#"Meta"];
_meta.visible = NO;
CCTMXObjectGroup *objects = [_tileMap objectGroupNamed:#"Objects"];
NSAssert(objects != nil, #"'Objects' object group not found");
//NSMutableDictionary * padPoints = [objects objectNamed:#"pad"];
NSMutableDictionary * padPoints;
SaveData * SaveDataManager = [SaveData sharedSaveDataManager];
for (int i = 0; i < 20; i ++) {
for (padPoints in [objects objects]) {
if ([[SaveDataManager.padArray objectAtIndex: i] intValue] == 1 ){
if ([[padPoints valueForKey:#"pad"] intValue] == i){
int x = [[padPoints valueForKey:#"x"] intValue];
int y = [[padPoints valueForKey:#"y"] intValue];
self.player = [CCSprite spriteWithFile:#"man.png"];
_player.position = ccp(x+16,y+16);
//[self addChild:_player];
}
}
}
}
// iterate through objects, finding all enemy spawn points
// create an enemy for each one
NSMutableDictionary * spawnPoints;
for (spawnPoints in [objects objects]) {
if ([[spawnPoints valueForKey:#"Enemy"] intValue] == 2){
int x = [[spawnPoints valueForKey:#"x"] intValue];
int y = [[spawnPoints valueForKey:#"y"] intValue];
[self addEnemyAtX:x+=16 y:y+=64];
}
}
player = [CCSprite spriteWithFile:#"man.png"];
player.position= _player.position;
[_tileMap addChild:player z: 0];
// [self addChild:player z:10];
[self setViewpointCenter:player.position];
[self addChild:_tileMap z:-1];
[self scheduleUpdate];
}
return self;
}
- (CGPoint)tileCoordForPosition:(CGPoint)position {
int x = position.x / _tileMap.tileSize.width;
int y = ((_tileMap.mapSize.height * _tileMap.tileSize.height) - position.y) / _tileMap.tileSize.height;
return ccp(x, y);
}
-(void)setPlayerPosition:(CGPoint)position {
Player * playerDataManager = [Player playerSaveDataManager];
CGPoint tileCoord = [self tileCoordForPosition:position];
int tileGid = [_meta tileGIDAt:tileCoord];
int x = player.position.x;
int y = player.position.y;
if (tileGid) {
NSDictionary *properties = [_tileMap propertiesForGID:tileGid];
if (properties) {
NSString *collision = [properties valueForKey:#"Collidable"];
if (collision && [collision compare:#"True"] == NSOrderedSame) {
//[[SimpleAudioEngine sharedEngine] playEffect:#"hit.caf"];
if (joyDegrees > 45 && joyDegrees < 135){
player.position = ccp(x,y-1);
}
if (joyDegrees > 135 && joyDegrees < 225){
player.position = ccp(x+1,y);
}
if (joyDegrees > 225 && joyDegrees < 315){
player.position = ccp(x,y+1);
}
if ((joyDegrees > 315 && joyDegrees < 360) || (joyDegrees > -1 && joyDegrees < 45)){
player.position = ccp(x-1,y);
}
return;
}
NSString *collectable = [properties valueForKey:#"Collectable"];
if (collectable && [collectable compare:#"True"] == NSOrderedSame) {
[[SimpleAudioEngine sharedEngine] playEffect:#"pickup.caf"];
[_meta removeTileAt:tileCoord];
[_foreground removeTileAt:tileCoord];
self.numCollected += 1;
[_hud numCollectedChanged:_numCollected];
playerDataManager.playerHealth -= 10;
}
NSString *Gate = [properties valueForKey:#"Gate"];
if (Gate && [Gate compare:#"1"] == NSOrderedSame) {
SaveData * SaveDataManager = [SaveData sharedSaveDataManager];
//[SaveDataManager.padArray removeAllObjects];
for (int i = 0; i < 20; i ++) {
[SaveDataManager.padArray replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:0]];
}
[SaveDataManager.padArray replaceObjectAtIndex:1 withObject:[NSNumber numberWithInt:1]];
//[[CCDirector sharedDirector] replaceScene:[LogCabinMap scene]];
[[CCDirector sharedDirector] pushScene:[LogCabinMap scene]];
}
if (Gate && [Gate compare:#"2"] == NSOrderedSame) {
SaveData * SaveDataManager = [SaveData sharedSaveDataManager];
//[SaveDataManager.padArray removeAllObjects];
for (int i = 0; i < 20; i ++) {
[SaveDataManager.padArray replaceObjectAtIndex:i withObject:[NSNumber numberWithInt:0]];
}
[SaveDataManager.padArray replaceObjectAtIndex:1 withObject:[NSNumber numberWithInt:1]];
//[[CCDirector sharedDirector] replaceScene:[LogShedMap scene]];
[[CCDirector sharedDirector] pushScene:[LogShedMap scene]];
}
}
}
//[[SimpleAudioEngine sharedEngine] playEffect:#"move.caf"];
player.position = position;
}
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
return YES;
}
-(void) update:(ccTime)deltaTime {
[self setPlayerPosition:newPos];
[self setViewpointCenter:player.position];
}
// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
// in this particular example nothing needs to be released.
// cocos2d will automatically release all the children (Label)
self.tileMap = nil;
self.background = nil;
self.foreground = nil;
self.buildings = nil;
self.meta =nil;
self.player = nil;
player = nil;
self.hud = nil;
// don't forget to call "super dealloc"
[super dealloc];
}
#end
#implementation HelloWorldHud
#synthesize background;
#synthesize background2;
#synthesize health;
#synthesize baseScaleFactor;
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldHud *layer = [HelloWorldHud node];
// add layer as a child to scene
[scene addChild: layer z:2];
HelloWorldLayer *hud = [HelloWorldLayer node];
[scene addChild: hud z:1];
//layer.hud = hud;
// return the scene
return scene;
}
-(void)initJoystick {
SneakyJoystickSkinnedBase *joystickBase = [[[SneakyJoystickSkinnedBase alloc] init] autorelease];
joystickBase.backgroundSprite = [CCSprite spriteWithFile:#"JoyB.png"];
joystickBase.thumbSprite = [CCSprite spriteWithFile:#"JoyS.png"];
joystickBase.joystick = [[SneakyJoystick alloc] initWithRect: CGRectMake(0, 0, 128, 128)];
joystickBase.position = ccp(55, 55);
[self addChild:joystickBase];
leftJoystick = [[joystickBase.joystick retain] autorelease];
}
-(void) update:(ccTime)deltaTime {
Player *playerDataManager = [Player playerSaveDataManager];
CGPoint scaledVelocity = ccpMult(leftJoystick.velocity, 100);
CGPoint newPosition = ccp(player.position.x + scaledVelocity.x * deltaTime, player.position.y + scaledVelocity.y * deltaTime);
if (leftJoystick.velocity.x == 0 && leftJoystick.velocity.y == 0 ){
if (!playerDataManager.standStill) {
[player stopAllActions];
playerDataManager.walkUp = FALSE;
playerDataManager.walkDown = FALSE;
playerDataManager.walkRight = FALSE;
playerDataManager.walkLeft = FALSE;
playerDataManager.standStill = TRUE;
[player runAction:playerDataManager.standAction];
}
}
if (leftJoystick.degrees > 45 && leftJoystick.degrees < 135){
if (!playerDataManager.walkUp) {
[player stopAllActions];
playerDataManager.walkUp = TRUE;
playerDataManager.walkDown = FALSE;
playerDataManager.walkRight = FALSE;
playerDataManager.walkLeft = FALSE;
playerDataManager.standStill = FALSE;
[player runAction:playerDataManager.walkUpAction];
}
}
if (leftJoystick.degrees > 135 && leftJoystick.degrees < 225){
if (!playerDataManager.walkLeft) {
[player stopAllActions];
playerDataManager.walkUp = FALSE;
playerDataManager.walkDown = FALSE;
playerDataManager.walkRight = FALSE;
playerDataManager.walkLeft = TRUE;
playerDataManager.standStill = FALSE;
[player runAction:playerDataManager.walkLeftAction];
}
}
if (leftJoystick.degrees > 225 && leftJoystick.degrees < 315){
if (!playerDataManager.walkDown) {
[player stopAllActions];
playerDataManager.walkUp = FALSE;
playerDataManager.walkDown = TRUE;
playerDataManager.walkRight = FALSE;
playerDataManager.walkLeft = FALSE;
playerDataManager.standStill = FALSE;
[player runAction:playerDataManager.walkDownAction];
}
}
if (((leftJoystick.degrees > 315 && leftJoystick.degrees < 360) && (leftJoystick.velocity.x != 0 && leftJoystick.velocity.y != 0 )) || ((leftJoystick.degrees > -1 && leftJoystick.degrees < 45) && (leftJoystick.velocity.x != 0 && leftJoystick.velocity.y != 0 ))){
if (!playerDataManager.walkRight) {
[player stopAllActions];
playerDataManager.walkUp = FALSE;
playerDataManager.walkDown = FALSE;
playerDataManager.walkRight = TRUE;
playerDataManager.walkLeft = FALSE;
playerDataManager.standStill = FALSE;
[player runAction:playerDataManager.walkRightAction];
}
}
float scaleFactor = playerDataManager.playerHealth/baseScaleFactor;
health.scaleX = playerDataManager.playerHealth/1;
newPos = newPosition;
joyDegrees = leftJoystick.degrees;
if (playerDataManager.playerHealth < 100) {
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:3 scene: [GameLogic scene]]];
[[CCDirector sharedDirector] replaceScene: [GameLogic scene]];
}
}
-(void) scroll:(ccTime)dt
{
//move 30*dt px vertically
if (background.position.y<background2.position.y){
background.position = ccp(background.contentSize.width/2, background.position.y - 225*dt);
background2.position = ccp(background2.contentSize.width/2, background.position.y+background.contentSize.height);
}else{
background2.position = ccp(background2.contentSize.width/2, background2.position.y- 225*dt);
background.position = ccp(background.contentSize.width/2, background2.position.y+background2.contentSize.height);
}
//reset offscreen position
if (background.position.y <-background.contentSize.height/2)
{
background.position = ccp(background.contentSize.height/2,background2.position.y+background2.contentSize.height);
}else if (background2.position.y < -background2.contentSize.height/2)
{
background2.position = ccp(background2.contentSize.height/2, background.position.y+background.contentSize.height);
}
}
-(id) init
{
if ((self = [super init])) {
CGSize size = [CCDirector sharedDirector].winSize;
background = [CCSprite spriteWithFile:#"rain.png"];
background2 = [CCSprite spriteWithFile:#"rain.png"];
[background.texture setAliasTexParameters];
[background2.texture setAliasTexParameters];
//position background sprites
background.position = ccp(background.contentSize.height/2,background.contentSize.width/2);
background2.position = ccp(size.width,0);
//schedule to move background sprites
//[self schedule:#selector(scroll:)];
//adding them to the main layer
//[self addChild:background z:-1];
//[self addChild:background2 z:-1];
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"GUI.plist"];
CCSpriteBatchNode *GUISpriteSheet = [CCSpriteBatchNode batchNodeWithFile:#"GUI.png"];
[self addChild:GUISpriteSheet];
CCSprite * healthBar = [CCSprite spriteWithSpriteFrameName:#"bar.png"];
CCSprite * cap = [CCSprite spriteWithSpriteFrameName:#"cap.png"];
CCSprite * endCap = [CCSprite spriteWithSpriteFrameName:#"endcap.png"];
health = [CCSprite spriteWithSpriteFrameName:#"red.png"];
healthBar.anchorPoint = ccp(0,1);
health.anchorPoint = ccp(0,1);
cap.anchorPoint = ccp(0,1);
endCap.anchorPoint = ccp(0,1);
healthBar.position = ccp(1 , size.height);
healthBar.scaleX = 25;
cap.position = ccp(0 , size.height);
int width = [healthBar boundingBox].size.width;
endCap.position = ccp(width , size.height);
health.position = ccp(1, size.height-2);
baseScaleFactor = width;
health.scaleX = baseScaleFactor;
[self addChild:healthBar];
[self addChild:cap];
[self addChild:endCap];
[self addChild:health];
CGSize winSize = [[CCDirector sharedDirector] winSize];
label = [CCLabelTTF labelWithString:#"0" dimensions:CGSizeMake(50, 20)
alignment:UITextAlignmentRight fontName:#"Verdana-Bold"
fontSize:18.0];
label.color = ccc3(0,0,0);
int margin = 10;
label.position = ccp(winSize.width - (label.contentSize.width/2)
- margin, label.contentSize.height/2 + margin);
[self addChild:label];
CCMenuItemFont * pause = [CCMenuItemFont itemFromString:#"Pause" target:self selector:#selector(pause:)];
CCMenu *menu = [CCMenu menuWithItems: pause, nil];
pause.position = ccp(206,142);
[self addChild:menu];
CCSprite *pix = [CCSprite spriteWithFile:#"pix.png"];
pix.position = ccp(size.width/2, size.height/2);
//pix.scale = 50000;
[self addChild:pix z:1];
//[pix runAction:[CCTintTo actionWithDuration:10 red:255 green:0 blue:0]];
//[pix runAction:[CCScaleTo actionWithDuration:15 scale:500]];
pix.color = ccc3(255, 255, 255);
[self scheduleUpdate];
[self initJoystick];
}
return self;
}
- (void)numCollectedChanged:(int)numCollected {
[label setString:[NSString stringWithFormat:#"%d", numCollected]];
// [label setString:[NSString stringWithFormat:#"%d", score]];
}
- (void) pause: (id) sender
{
[[CCDirector sharedDirector] pushScene:[pauseM scene]];
}
- (void) dealloc
{
self.background = nil;
self.background2 = nil;
self.health = nil;
self.meta =nil;
player = nil;
// don't forget to call "super dealloc"
[super dealloc];
}
#end
Above is the .m scene that is running when the problem occurs and below is the GameLogic.m
#import "GameLogic.h"
#import "Player.h"
#import "Menu.h"
#implementation GameLogic
+(id) scene
{
CCScene *scene = [CCScene node];
GameLogic *layer = [GameLogic node];
[scene addChild: layer];
return scene;
}
+(id) gameLogicSaveDataManager {
static id gameLogicSaveDataManager = nil;
if (gameLogicSaveDataManager == nil) {
gameLogicSaveDataManager = [[self alloc] init];
}
return gameLogicSaveDataManager;
}
-(id) init
{
if( (self=[super init] )) {
CCSprite *bg = [CCSprite spriteWithFile:#"bg.jpg"];
bg.anchorPoint = ccp(0,0);
id fadeIn = [CCFadeIn actionWithDuration:3];
[self addChild:bg];
[bg runAction: fadeIn];
CCLayer *menuLayer = [[[CCLayer alloc] init] autorelease];
[self addChild:menuLayer];
CCMenuItemImage *home = [CCMenuItemImage
itemFromNormalImage:#"bg.jpg"
selectedImage:#"bg.jpg"
target:self
selector:#selector(home:)];
CCMenu *menu = [CCMenu menuWithItems: home, nil];
home.position = ccp(0,0);
[menuLayer addChild: menu];
}
return self;
}
- (void) home: (id) sender
{
[[CCDirector sharedDirector] replaceScene:[Menu scene]];
}
- (void) dealloc
{
[super dealloc];
}
#end
OpenGL error 0x503 means GL_STACK_OVERFLOW, it means you are pushing too many things onto the opengl stack.
I see several instances of pushScene in your code, but no instances of pop anything anywhere. You cannot just keep pushing things indefinitely without popping them, or you will get this error.
We need to what is currently running in your scene, how it has been allocated and how it is released. We also need to know the same information for the new loaded scene GameLogic. Edit your question and add these data.

Resources