Saving NSInteger intScore when application is closed - iphone

I made an app with xcode 4, all code is in the main code file so i don't have more classes.
I have 3 views but only use one at the moment. Now in the game i save an integer as score, and at the end of the game it shows what your score is, but i wanted to know how i can let that int show up in a label in one of my other 2 views, and how i can keep it there when the application is restarted. I'm sorry of my bad english but i'm new to this objective C and iphone Apps. Thank You!
and how do i put something in an other viewcontroller, can't fine codefile
this is the code:
//
// ViewController.m
// Mundo Grafia
//
// Created by Axel Lambregts on 2/10/12.
// Copyright (c) 2012 AxelNiels. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
// variabelen aanmaken
NSInteger intScore;
NSInteger intRandomMonument;
NSInteger intRandomAnswerPosition;
NSInteger intRandomAnswerA;
NSInteger intRandomAnswerB;
NSInteger intRandomAnswerC;
NSInteger intRandomAnswerD;
NSInteger intArrayEuropeLenght;
NSInteger intAmountOfQuestionsAsked;
NSString *scoreSpatie;
NSString *arrEurope[][2] =
{
{#"Eifel.jpg",#"Paris"},
{#"NotreDame.jpg",#"Paris"},
{#"ArcDeTriompheParis.jpg",#"Paris"},
{#"AtomuimBrussels.jpg",#"Brussels"},
{#"MannekePis.jpg",#"Brussels"},
{#"Colosseum.jpg",#"Rome"},
{#"TreviFountainRome.jpg",#"Rome"},
{#"SagradaFamilia.jpg",#"Barcelona"},
{#"SpanishSchoolMadrid.jpg",#"Madrid"},
{#"KremlinMoskou.jpg",#"Moskou"},
{#"MermaidKopenhagen.jpg",#"Copenhagen"},
{#"MonteCarloMonaco.jpg",#"Monaco"},
{#"AcropolisAthens.jpg",#"Athens"},
{#"ParlementBudapest.jpg",#"Budapest"},
{#"BuildingReykjavik.jpg",#"Reykjavik"},
{#"StatueKiev.jpg",#"Kiev"},
{#"PortOfEuropeLissabon.jpg",#"Lisbon"},
{#"ViewSanMarino.jpg",#"San Marino"},
{#"BridgesPrague.jpg",#"Prague"},
{#"MoskeeAnkara.jpg",#"Ankara"},
{#"TowerBridgeLondon.jpg",#"London"},
{#"BigBenLondon.jpg",#"London"},
{#"LondonEyeLondon.jpg",#"London"},
{#"BrandenburgerTor.jpg",#"Berlin"},
{#"ReichstagBerlin.jpg",#"Berlin"},
{nil,nil}
};
/*
NSArray *arrEurope = #[
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"AtomuimBrussels.jpg",#"Brussels"],
#[#"MannekePis.jpg",#"Brussels"],
#[#"Colosseum.jpg",#"Rome"],
#[#"TreviFountainRome.jpg",#"Rome"],
#[#"SagradaFamilia.jpg",#"Barcelona"],
#[#"SpanishSchoolMadrid.jpg",#"Madrid"],
#[#"KremlinMoskou.jpg",#"Moskou"],
#[#"MermaidKopenhagen.jpg",#"Copenhagen"],
#[#"MonteCarloMonaco.jpg",#"Monaco"],
#[#"AcropolisAthens.jpg",#"Athens"],
#[#"ParlementBudapest.jpg",#"Budapest"],
#[#"BuildingReykjavik.jpg",#"Reykjavik"],
#[#"StatueKiev.jpg",#"Kiev"],
#[#"PortOfEuropeLissabon.jpg",#"Lisbon"],
#[#"ViewSanMarino.jpg",#"San Marino"],
#[#"BridgesPrague.jpg",#"Prague"],
#[#"MoskeeAnkara.jpg",#"Ankara"],
#[#"TowerBridgeLondon.jpg",#"London"],
#[#"BigBenLondon.jpg",#"London"],
#[#"LondonEyeLondon.jpg",#"London"],
#[#"BrandenburgerTor.jpg",#"Berlin"],
#[#"ReichstagBerlin.jpg",#"Berlin"]
];
*/
//methode'start' wanneer er op de start-knop wordt gedrukt
-(IBAction)start{
[self NewQuestionEurope];
intAmountOfQuestionsAsked = 0;
//reset and show score
intScore = 0;
score.text = [NSString stringWithFormat:#"%d", intScore];
//make buttons and labels visible
Start.hidden = YES;
question.hidden = NO;
score.hidden = NO;
scoretext.hidden = NO;
imageContainer.hidden = NO;
answerA.hidden = NO;
answerB.hidden = NO;
answerC.hidden = NO;
answerD.hidden = NO;
answerA.textColor = [UIColor greenColor];
answerB.textColor = [UIColor greenColor];
answerC.textColor = [UIColor greenColor];
answerD.textColor = [UIColor greenColor];
clickButtonA.hidden = NO;
clickButtonB.hidden = NO;
clickButtonC.hidden = NO;
clickButtonD.hidden = NO;
GoodFalse.hidden = NO;
GoodFalse.text=#"Press a button to answer";
GoodFalse.textColor = [UIColor greenColor];
question.text = #"Where is this picture taken?";
}//einde start
-(IBAction)Reset{
score.text= #"gelukt";
}
-(IBAction)NewQuestionEurope{
if(intAmountOfQuestionsAsked == 19){
question.text = [#"Uw score is: "stringByAppendingString: [NSString stringWithFormat:#"%d", intScore]];
Start.hidden = NO;
question.hidden = NO;
score.hidden = YES;
scoretext.hidden = YES;
imageContainer.hidden = YES;
answerA.hidden = YES;
answerB.hidden = YES;
answerC.hidden = YES;
answerD.hidden = YES;
clickButtonA.hidden = YES;
clickButtonB.hidden = YES;
clickButtonC.hidden = YES;
clickButtonD.hidden = YES;
GoodFalse.hidden = YES;
Start.titleLabel.text = #"END";
}
else{
intAmountOfQuestionsAsked ++;
//Deze lus geeft aan intArrayEuropeLenght de waarde van hoeveel rijen de array bevat//
intArrayEuropeLenght = 0;
while (arrEurope[intArrayEuropeLenght][0] != NULL)
{
intArrayEuropeLenght++;
}
//score.text = [NSString stringWithFormat:#"%d", intScore];
scoreSpatie = [
[NSString stringWithFormat:#"%d", intScore]
stringByAppendingString:#"/"];
score.text = [
scoreSpatie
stringByAppendingString:[NSString stringWithFormat:#"%d", intAmountOfQuestionsAsked]
];
// Randoms genereren voor: 4 random antwoorden; 1 random afbeelding; een random positie om het juiste antwoord in te plaatsen
intRandomMonument = arc4random()%intArrayEuropeLenght;
intRandomAnswerA = arc4random()%intArrayEuropeLenght;
intRandomAnswerB = arc4random()%intArrayEuropeLenght;
intRandomAnswerC = arc4random()%intArrayEuropeLenght;
intRandomAnswerD = arc4random()%intArrayEuropeLenght;
intRandomAnswerPosition = arc4random()%4;
while(arrEurope[intRandomMonument][0] == #"removed"){
intRandomMonument = arc4random()%intArrayEuropeLenght;
}
//Random antwoorden maken
answerA.text = #"";
answerB.text = #"";
answerC.text = #"";
answerD.text = #"";
if(answerA.text = #""){
answerA.text = arrEurope[intRandomAnswerA][1];
}
if(answerB.text = #""){
answerB.text = arrEurope[intRandomAnswerB][1];
}
if(answerC.text = #""){
answerC.text = arrEurope[intRandomAnswerC][1];
}
if(answerD.text = #""){
answerD.text = arrEurope[intRandomAnswerD][1];
}
switch(intRandomAnswerPosition)
{
case 0: answerA.text = arrEurope[intRandomMonument][1];
break;
case 1: answerB.text = arrEurope[intRandomMonument][1];
break;
case 2: answerC.text = arrEurope[intRandomMonument][1];
break;
case 3: answerD.text = arrEurope[intRandomMonument][1];
};
//als er antwoorden hetzelfde zijn, voor de gelijke een random blijven maken tot ze niet hetzelfde zijn
if(
[answerA.text isEqualToString: answerB.text]||
[answerA.text isEqualToString: answerC.text]||
[answerA.text isEqualToString: answerD.text]
){
answerA.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerB.text isEqualToString: answerA.text]||
[answerB.text isEqualToString: answerC.text]||
[answerB.text isEqualToString: answerD.text]
){
answerB.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerC.text isEqualToString: answerA.text]||
[answerC.text isEqualToString: answerB.text]||
[answerC.text isEqualToString: answerD.text]
){
answerC.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerD.text isEqualToString: answerA.text]||
[answerD.text isEqualToString: answerB.text]||
[answerD.text isEqualToString: answerC.text]
){
answerD.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
//Laat de afbeelding zien van het gekozen monument (via random gekozen)
imageContainer.image = [UIImage imageNamed: arrEurope[intRandomMonument][0]];
}
}
//hier onder zit ergens een fout want hij geeft precies random juist en fout :)
//kan zijn dat het opgelost is vanaf we niet 2x dezelfde vragen hebben maar ik denk het niet.
//press buttonA
-(IBAction)AnswerA {
if([answerA.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonB
-(IBAction)AnswerB {
if([answerB.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonC (works)
-(IBAction)AnswerC {
if([answerC.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonD
-(IBAction)AnswerD {
if([answerD.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//hier onder niets wijzigen
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

NSUserDefaults *scores = [NSUserDefaults standardUserDefaults];
if (_points>[scores integerForKey :#"highscore"]) {
[_highScoresLabel setString:[NSString stringWithFormat:#"%d",_points]];
[scores setInteger:_points forKey:#"highscore"];
I'm using that code to show persistent highscore in one of my game.
to show in another UIViewController simply add this code where _higScoreLabel is the label ypu want the scores to be shown :
NSUserDefaults *scores = [NSUserDefaults standardUserDefaults];
NSString *_points = [scores integerForKey :#"highscore"];
[_highScoresLabel setString:[NSString stringWithFormat:#"%d",_points]];

As soon as you know what the user's final score was, write the integer to NSUserDefaults like:
[[NSUserDefaults standardUserDefaults] setInteger:intScore forKey:#"score"];
Then, in order to show the score integer in the other view controller, you'll need to just read the value from disk in viewDidLoad of the other viewController, and then set it in the label!
Since the value is already stored on disk, you don't even need to pass it as a parameter or set it as a property on the other viewcontroller, just read it from NSUserDefaults in viewDidLoad (or whatever/whereever method you need to set it).
So in the second viewcontroller, do:
- (void) viewDidLoad {
self.anotherLabel.text = [NSString stringWithFormat:#"%d", [defaults integerForKey:#"score"]];
}

// To save in pref
int highScore = yourGameScore;
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:highScore] forKey:#"HighScore"];
[[NSUserDefaults standardUserDefaults] synchronize];
// To get saved value from pref
int highScore = [[[NSUserDefaults standardUserDefaults] objectForKey:#"HighScore"] intValue ];
here is similar question in stack..

Try using NSUserDefaults ,it will keep the value in memory until you forcefully remove it or you delete the app.
int Score = HighScore;
[[NSUserDefaults standardUserDefaults] setObject:Score forKey:#"anyKey"];
currentScoreLabel.text = [NSString stringWithFormat:#"%d",Score];
highScoreLabel.text=[NSString stringWithFormat:#"%d",[[NSUserDefaults standardUserDefaults] objectForKey:#"anyKey"]];

Related

Core plot : bars disappears when switching app to background and then to foreground while drawing a bar graph

My bar graph disappears when I switch my app to background and then again comes back to foreground.
It's like shown below :
||| || ||
So in the above picture I have gaps, that means when my app is in background core plot does not draw bar graph. Is it a limitation of core plot?
My main task is to draw one bar per second and I have done this, but it's not working while in background. Is there some other alternate option by which I can achieve this?
Here is what I tried:
I made my graph object nil and then tried it reloading when app again comes back to foreground. But it didn't work.
-(void)redrawGraphWhenApplicationEntersForeground
{
NSLog(#"reload graph");
NSLog(#"all plots : %# , %#", [self.graph allPlots], plotArray);
DDLogInfo(#"relaod graph when entered in Foreground ");
// [self.data removeAllObjects];
//Create graph and set it as host view's graph
self.graph = nil;
[self.graph reloadDataIfNeeded];
}`
Here is my full code :
// Update is called by a timer ( of 10 second) , so that each second this method will be called and it will draw a bar.
- (void)update:(id)data1 withState:(NSInteger) type
{
switch (type) {
case ZAP_UPDATE:
if(curLinkType == DOWNLINK)
{
[self drawDownlinkGrpah];
}else if(curLinkType == UPLINK)
{
[self drawUplinkGrpah];
}
[gauge setValue:speedValue];
break;
case ZAP_DONE:
[self displayDone:type speedBps:speedBps pktLoss:pktLoss srcdst:[zap destinationAddress]];
onTap = false;
runningTime=0;
if(gauge != nil){
[gauge setValue:0];
}
{
NSArray *parameter = [NSArray arrayWithObjects: speed, unit, nil];
[self performSelector:#selector(stopGauge:) withObject:parameter afterDelay:0.2];
}
}
}
- (void)drawDownlinkGrpah {
DownlinCount++;
self.downlinkdata = [NSMutableArray array];
double position = DownlinCount*((4*10)/(double)durationval);
NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:position],BAR_POSITION,
[NSNumber numberWithDouble:speedBarValue],BAR_HEIGHT,
[UIColor orangeColor],COLOR,
nil];
[self.downlinkdata addObject:bar];
self.data = self.downlinkdata;
[self generateBarPlotForDownlink:YES];
}
- (void)drawUplinkGrpah {
UplinkCount++;
self.uplinkdata = [NSMutableArray array];
double position = UplinkCount*((4*10)/(double)durationval);
NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:position],BAR_POSITION,
[NSNumber numberWithDouble:speedBarValue],BAR_HEIGHT,
[UIColor orangeColor],COLOR,
nil];
[self.uplinkdata addObject:bar];
self.data = self.uplinkdata;
[self generateBarPlotForDownlink:NO];
}
- (NSInteger)getBarposition:(NSInteger)samplesize {
return (4*10)/samplesize;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)resetGraph:(UIImageView*) imageview {
for(UIView *view in imageview.subviews)
[view removeFromSuperview];
[imageview setImage:[UIImage imageNamed:#"graph_container"]];
}
#pragma mark -
-(void)appGoesinBackground
{
// NSLog(#"make nil graph");
// DDLogInfo(#"remove graph when entered in background ");
//
self.graph = nil;
// [self.data removeAllObjects];
[plotArray removeAllObjects]; // remove all data before entering to background
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(redrawGraphWhenApplicationEntersForeground)
name: UIApplicationDidBecomeActiveNotification
object: nil];
}
// redraw graph ..
-(void)redrawGraphWhenApplicationEntersForeground
{
NSLog(#"reload graph");
NSLog(#"all plots : %# , %#", [self.graph allPlots], plotArray);
DDLogInfo(#"relaod graph when entered in Foreground ");
// [self.data removeAllObjects];
//Create graph and set it as host view's graph
// self.graph = nil;
//
for (CPTBarPlot *p in plotArray) {
// [self.graph addPlot:p];
[p reloadData];
}
}
#pragma mark - generate bar plot
- (void)generateBarPlotForDownlink:(BOOL)enabled
{
NSLog(#"generateBarPlotForDownlink >>>>>>");
//Create host view
self.hostingView = [[CPTGraphHostingView alloc] initWithFrame:CGRectMake(-35, -20, 128, 73)];
//Create graph and set it as host view's graph
self.graph = [[CPTXYGraph alloc] initWithFrame:self.downlinkImageView.frame];
self.graph.plotAreaFrame.masksToBorder = NO;
[self.hostingView setHostedGraph:self.graph];
if(enabled) // for downlink graph ..
{
self.downlinkImageView.image=nil;
[self.downlinkImageView addSubview:self.hostingView];
}
else{ // for uplink graph ..
self.uplinkImageView.image=nil;
[self.uplinkImageView addSubview:self.hostingView];
}
// Create bar plot and add it to the graph
CPTBarPlot *plot = [[CPTBarPlot alloc] init] ;
plot.dataSource = self;
plot.delegate = self;
//set axes ranges
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat((AXIS_END - AXIS_START)+1)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat(maxYRange)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.xAxis.minorTickLength = 1.0f;
axisSet.yAxis.minorTickLength = 1.0f;
axisSet.hidden=YES;
axisSet.xAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
axisSet.yAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
float barwidht = (2*10.0)/(float)durationval;
NSString *inStr = [NSString stringWithFormat: #"%f", barwidht];
plot.barWidth = [[NSDecimalNumber decimalNumberWithString:inStr] // Need to change according sample // 1.5 for 10 , 0.75 for 20
decimalValue];
plot.barOffset = [[NSDecimalNumber decimalNumberWithString:#"5.0"]
decimalValue];
plot.barCornerRadius = 0.0;
// Remove bar outlines
CPTMutableLineStyle *borderLineStyle = [CPTMutableLineStyle lineStyle];
borderLineStyle.lineColor = [CPTColor clearColor];
plot.lineStyle = borderLineStyle;
plot.identifier = #"chocoplot";
[self.graph addPlot:plot];
// Add plot to array in case if app is moved to background state ..
[plotArray addObject:plot];
NSLog(#"plot : %#",plot);
NSLog(#"plot added ..%lu", (unsigned long)plotArray.count );
}
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
if ( [plot.identifier isEqual:#"chocoplot"] )
return [self.data count];
return 0;
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
if ( [plot.identifier isEqual:#"chocoplot"] )
{
NSDictionary *bar = [self.data objectAtIndex:index];
if(fieldEnum == CPTBarPlotFieldBarLocation)
return [bar valueForKey:BAR_POSITION];
else if(fieldEnum ==CPTBarPlotFieldBarTip)
return [bar valueForKey:BAR_HEIGHT];
}
return [NSNumber numberWithFloat:0];
}
-(CPTFill *)barFillForBarPlot:(CPTBarPlot *)barPlot
recordIndex:(NSUInteger)index
{
if ( [barPlot.identifier isEqual:#"chocoplot"] )
{
NSDictionary *bar = [self.data objectAtIndex:index];
CPTGradient *gradient = [CPTGradient gradientWithBeginningColor:[CPTColor redColor]
endingColor:[bar valueForKey:#"COLOR"]
beginningPosition:0.0 endingPosition:0.6 ];
[gradient setGradientType:CPTGradientTypeAxial];
[gradient setAngle:320.0];
CPTFill *fill = [CPTFill fillWithGradient:gradient];
return fill;
}
return [CPTFill fillWithColor:[CPTColor colorWithComponentRed:1.0 green:1.0 blue:1.0 alpha:1.0]];
}
Screenshot:
You don't need to create a new graph every time you get new plot data. Just add the new point to the data array and call -reloadData on the plot.
When the app goes into the background, just clear your data array and call -reloadData on the plot. It will reload the empty data and display the graph when the app comes back to the foreground. There's no reason to set self.graph to nil unless you remove the graph from the hosting view and you want it to go away. From what I can see in the posted code, the graph is still in the hosting view, but you've lost your reference to it, making any updates you make when the app comes to the foreground ineffective.
Here is the code that worked for me :
- (void)drawDownlinkGrpah {
NSLog(#"drawDownlinkGrpah CAlled");
DownlinCount++;
double position = DownlinCount*((4*10)/(double)durationval);
NSDictionary *bar = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:position],BAR_POSITION,
[NSNumber numberWithDouble:speedBarValue],BAR_HEIGHT,
[UIColor orangeColor],COLOR,
nil];
[self.downlinkdata addObject:bar];
self.data = self.downlinkdata;
[self generateBarPlotForDownlink:YES];
}
#pragma mark - generate bar
- (void)generateBarPlotForDownlink:(BOOL)enabled
{
if(enabled)
{
self.downlinkImageView.image=nil;
if(![self.hostingView isDescendantOfView:self.downlinkImageView])
{
// Configure hosting view so that it appears from fresh ..
[self configureGraph];
[self.downlinkImageView addSubview:self.hostingView];
NSLog(#"hosting view added in downlink view ");
}
}
else
{
self.uplinkImageView.image=nil;
// if hosting view is not in uplink view
if(![self.hostingView isDescendantOfView:self.uplinkImageView])
{
// Configure hosting view so that it appears from fresh ..
[self configureGraph];
[self.uplinkImageView addSubview:self.hostingView];
NSLog(#"hosting view added in uplink view ");
}
}
//set axes ranges
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat((AXIS_END - AXIS_START)+1)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:
CPTDecimalFromFloat(AXIS_START)
length:CPTDecimalFromFloat(maxYRange)];
CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
axisSet.xAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.yAxis.majorIntervalLength = CPTDecimalFromFloat(1.0f);
axisSet.xAxis.minorTickLength = 1.0f;
axisSet.yAxis.minorTickLength = 1.0f;
axisSet.hidden=YES;
axisSet.xAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
axisSet.yAxis.labelingPolicy=CPTAxisLabelingPolicyNone;
// Create bar plot and add it to the graph
NSLog(#"plot created %ld", (long)durationval);
CPTBarPlot *plot = [[CPTBarPlot alloc] init] ;
plot.dataSource = self;
plot.delegate = self;
float barwidht = (2*10.0)/(float)durationval;
NSString *inStr = [NSString stringWithFormat: #"%f", barwidht]; //CPTDecimalFromDouble(2.0);
plot.barWidth = [[NSDecimalNumber decimalNumberWithString:inStr]
decimalValue];// Need to change according sample // 1.5 for 10 , 0.75 for 20
plot.barWidth = CPTDecimalFromDouble(barwidht);
plot.barOffset = [[NSDecimalNumber decimalNumberWithString:#"5.0"]
decimalValue];
plot.barCornerRadius = 0.0;
// Remove bar outlines
CPTMutableLineStyle *borderLineStyle = [CPTMutableLineStyle lineStyle];
borderLineStyle.lineColor = [CPTColor clearColor];
plot.lineStyle = borderLineStyle;
plot.identifier = #"chocoplot";
[self.graph addPlot:plot];
}
#pragma mark - core plot data source and delegate methods
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
if ( [plot.identifier isEqual:#"chocoplot"] )
return [self.data count];
return 0;
}
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
if ( [plot.identifier isEqual:#"chocoplot"] )
{
NSDictionary *bar = [self.data objectAtIndex:index];
if(fieldEnum == CPTScatterPlotFieldX)
return [bar valueForKey:BAR_POSITION];
else if(fieldEnum ==CPTScatterPlotFieldY)
return [bar valueForKey:BAR_HEIGHT];
}
return [NSNumber numberWithFloat:0];
}
drawDownlinkGraph method would be called each second using a timer and it will call generateBarPlotForDownlink: Method every second . And bar will be drawn each second on a real time basis even if APP is in background.

Reset array after playing the game?

I made a quiz in iOS with xcode, what i have now is a quiz that generates 20 random answers out of an array, it controls the text of the labels when a button is pushed to check if the answer is correct. The answers are also random generated and i made sure that there weren't mulple answers with the same text. My problem is that when a question is asked, i change the text of an object in my array to "removed"; but when i push start again after i've done the quiz, my array has 20 objects with the string "remove"; my question is: How can I reset my array to it's normal objects? Here is my full code, ignore the comments but it's kind of a junk cause i'm new to ios programming:
//
// ViewController.m
// Mundo Grafia
//
// Created by Axel Lambregts on 2/10/12.
// Copyright (c) 2012 AxelNiels. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
// variabelen aanmaken
NSInteger intScore;
NSInteger intRandomMonument;
NSInteger intRandomAnswerPosition;
NSInteger intRandomAnswerA;
NSInteger intRandomAnswerB;
NSInteger intRandomAnswerC;
NSInteger intRandomAnswerD;
NSInteger intArrayEuropeLenght;
NSInteger intAmountOfQuestionsAsked;
NSString *scoreSpatie;
NSString *arrEurope[][2] =
{
{#"Eifel.jpg",#"Paris"},
{#"NotreDame.jpg",#"Paris"},
{#"ArcDeTriompheParis.jpg",#"Paris"},
{#"AtomuimBrussels.jpg",#"Brussels"},
{#"MannekePis.jpg",#"Brussels"},
{#"Colosseum.jpg",#"Rome"},
{#"TreviFountainRome.jpg",#"Rome"},
{#"SagradaFamilia.jpg",#"Barcelona"},
{#"SpanishSchoolMadrid.jpg",#"Madrid"},
{#"KremlinMoskou.jpg",#"Moskou"},
{#"MermaidKopenhagen.jpg",#"Copenhagen"},
{#"MonteCarloMonaco.jpg",#"Monaco"},
{#"AcropolisAthens.jpg",#"Athens"},
{#"ParlementBudapest.jpg",#"Budapest"},
{#"BuildingReykjavik.jpg",#"Reykjavik"},
{#"StatueKiev.jpg",#"Kiev"},
{#"PortOfEuropeLissabon.jpg",#"Lisbon"},
{#"ViewSanMarino.jpg",#"San Marino"},
{#"BridgesPrague.jpg",#"Prague"},
{#"MoskeeAnkara.jpg",#"Ankara"},
{#"TowerBridgeLondon.jpg",#"London"},
{#"BigBenLondon.jpg",#"London"},
{#"LondonEyeLondon.jpg",#"London"},
{#"BrandenburgerTor.jpg",#"Berlin"},
{#"ReichstagBerlin.jpg",#"Berlin"},
{nil,nil}
};
/*
NSArray *arrEurope = #[
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"Eifel.jpg",#"Paris"],
#[#"NotreDame.jpg",#"Paris"],
#[#"ArcDeTriompheParis.jpg",#"Paris"],
#[#"AtomuimBrussels.jpg",#"Brussels"],
#[#"MannekePis.jpg",#"Brussels"],
#[#"Colosseum.jpg",#"Rome"],
#[#"TreviFountainRome.jpg",#"Rome"],
#[#"SagradaFamilia.jpg",#"Barcelona"],
#[#"SpanishSchoolMadrid.jpg",#"Madrid"],
#[#"KremlinMoskou.jpg",#"Moskou"],
#[#"MermaidKopenhagen.jpg",#"Copenhagen"],
#[#"MonteCarloMonaco.jpg",#"Monaco"],
#[#"AcropolisAthens.jpg",#"Athens"],
#[#"ParlementBudapest.jpg",#"Budapest"],
#[#"BuildingReykjavik.jpg",#"Reykjavik"],
#[#"StatueKiev.jpg",#"Kiev"],
#[#"PortOfEuropeLissabon.jpg",#"Lisbon"],
#[#"ViewSanMarino.jpg",#"San Marino"],
#[#"BridgesPrague.jpg",#"Prague"],
#[#"MoskeeAnkara.jpg",#"Ankara"],
#[#"TowerBridgeLondon.jpg",#"London"],
#[#"BigBenLondon.jpg",#"London"],
#[#"LondonEyeLondon.jpg",#"London"],
#[#"BrandenburgerTor.jpg",#"Berlin"],
#[#"ReichstagBerlin.jpg",#"Berlin"]
];
*/
//methode'start' wanneer er op de start-knop wordt gedrukt
-(IBAction)start{
[self NewQuestionEurope];
intAmountOfQuestionsAsked = 0;
//reset and show score
intScore = 0;
score.text = [NSString stringWithFormat:#"%d", intScore];
//make buttons and labels visible
Start.hidden = YES;
question.hidden = NO;
score.hidden = NO;
scoretext.hidden = NO;
imageContainer.hidden = NO;
answerA.hidden = NO;
answerB.hidden = NO;
answerC.hidden = NO;
answerD.hidden = NO;
answerA.textColor = [UIColor greenColor];
answerB.textColor = [UIColor greenColor];
answerC.textColor = [UIColor greenColor];
answerD.textColor = [UIColor greenColor];
clickButtonA.hidden = NO;
clickButtonB.hidden = NO;
clickButtonC.hidden = NO;
clickButtonD.hidden = NO;
GoodFalse.hidden = NO;
GoodFalse.text=#"Press a button to answer";
GoodFalse.textColor = [UIColor greenColor];
question.text = #"Where is this picture taken?";
}//einde start
-(IBAction)Reset{
score.text= #"gelukt";
}
-(IBAction)NewQuestionEurope{
if(intAmountOfQuestionsAsked == 19){
question.text = [#"Uw score is: "stringByAppendingString: [NSString stringWithFormat:#"%d", intScore]];
Start.hidden = NO;
question.hidden = NO;
score.hidden = YES;
scoretext.hidden = YES;
imageContainer.hidden = YES;
answerA.hidden = YES;
answerB.hidden = YES;
answerC.hidden = YES;
answerD.hidden = YES;
clickButtonA.hidden = YES;
clickButtonB.hidden = YES;
clickButtonC.hidden = YES;
clickButtonD.hidden = YES;
GoodFalse.hidden = YES;
Start.titleLabel.text = #"END";
}
else{
intAmountOfQuestionsAsked ++;
//Deze lus geeft aan intArrayEuropeLenght de waarde van hoeveel rijen de array bevat//
intArrayEuropeLenght = 0;
while (arrEurope[intArrayEuropeLenght][0] != NULL)
{
intArrayEuropeLenght++;
}
//score.text = [NSString stringWithFormat:#"%d", intScore];
scoreSpatie = [
[NSString stringWithFormat:#"%d", intScore]
stringByAppendingString:#"/"];
score.text = [
scoreSpatie
stringByAppendingString:[NSString stringWithFormat:#"%d", intAmountOfQuestionsAsked]
];
// Randoms genereren voor: 4 random antwoorden; 1 random afbeelding; een random positie om het juiste antwoord in te plaatsen
intRandomMonument = arc4random()%intArrayEuropeLenght;
intRandomAnswerA = arc4random()%intArrayEuropeLenght;
intRandomAnswerB = arc4random()%intArrayEuropeLenght;
intRandomAnswerC = arc4random()%intArrayEuropeLenght;
intRandomAnswerD = arc4random()%intArrayEuropeLenght;
intRandomAnswerPosition = arc4random()%4;
while(arrEurope[intRandomMonument][0] == #"removed"){
intRandomMonument = arc4random()%intArrayEuropeLenght;
}
//Random antwoorden maken
answerA.text = #"";
answerB.text = #"";
answerC.text = #"";
answerD.text = #"";
if(answerA.text = #""){
answerA.text = arrEurope[intRandomAnswerA][1];
}
if(answerB.text = #""){
answerB.text = arrEurope[intRandomAnswerB][1];
}
if(answerC.text = #""){
answerC.text = arrEurope[intRandomAnswerC][1];
}
if(answerD.text = #""){
answerD.text = arrEurope[intRandomAnswerD][1];
}
switch(intRandomAnswerPosition)
{
case 0: answerA.text = arrEurope[intRandomMonument][1];
break;
case 1: answerB.text = arrEurope[intRandomMonument][1];
break;
case 2: answerC.text = arrEurope[intRandomMonument][1];
break;
case 3: answerD.text = arrEurope[intRandomMonument][1];
};
//als er antwoorden hetzelfde zijn, voor de gelijke een random blijven maken tot ze niet hetzelfde zijn
if(
[answerA.text isEqualToString: answerB.text]||
[answerA.text isEqualToString: answerC.text]||
[answerA.text isEqualToString: answerD.text]
){
answerA.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerB.text isEqualToString: answerA.text]||
[answerB.text isEqualToString: answerC.text]||
[answerB.text isEqualToString: answerD.text]
){
answerB.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerC.text isEqualToString: answerA.text]||
[answerC.text isEqualToString: answerB.text]||
[answerC.text isEqualToString: answerD.text]
){
answerC.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
if(
[answerD.text isEqualToString: answerA.text]||
[answerD.text isEqualToString: answerB.text]||
[answerD.text isEqualToString: answerC.text]
){
answerD.text = arrEurope[arc4random()%intArrayEuropeLenght][1];
};
//Laat de afbeelding zien van het gekozen monument (via random gekozen)
imageContainer.image = [UIImage imageNamed: arrEurope[intRandomMonument][0]];
}
}
//hier onder zit ergens een fout want hij geeft precies random juist en fout :)
//kan zijn dat het opgelost is vanaf we niet 2x dezelfde vragen hebben maar ik denk het niet.
//press buttonA
-(IBAction)AnswerA {
if([answerA.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonB
-(IBAction)AnswerB {
if([answerB.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonC (works)
-(IBAction)AnswerC {
if([answerC.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct!";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//press buttonD
-(IBAction)AnswerD {
if([answerD.text isEqualToString: arrEurope[intRandomMonument][1]]){
GoodFalse.text = #"Correct";
GoodFalse.textColor = [UIColor greenColor];
intScore ++;
}else {
GoodFalse.text=#"Wrong!";
GoodFalse.textColor = [UIColor redColor];
}
arrEurope[intRandomMonument][0] = #"removed";
[self NewQuestionEurope];
}
//hier onder niets wijzigen
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I see 2 options:
you call the init line again...
String *arrEurope[][2] =
{
{#"Eifel.jpg",#"Paris"},
{#"NotreDame.jpg",#"Paris"},...
Or you add a third row to your array and put the "removed" (i would call it "used") parameter there. In the last case you can then just iterate over your array again and put the "removed" back to "active"
Either make a copy of arrEurope on game start and restore to it when the game is restarted or use some other array to mark a question as removed. I would personally try to use option 2.

Objects added as subview to scrollview are not showing up

I am trying to add elements to a scroll view using this code:
int missionCount;
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSDictionary *missionsDict = [responseString JSONValue];
/*NSArray *luckyNumbers = [json objectWithString:responseString error:&error];*/
NSLog(#"user Info array is: %#", missionsDict);
// NSDictionary *array = [luckyNumbers1 objectForKey:#"data"];
NSDictionary *missionsData;
missionsData = [missionsDict objectForKey:#"data"];
NSLog(#"missionsData is: %#", missionsData);
NSEnumerator *inner = [missionsData objectEnumerator];
missionsScroll.contentSize = CGSizeMake(768, 1005);
id value;
int badgeY1;
int badgeY2;
int badgeY3;
badgeY1 = 146;
badgeY2 = 188;
badgeY3 = 188;
while((value = [inner nextObject])) {
NSLog(#"value is: %#", value);
NSLog(#"progress is: %#", [value objectForKey:#"progress"]);
NSLog(#"user Info array is: %#", missionsDict);
NSLog(#"name is: %#",[value objectForKey:#"reward_definitions"]);
NSLog(#"missionsData is: %#", missionsData);
NSDictionary *moreData;
moreData = [value objectForKey:#"reward_definitions"];
NSEnumerator *inner2 = [moreData objectEnumerator];
id value2;
int badgeX;
int badgeCount;
badgeX = 0;
badgeCount = 0;
while((value2 = [inner2 nextObject])) {
UIProgressView *progressView;
progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(323, badgeY1, 372, 9)];
float progressValue;
progressValue = ([[[value objectForKey:#"progress"] objectForKey:#"earned"] floatValue] / [[[value objectForKey:#"progress"] objectForKey:#"possible"] floatValue]);
NSLog(#"progressValue is: %f", progressValue);
[progressView setProgress:progressValue];
[missionsScroll addSubview:progressView];
UILabel *missionName;
missionName = [[UILabel alloc] initWithFrame:CGRectMake(66, badgeY1, 227, 21)];
missionName.backgroundColor = [UIColor clearColor];
missionName.textColor = [UIColor whiteColor];
missionName.font = [UIFont fontWithName:#"Heiti TC" size:23.0];
missionName.text = [value objectForKey:#"name"];
[missionsScroll addSubview:missionName];
UILabel *requirementsLabel;
requirementsLabel = [[UILabel alloc] initWithFrame:CGRectMake(66, badgeY2+25, 227, 21)];
requirementsLabel.backgroundColor = [UIColor clearColor];
requirementsLabel.textColor = [UIColor whiteColor];
requirementsLabel.font = [UIFont fontWithName:#"Papyrus" size:19];
requirementsLabel.text = #"To complete you need:";
[missionsScroll addSubview:requirementsLabel];
NSLog(#"Image URL is: %#", [value2 objectForKey:#"image_url"]);
NSURL *url1 = [NSURL URLWithString: [NSString stringWithFormat:#"%#", [value2 objectForKey:#"image_url"]]];
NSData *urlData1 = [NSData dataWithContentsOfURL:url1];
UIImage *image1 = [UIImage imageWithData:urlData1];
UIImageView *badge = [[UIImageView alloc] initWithImage:image1];
[badge setFrame:CGRectMake(badgeX, badgeY2+70, 70, 70)];
[missionsScroll addSubview:badge];
[badge release];
badgeCount = badgeCount+1;
NSLog(#"badgeCount is: %i", badgeCount);
if (badgeCount == 4) {
NSLog(#"Badge Count = 4");
badgeY2 = badgeY2 +70;
badgeX = 0;
badgeCount = 0;
} else {
NSLog(#"Badge Count ≠ 4");
badgeX = badgeX +75;
}
}
NSLog(#"1st While loop done");
// NSLog(#"reward_definitions is: %#", [missionsData objectForKey:#"id"]);
// NSLog(#"Image URL is: %#", [[value objectForKey:#"reward_definitions"] objectForKey:#"image_url"]);
//if ( [array isKindOfClass:[NSDictionary class]] ) {
badgeY1 = badgeY1 +200;
badgeY2 = badgeY2 +200;
badgeY3 = badgeY3 +200;
missionCount = missionCount+1;
}
NSLog(#"While loops done");
for (int a; missionCount > 4; a = a+1) {
missionsScroll.contentSize = CGSizeMake(776, missionsScroll.contentSize.height+200);
}
Nothing is showing up in the scroll view.
It's not obvious what is happening, but first things to check are where the views are valid (not nil) and that this code is running on the main thread.
Put these in and post the results.
NSLog(#"missionsScroll: %#", (missionsScroll==nil)?#"NIL":#"OK");
NSLog(#"progressView: %#", (progressView==nil)?#"NIL":#"OK");
NSLog(#"missionName: %#", (missionName==nil)?#"NIL":#"OK");
NSLog(#"mainThread: %#", ([NSThread isMainThread])?#"OK":#"Background Thread");
Your code is quite convoluted and very difficult to read. Perhaps you could check if your complicated coordinates calculations work as expected, e.g.
NSLog(#"Frame of badge %#", NSStringFromCGRect(badge.frame));
How many times are your while loops iterating? The outer loop increases the y-position of your labels. But the labels will only be displayed at the end of the run loop / start of the next run loop. If you exit this method with the labels with a high y-value then you'll not see them. (It doesn't matter how many times you change the y-value while you're running this code. The display will only update when it's all done.)
** Correction ** You seem to be adding new views each time around your while loop. So in fact I'd expect you to have multiple copies of the subviews appearing when they finally get displayed.
(There's a lot of code to wade through here. If my answer is way off, you might get better answers, but trimming back some of the code and isolating the issue.)

wait for a method to finish before starting another

assume that i have two sequential methods, methodA and methodB (methodB is called at the end of methodA) and i need to finish completely with the process of methodA before starting methodB :
-(void)methodA {
//do some very heavy computation here
[self methodB];
}
-(void)methodB {
//this method performs some animation
}
methodA requires alot of processing power and takes time to finish while methodB has animations. The animations are starting laggy at first and im guessing this has to do with the overhead of method A. So how can i make the second method start only after the first has finished completely?
this is the actual code:
the code is very messy and unorganized. there is alot of code that has been commented out so please ingore that. I test some things sometimes and then comment them out incase i need them later.
here is what is happening: it starts with (void)checkMoves method. This method calls either one of two similar methods which are
-(void)getMovesForJourney:(int)journey withRolls:(NSArray *)rolls or
-(void) getEntryMovesForJourney:(int)journey withRolls:(NSArray *)rolls
these methods are wrappers for a long recursive process (which is most probably where the multithreading is happening).
at the end of (void)checkMoves another method -(void)analyseMoves is called. This is also a heavy process.
and finally, at the end of -(void)analyseMoves the animation method -(void)move: is called. this last method is starting with a lag.
finally at the end of -(void)move: the process will start again until no more 'moves' are available.
the methods below are not in order so please refer to the description above to know whats going on.
-(void) checkMoves {
GameScene *game = [GameScene sharedGameScene];
CCLOG(#"start");
for (Stone *stone in stones) {
if (!stone.onBoard) {
if ([game EntryAvailable]) {
[self getEntryMovesForJourney:stone.journey withRolls:[game rollsAsIntegers]];
}
}
else {
[self getMovesForJourney:stone.journey withRolls:[game rollsAsIntegers]];
}
}
CCLOG(#"finish");
[self analyseMoves];
}
-(NSMutableArray *) otherPlayerLocations {
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
Player *otherPlayer = [game playerOne];
NSMutableArray *locations = [[[NSMutableArray alloc] init] autorelease];
for (Stone *stone in otherPlayer.stones) {
if (stone.journey < 77) {
int location;
if (stone.onBoard)
location = [[board tileForATag:[self convertJourneyToTileTag:stone.journey]] bTag];
else
location = 0;
[locations addObject:[NSNumber numberWithInt:location]];
}
}
return locations;
}
-(void) analyseMoves {
if (moves.count > 0) {
NSMutableArray *killMoves = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *safeMoves = [[[NSMutableArray alloc] init] autorelease];
int mostThreatened;
float highestThreat = -1.0;
float lowestThreat = 100.0;
AIMove *safestMove;
//get kill and safe moves in seperate arrays
for (AIMove *move in moves) {
if (move.moveType == killMoveType)
[killMoves addObject:move];
else if (move.moveType == safeMoveType)
[safeMoves addObject:move];
// get highest threatened stone
//if (move.potThreat > highestThreat) {
// mostThreatened = move.journey;
// highestThreat = move.potThreat;
if (move.initThreat < lowestThreat) {
lowestThreat = move.initThreat;
safestMove = [move copy];
CCLOG(#"safest move assigned");
}
//}
}
//MOVE SELECTION:
//___________________________________
//choose best kill move
int killJourney;
if (killMoves.count > 0) {
//leave one move in killMoves with highest journey
killJourney = [[killMoves objectAtIndex:0] tileTag];
for (AIMove *killMove in killMoves) {
if (killMove.tileTag < killJourney)
[killMoves removeObject:killMove];
else
killJourney = killMove.tileTag;
}
}
//select correct move
if (killMoves.count > 0) {
[self move:[killMoves objectAtIndex:0]];
CCLOG(#"Kill move chosen");
}
else {
CCLOG(#"this is called!!!!");
CCLOG(#"safest move with initThreat: %i, potThreat: %i",safestMove.journey, safestMove.tileTag);
[self move:safestMove];
CCLOG(#"Success");
}
/*
else if (safeMoves.count > 0) {
[self move:[safeMoves objectAtIndex:0]];
CCLOG(#"safe move chosen");
}
else {
//temp random move generation
randomMove = CCRANDOM_0_1()*[moves count];
AIMove *move = [moves objectAtIndex:randomMove];
[self move:move];
CCLOG(#"Random move chosen");
}
*/
}
}
-(void) assignThreatLevel:(AIMove *)move {
NSArray *otherPlayerStones = [self otherPlayerLocations];
NSMutableArray *initThreats = [[NSMutableArray alloc] init];
NSMutableArray *potThreats = [[NSMutableArray alloc] initWithCapacity:4];
for (NSNumber *location in otherPlayerStones) {
//get threat levels for potential moves
if (move.tileTag > [location intValue]) {
int dif = move.tileTag - [location intValue];
CCLOG(#"dif: %i",dif);
//threat level conditions:
// 1 >> 5 = 70% of journey
// 6 >> 9 = 40% of journey
// 10 & 11 = 50% of journey
// 12 >> 24 = 20% of journey
// 25 && 26 = 50% of journey
// 27+ = 20% of journey
if (move.tileTag < 9) {
[initThreats addObject:[NSNumber numberWithFloat:0.0f]];
}
else if (dif >= 1 && dif <= 5) {
[initThreats addObject:[NSNumber numberWithFloat:k1to5]];
}
else if (dif >= 6 && dif <= 9) {
[initThreats addObject:[NSNumber numberWithFloat:k6to9]];
}
else if (dif == 10 || dif == 11) {
[initThreats addObject:[NSNumber numberWithFloat:k10to11]];
}
else if (dif >= 12 && dif <= 24) {
[initThreats addObject:[NSNumber numberWithFloat:k12to24]];
}
else if (dif == 25 || dif == 26) {
[initThreats addObject:[NSNumber numberWithFloat:k25to26]];
}
else if (dif > 26) {
[initThreats addObject:[NSNumber numberWithFloat:k27plus]];
}
//-------------------------------------
}
//get Threat levels for current positions
if (move.tileTag > [location intValue]) {
int dif = move.tileTag - [location intValue];
//threat level conditions:
// 1 >> 5 = 70% of journey
// 6 >> 9 = 40% of journey
// 10 & 11 = 50% of journey
// 12 >> 24 = 20% of journey
// 25 && 26 = 50% of journey
// 27+ = 20% of journey
if (move.journey < 8 || move.journey > 75)
[potThreats addObject:[NSNumber numberWithFloat:0.0f]];
else if (dif >= 1 && dif <= 5)
[potThreats addObject:[NSNumber numberWithFloat:k1to5]];
else if (dif >= 6 && dif <= 9)
[potThreats addObject:[NSNumber numberWithFloat:k6to9]];
else if (dif == 10 || dif == 11)
[potThreats addObject:[NSNumber numberWithFloat:k10to11]];
else if (dif >= 12 && dif <= 24)
[potThreats addObject:[NSNumber numberWithFloat:k12to24]];
else if (dif == 25 || dif == 26)
[potThreats addObject:[NSNumber numberWithFloat:k25to26]];
else if (dif > 26)
[potThreats addObject:[NSNumber numberWithFloat:k27plus]];
//-------------------------------------
}
}
float initThreat = 0.0f;
float potThreat = 0.0f;
for (NSNumber *number in initThreats) {
if ([number floatValue] > initThreat)
initThreat = [number floatValue];
}
for (NSNumber *number in potThreats) {
if ([number floatValue] > potThreat)
potThreat = [number floatValue];
}
move.initThreat = initThreat;
move.potThreat = potThreat;
[initThreats release];
}
-(void) move:(AIMove *)move {
CCLOG(#"Moves count: %i",[moves count]);
if ([moves count] > 0) {
BOOL isOtherStoneOnPreviousTile = NO;
int total;
if (move.tileTag > 8)
total = move.tileTag - move.journey;
else if (move.tileTag < 9 && move.journey > 8)
total = ((9-move.tileTag)+75) - move.journey;
else if (move.tileTag < 9)
total = move.tileTag - move.journey;
CCLOG(#"Total: %i",total);
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
BoardTile *tile = [[game board] tileForBTag:move.tileTag];
CCSequence *sequence;
NSMutableArray *actions = [[[NSMutableArray alloc] init] autorelease];
id delay = [CCDelayTime actionWithDuration:0.5];
[actions addObject:delay];
if (move.journey > 0) {
for (int i = 1; i < total+1; i++) {
if (move.journey+i < 76)
tile = [board tileForBTag:move.journey+i];
else
tile = [board tileForBTag:9-((move.journey+i)-75)];
id moveAction = [CCMoveTo actionWithDuration:0.2 position:tile.position];
[actions addObject:moveAction];
}
}
else {
id moveAction = [CCMoveTo actionWithDuration:0.2 position:tile.position];
[actions addObject:moveAction];
}
// id moveFunc = [CCCallFunc actionWithTarget:self selector:#selector(moveMotion)];
//id moveAction = [CCMoveTo actionWithDuration:0.3 position:tile.position];
id killFunc = [CCCallFuncND actionWithTarget:self selector:#selector(killStonesForTile:data:) data:tile];
//id callfunc = [CCCallFunc actionWithTarget:self selector:#selector(move)];
[actions addObject:killFunc];
//[actions addObject:callfunc];
sequence = [CCSequence actionMutableArray:actions];
[actions removeAllObjects];
CGPoint exitPos = ccp(exitPosition.x-(completeStones*30),exitPosition.y-(completeStones*30));
id move2 = [CCMoveTo actionWithDuration:0.2f position:exitPos];
id sequence2 = [CCSequence actions:move2, nil];
Stone *stone = [self getStoneForJourney:move.journey];
//-
//------------------------------------------
//clean tracks
for (Stone *stone in stones) {
if (stone.journey == (move.tileTag - move.journey))
isOtherStoneOnPreviousTile = YES;
}
if (!isOtherStoneOnPreviousTile) {
BoardTile *prevTile = [board tileForBTag:[self convertJourneyToTileTag:move.journey]];
prevTile.occupiedBy = 0;
}
//===========================================
//-------------------------------------------
//set stone status
if (move.tileTag < 9 && stone.crossedEntry)
stone.journey = (9 - move.tileTag) + 75;
else
stone.journey = move.tileTag;
stone.onBoard = YES;
tile.occupiedBy = player2;
if (stone.journey > 8 && !stone.crossedEntry)
stone.crossedEntry = YES;
//============================================
if (stone.journey < 84)
[stone runAction:sequence];
else {
[stone runAction:sequence2];
completeStones++;
stone.isJourneyComplete = YES;
}
CCLOG(#"Stone Journey:%i",stone.journey);
NSArray *rollTypesArray = [move rollTypes];
[self removeRollTypes:rollTypesArray];
[moves removeAllObjects];
[game updateRollResults];
[self updateMoveAvailability];
}
else {
GameScene *game = [GameScene sharedGameScene];
[moves removeAllObjects];
[game nextTurn];
[game updateRollResults];
}
}
-(Stone *)getStoneForJourney:(int)journey {
Stone *theStone;
for (Stone *stone in stones) {
if (stone.journey == journey)
theStone = stone;
}
return theStone;
}
-(void)dealloc {
[moves release];
[rollTypes release];
[results release];
[super dealloc];
}
-(void)killStonesForTile:(id)sender data:(BoardTile *)tile {
GameScene *game = [GameScene sharedGameScene];
int tileTag;
Player *otherPlayer;
if (playerNumber == player1) {
tileTag = tile.aTag;
otherPlayer = [game playerTwo];
}
else {
tileTag = tile.bTag;
otherPlayer = [game playerOne];
}
CCArray *currentStones = [otherPlayer stones];
for (Stone *stone in currentStones) {
if (!stone.isJourneyComplete) {
int journey = stone.journey;
if (tileTag == tile.aTag) {
if (journey > 0 && [self convertJourneyToTileTag:journey] == tile.bTag) {
CCLOG(#"blue stone killed");
[self returnStoneToOrigin:stone];
}
}
if (tileTag == tile.bTag) {
if (journey > 0 && [self convertJourneyToTileTag:journey] == tile.aTag) {
CCLOG(#"gold stone killed");
[self returnStoneToOrigin:stone];
}
}
}
}
}
-(void)removeRollTypes:(NSArray *)theRollTypes {
GameScene *game = [GameScene sharedGameScene];
NSMutableArray *rolls = [game rolls];
for (NSNumber *roll in theRollTypes) {
NSUInteger index = [rolls indexOfObject:[game convertIntToRoll:roll]];
CCLOG(#"rolltypes count: %i",[theRollTypes count]);
CCLOG(#"roll integer: %i",[roll intValue]);
[rolls removeObjectAtIndex:index];
}
}
#pragma mark -
#pragma mark enumerations
- (NSArray*)getSums:(NSArray*)numbers {
NSMutableArray *result = [self getSumsHelper:numbers startingFrom:0];
[result removeObjectAtIndex:0];
return result;
}
- (NSMutableArray*)getSumsHelper:(NSArray*)numbers startingFrom:(NSUInteger)index {
/* (1) */
if (index >= [numbers count])
return [NSMutableArray arrayWithObject:[NSNumber numberWithFloat:0]];
/* (2) Generate all the subsets where the `index`th element is not included */
NSMutableArray* result = [self getSumsHelper:numbers startingFrom:index+1];
// NSSortDescriptor *mySorter = [[NSSortDescriptor alloc] initWithKey:#"floatValue" ascending:YES];
// [result sortUsingDescriptors:[NSArray arrayWithObject:mySorter]];
/* (3) Add all the cases where the `index`th element is included */
NSUInteger i, n = [result count];
float element = [[numbers objectAtIndex:index] floatValue];
for (i = 0; i < n; i++) {
float element2 = [[result objectAtIndex:i] floatValue];
float sum = element+element2;
BOOL numberPresent = NO;
for (NSNumber *number in result) {
if ([number floatValue] == sum)
numberPresent = YES;
}
if (!numberPresent)
[result addObject:[NSNumber numberWithFloat:sum]];
}
return result;
}
-(NSArray *) getCombsforNumbers:(NSArray *)numbers withTarget:(int)target{
NSMutableArray *partial = [[NSMutableArray alloc] init];
[partial addObject:[NSNumber numberWithInt:0]];
[results removeAllObjects];
NSArray *result = [self getCombsHelper:numbers target:target partial:partial];
NSUInteger minCount = [[result objectAtIndex:0] count];
NSUInteger index = 0;
NSMutableArray *combArray = [result objectAtIndex:0];
for (NSMutableArray *array in result) {
if ([array count] < minCount) {
minCount = [array count];
index = [result indexOfObject:array];
combArray = array;
}
}
//remove number 0 from array
[combArray removeObject:[NSNumber numberWithInt:0]];
return combArray;
}
-(NSMutableArray *) getCombsHelper:(NSArray *)numbers target:(int)target partial:(NSMutableArray *)partial {
int s = 0;
for (NSNumber *number in partial) {
s += [number intValue];
}
if (s == target) {
[results addObject:partial];
}
if (s >= target) {
return results;
}
for (int i = 0; i < [numbers count]; i++) {
NSMutableArray *remaining = [[[NSMutableArray alloc] init] autorelease];
int n = [[numbers objectAtIndex:i] intValue];
for (int j = i+1; j<[numbers count]; j++) {
[remaining addObject:[numbers objectAtIndex:j]];
}
NSMutableArray *partialRec = [[[NSMutableArray alloc] init] autorelease];
[partialRec addObjectsFromArray:partial];
[partialRec addObject:[NSNumber numberWithInt:n]];
[self getCombsHelper:remaining target:target partial:partialRec];
}
return results;
}
-(void) getMovesForJourney:(int)journey withRolls:(NSArray *)rolls {
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
NSArray *sums = [self getSums:rolls];
for (NSNumber *number in sums) {
if ([number intValue]+journey <= 84) {
BoardTile *tile = [board tileForBTag:[self convertJourneyToTileTag:journey+[number intValue]]];
if (tile.isSafeTile) {
if (tile.occupiedBy != player1) {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
//----------------------------------
move.moveType = safeMoveType;
move.initThreat = 0.0;
CCLOG(#"move initThreat: %f",move.initThreat);
[move setRollTypes:theRollTypes];
[moves addObject:move];
}
}
else {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
//-----------------------------------
[move setRollTypes:theRollTypes];
//assing threat level
[self assignThreatLevel:move];
CCLOG(#"move initThreat: %f",move.initThreat);
//check for kill move
NSArray *otherPlayerPositions = (NSArray *)[self otherPlayerLocations];
for (NSNumber *location in otherPlayerPositions) {
if (move.tileTag == [location intValue])
move.moveType = killMoveType;
}
[moves addObject:move];
}
}
//int i = [number intValue];
//NSArray *combs = [self getCombsforNumbers:numbers withTarget:i];
}
}
-(void) getEntryMovesForJourney:(int)journey withRolls:(NSArray *)rolls {
GameScene *game = [GameScene sharedGameScene];
Board *board = [game board];
NSArray *sums = [self getSums:rolls];
for (NSNumber *number in sums) {
if ([number intValue]+journey <= 84) {
BoardTile *tile = [board tileForBTag:[self convertJourneyToTileTag:journey+[number intValue]]];
if (tile.isSafeTile) {
if (tile.occupiedBy != player1) {
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
BOOL containsEntry = NO;
for (NSNumber *rollType in theRollTypes) {
if ([rollType intValue] == 1) {
containsEntry = YES;
}
}
if (containsEntry) {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
move.moveType = safeMoveType;
move.initThreat = 0.0;
CCLOG(#"move initThreat: %f",move.initThreat);
[move setRollTypes:theRollTypes];
[moves addObject:move];
//----------------------------------
}
}
}
else {
NSArray *theRollTypes = [[self getCombsforNumbers:rolls withTarget:[number intValue]] copy];
BOOL containsEntry = NO;
for (NSNumber *rollType in theRollTypes) {
if ([rollType intValue] == 1) {
containsEntry = YES;
}
}
if (containsEntry) {
AIMove *move = [AIMove moveWithJourney:journey tileTag:tile.bTag];
[move setRollTypes:theRollTypes];
//check for kill move
NSArray *otherPlayerPositions = (NSArray *)[self otherPlayerLocations];
for (NSNumber *location in otherPlayerPositions) {
if (move.tileTag == [location intValue])
move.moveType = killMoveType;
}
//assing threat level
[self assignThreatLevel:move];
[moves addObject:move];
//Checking rolltypes, remove later
NSLog(#"%i = ",[number intValue]);
for (NSNumber *comb in theRollTypes) {
NSLog(#"%i",[comb intValue]);
}
NSLog(#"-----------");
CCLOG(#"move initThreat: %f",move.initThreat);
[move setRollTypes:theRollTypes];
[moves addObject:move];
//----------------------------------
}
}
}
}
}
Technically, methodB is called after methodA is finished. In methodA you are apparently doing things that are backgrounded, meaning that the method finishes while some tasks are performed on another thread (or scheduled on the runloop). There's nothing we can say about this unless you do share the inner workings of methodA.

Array out of bounds and slow slow app

So below is my code for my controller, which I have four of one for each tab on the tab bar. I have two issues.
I am getting an array out bounds but I can't chase it down. Am I missing something here?
Second when my app starts up it take 5 - 8 seconds before it loads the first view of the tab bar. Once it loads and I click another tab, the tab doesn't turn blue and the app sits there for 3 seconds then finally switches. I am a noob and am struggling here. I think this issue might be fixed by fetching the data in another thread or something? I am sure this controller is full of bugs.
import "AllMackTableViewController.h"
import "PostDetailViewController.h"
import "MackdabMobileAppDelegate.h"
import <QuartzCore/QuartzCore.h>
import "Post.h"
define FONT_SIZE 14.0f
define CELL_CONTENT_WIDTH 254.0f
define CELL_CONTENT_MARGIN 5.0f
#implementation AllMackTableViewController
#synthesize jsonArray;
#synthesize localJsonArray;
#synthesize postDetailViewController;
#synthesize allPostsTableView;
#synthesize fetchedResultsController, managedObjectContext;
#synthesize minuteTimer;
#synthesize regionsTimer;
pragma mark
pragma mark View lifecycle
(void)viewDidLoad {
[super viewDidLoad];
self.title = NSLocalizedString(#"Feed", #"You're Matching Posts");
UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
target:self
action:#selector(refresh)];
self.navigationItem.rightBarButtonItem = refreshButton;
allPostsTableView.delegate = self;
[refreshButton release];
[self refresh];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
(void)scrollViewDidScroll:(UIScrollView *) scrollView;
{
CGFloat scrollHeight = scrollView.contentSize.height;
CGPoint p = scrollView.contentOffset;
//NSLog(#"x = %f, y = %f", p.x, p.y);
}
(void)viewWillAppear:(BOOL)animated {
/*
Set up two timers, one that fires every minute, the other every fifteen minutes.
1/ The time displayed for each time zone must be updated every minute on the minute.
2/ Time zone data is cached. Some time zones are based on 15 minute differences from GMT, so update the cache every 15 minutes, on the "quarter".
*/
NSTimer *timer;
NSDate *date = [NSDate date];
/*
Set up a timer to update the table view every minute on the minute so that it shows the current time.
*/
NSDate *oneMinuteFromNow = [date dateByAddingTimeInterval:60];
NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit;
NSDateComponents *timerDateComponents = [calendar components:unitFlags fromDate:oneMinuteFromNow];
// Add 1 second to make sure the minute update has passed when the timer fires.
[timerDateComponents setSecond:1];
NSDate *minuteTimerDate = [calendar dateFromComponents:timerDateComponents];
timer = [[NSTimer alloc] initWithFireDate:minuteTimerDate interval:60 target:self selector:#selector(updateTime:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
self.minuteTimer = timer;
[timer release];
}
pragma mark
pragma mark Table view data source
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
// return [self.localJsonArray count];
NSLog(#"Setting numberOfRowsInSection to %i",[self.localJsonArray count]);
if ( [jsonArray count] < 9 ) {
return [self.localJsonArray count];
NSLog(#"Setting numberOfRowsInSection to %i inside of non add one.",[self.localJsonArray count]);
} else {
return [self.localJsonArray count] + 1;
}
}
(void)updateTime:(NSTimer *)timer {
/*
To display the current time, redisplay the time labels.
Don't reload the table view's data as this is unnecessarily expensive it recalculates the number of cells and the height of each item to determine the total height of the view etc. The external dimensions of the cells haven't changed, just their contents.
*/
NSArray *visibleCells = self.tableView.visibleCells;
for (PostTableCustomCellController *cell in visibleCells) {
[cell redisplay];
}
[self updateRegions];
}
(NSString *)dateDiff:(NSString *)origDate {
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setFormatterBehavior:NSDateFormatterBehavior10_4];
[df setDateFormat:#"EEE, dd MMM yy HH:mm:ss VVVV"];
NSDate *convertedDate = [df dateFromString:origDate];
[df release];
NSDate *todayDate = [NSDate date];
double ti = [convertedDate timeIntervalSinceDate:todayDate];
ti = ti * 1;
if(ti < 1) {
return #"never";
} else if (ti < 60) {
return #"less than a minute ago";
} else if (ti < 3600) {
int diff = round(ti / 60);
return [NSString stringWithFormat:#"%d minutes ago", diff];
} else if (ti < 86400) {
int diff = round(ti / 60 / 60);
return[NSString stringWithFormat:#"%d hours ago", diff];
} else if (ti < 2629743) {
int diff = round(ti / 60 / 60 / 24);
return[NSString stringWithFormat:#"%d days ago", diff];
} else {
return #"never";
}
}
(void)updateRegions {
/*
The following sets the date for the regions, hence also for the time zone wrappers. This has the sideeffect of "faulting" the time zone wrappers (see TimeZoneWrapper's setDate: method), so can be used to relieve memory pressure.
*/
NSDate *date = [NSDate date];
for (Post *post in localJsonArray) {
post.timeRemaining = [self dateDiff:post.deadline];
}
}
// Customize the appearance of table view cells.
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UILabel *distance;
UIImage *image = [UIImage imageNamed:#"imageA.png"];
static NSString *CellIdentifier = #"customCell"; // This is identifier given in IB jason set this.
PostTableCustomCellController *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (indexPath.row != [localJsonArray count] ) {
if (cell == nil) {
NSLog(#"Cell created");
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"PostTableCustomCellController" owner:nil options:nil];
for(id currentObject in nibObjects)
{
if([currentObject isKindOfClass:[PostTableCustomCellController class]])
{
cell = (PostTableCustomCellController *)currentObject;
}
}
}
Post *post = [localJsonArray objectAtIndex:indexPath.row];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy"];
//Optionally for time zone converstions
//[formatter setTimeZone:[NSTimeZone timeZoneWithName:#"..."]];
NSString *stringFromDate = [formatter stringFromDate:post.deadline];
cell.authorName.text = post.author;
cell.deadline.text = stringFromDate;
cell.budget.text = post.budget;
cell.description.text = post.description;
[[cell avatar] setImage:[UIImage imageNamed:#"butterfly.jpeg"]];
[stringFromDate release];
NSLog([NSString stringWithFormat:#"%#", post.distance]);
if([#"" isEqualToString: post.distance] || nil == post.distance) {
cell.distance.text = #"1 mi.";
}else{
cell.distance.text = #"25 mi.";
}
Post *myPost = [localJsonArray objectAtIndex:[indexPath row]];
// Might can remove these
UILabel *locationLabel = (UILabel *) [cell distance];
UITextView *postTextView = (UITextView *) [cell description];
//CGSize maximumLabelSize = CGSizeMake(254,88.0f);
NSString *text;
CGSize constraint;
CGSize size;
CGFloat height;
CGFloat realHeight;
CGSize expectedLabelSize;
text = myPost.description;
constraint = CGSizeMake(CELL_CONTENT_WIDTH (CELL_CONTENT_MARGIN * 2), 88.0f);
size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
height = MAX(size.height, 35.0f);
realHeight = height + 36.0f (10);
expectedLabelSize = [text sizeWithFont:[UIFont boldSystemFontOfSize:18.0f] constrainedToSize:CGSizeMake(252.0f, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
CGRect newFrame = postTextView.frame;
newFrame.size.height = expectedLabelSize.height;
newFrame.size.width = 252;
postTextView.frame = newFrame;
[[cell description] sizeToFit];
[[cell viewForBackground] sizeToFit];
[cell setNeedsDisplay];
}// Ok, all done for filling the normal cells, next we probaply reach the +1 index, which doesn’t contain anything yet
if ( [jsonArray count] == 9 ) { // Only call this if the array count is 25
if(indexPath.row == [localJsonArray count] ) { // Here we check if we reached the end of the index, so the +1 row
if (cell == nil) {
cell = [[[PostTableCustomCellController alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Reset previous content of the cell, I have these defined in a UITableCell subclass, change them where needed
cell.authorName.text = nil;
cell.deadline.text = nil;
cell.budget.text = nil;
cell.description.text = nil;
// Here we create the ‘Load more’ cell
UILabel *loadMore =[[UILabel alloc]initWithFrame: CGRectMake(20,0,362,100)];
loadMore.textColor = [UIColor blackColor];
loadMore.highlightedTextColor = [UIColor darkGrayColor];
loadMore.backgroundColor = [UIColor clearColor];
loadMore.font=[UIFont fontWithName:#"Verdana" size:20];
loadMore.textAlignment=UITextAlignmentCenter;
loadMore.font=[UIFont boldSystemFontOfSize:20];
loadMore.text=#"Load More..";
[cell addSubview:loadMore];
}
}
return cell;
}
(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
if (indexPath.row != [localJsonArray count] ) {
Post *myPost = [localJsonArray objectAtIndex:[indexPath row]];
NSString *text = myPost.description;
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH (CELL_CONTENT_MARGIN * 2), 88.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 35.0f);
return height + (CELL_CONTENT_MARGIN * 2) + 28.0f;
}else{
return 100.0f;
}
}
(IBAction)nextTwentyFivePlease:(NSString *)thePostID{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
self.jsonArray = [Post findNextTwentyFiveRemote:thePostID];
if (self.localJsonArray == nil) {
self.localJsonArray = [[NSMutableArray alloc]init]; // init the local array if it’s empty
}
[self.localJsonArray addObjectsFromArray:self.jsonArray];
[self.tableView reloadData];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
(IBAction)refresh {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
self.jsonArray = [Post findAllRemote];
if (self.localJsonArray == nil) {
self.localJsonArray = [[NSMutableArray alloc]init]; // init the local array if it’s empty
}
[self.localJsonArray addObjectsFromArray:self.jsonArray];
//self.localJsonArray = [Post findAllRemote];
[self.tableView reloadData];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
pragma mark
pragma mark Table view delegate
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if ( [jsonArray count] == 9 ) { // only check for the load more function if we have 25 results in the dynamic array
if (indexPath.row == [localJsonArray count] ) { // See if we reached the +1 in the results
Post *tempPost = [jsonArray objectAtIndex:indexPath.row];
NSLog('What is at tempPost');
[self nextTwentyFivePlease:tempPost.postID]; // function to load more results
}
} else {
NSInteger row = [indexPath row];
if (self.postDetailViewController == nil) {
PostDetailViewController *aPostDetail = [[PostDetailViewController alloc] initWithNibName:#"PostDetailView" bundle:nil];
self.postDetailViewController = aPostDetail;
postDetailViewController.post = [localJsonArray objectAtIndex:row];
[aPostDetail release];
}
postDetailViewController.title = [NSString stringWithFormat:#"Details"];
MackdabMobileAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.allMacksNavController pushViewController:postDetailViewController animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
}
pragma mark
pragma mark Timer set accessor methods
(void)setMinuteTimer:(NSTimer *)newTimer {
if (minuteTimer != newTimer) {
[minuteTimer invalidate];
minuteTimer = newTimer;
}
}
(void)setRegionsTimer:(NSTimer *)newTimer {
if (regionsTimer != newTimer) {
[regionsTimer invalidate];
regionsTimer = newTimer;
}
}
pragma mark
pragma mark Memory management
(void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
(void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
(void)dealloc {
[allPostsTableView release];
[postDetailViewController release];
[localJsonArray release]; // may need to remove this
[super dealloc];
}
#end
In your refresh method which is called in viewDidLoad, it appears that it is doing a bunch of network access to download some information. That would explain why it is taking so long to show your initial tab.
You'll want to do that network access in a background thread so that your UI doesn't block. Then once you've gotten the results back you can update your UI from the main thread. Something like:
- (IBAction) refresh {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[self performSelectorInBackground:#selector(refreshInBackground) withObject:nil];
}
- (void) refreshInBackground {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
self.jsonArray = [Post findAllRemote];
if (self.localJsonArray == nil) {
self.localJsonArray = [[NSMutableArray alloc]init]; // init the local array if it’s empty
}
[self.localJsonArray addObjectsFromArray:self.jsonArray];
[self performSelectorOnMainThread:#selector(refreshComplete) withObject:nil waitUntilDone:NO];
}
- (void) refreshComplete {
[self.tableView reloadData];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
EDIT: As Rob noted in the comment below, you'll want to add some kind of flag (or semaphore) to avoid firing off multiple -refresh calls at the same time. Threading and race conditions are always a tricky bit, but my goal above was just to get you moving in the right direction so that you can use background threads for your network calls.