remove Annotation removes random amount of annotations at a time - iphone

I've got this code to erase an annotations (pins) in my mkmapview without erasing my blue dot (userLocation). The problem is that it erasing the pins I've added in seemingly random numbers. when it's called through an IBAction it removes the first 5 then click again it removes the next 3, then the next 2, then the last one.
When pressed I need it to remove that latest pin...etc. etc.
for (int i = 0;
i < [mapView.annotations count];
i++
)
{ if ([[mapView.annotations objectAtIndex:i] isKindOfClass:[MyAnnotation class]])
{
[mapView removeAnnotation:[mapView.annotations objectAtIndex:i]];
}
}

The problem is that you are modifying the annotation collection while iterating over it. At every execution of the loop, the loop's termination condition [mapView.annotations count] changes its value. This will lead to unforeseen behavior. You should
either put all annotations you want to remove into an empty mutable array inside the loop an then call removeAnnotations: with this array as a parameter after you exit the loop,
or count down from the annotation with the highest index to 0.

Use this code
NSInteger *counter = [mapView.annotations count];
for (int i = 0; i < counter; i++ )
{
if ([[mapView.annotations objectAtIndex:i] isKindOfClass:[MyAnnotation class]])
{
[mapView removeAnnotation:[mapView.annotations objectAtIndex:i]];
}
}

Related

How can I increase numeric part of property name in for() loop?

I've 10 pan recognisers and want to assign to class property.
How can I increase numeric part of property name in for() loop?
for (int i=0; i < [_myArray count]; i++)
{
myClassInstance.recognizer = pangesture + i ?? // doesn't work of course. but how??
}
It's not fantastic form — definitely follow Caleb's comments wherever possible — but if you're really backed into a corner:
for(int i = 0; i < [_myArray count]; i++)
{
NSString *nameOfProperty = [NSString stringWithFormat:#"pangesture%d", i];
UIPanGestureRecognizer *recogniser = [self valueForKey:nameOfProperty];
}
That's using key-value coding; IBOutlets are necessarily KVC compliant or there'd be no way to load the NIB.
I've 10 pan recognisers and want to assign to class property. How can
I increase numeric part of property name in for() loop?
I'm not sure I understand your question fully, but assuming that you've got 10 gesture recognizers named g1 through g10 that you want to assign to 10 objects using a loop, a good approach would be to put those 10 gesture recognizers into an array and then make the assignment using the current index:
NSArray *recognizers = #[g1, g2, g3, g4, g5, g6, g7, g8, g9, g10];
if ([recognizers count < [_myArray count]) {
NSLog("Houston, we have a problem! Not enough gesture recognizers to go around.");
}
for (int i=0; i < [_myArray count]; i++)
{
myClassInstance.recognizer = recognizers[i]; // note the fancy "new" array access syntax!
}
If you're not allocating the gesture recognizers individually, then you can just create one each time though the loop:
for (MyClass *instance in _myArray) {
instance.recognizer = [[UIGestureRecognizer alloc] init...];
}

NSNumber stores zero value instead of the correct numeric value

I developing a simple calculator iPhone application. Just for practicing purpose. I have an IBAction method that stores the digits that the user entered. The whole concept is that the calculator app piles up pending oprations so the user can perform multiple actions and the screen shows the result the following way: 1 + 2 - 4 + 10 = X. So i have two NSMutableArray that stores NSNumber numbers and the operator actions. When the user clicks an operator button, a new array element created for the new number. When the users entering the digits, the last array element is updating itself until an operator button is pressed.
The problem is that every array element is zero. Inside the method it stores the corrent value when i set it, but when the method is executed and called again it contins nothing but zeros instead of the entered numbers. The NSNumber objects are present, the array contains every number, but every number is 0.
Here is the method:
// Processing digit buttons
- (IBAction)clickDigit: (UIButton *) sender {
double currentNumber = [[numbers lastObject] doubleValue];
// Get the digit
double digit = sender.tag;
// Do nothing when the currentNumber and the digit both zero
if(currentNumber == 0 && digit == 0) {
return;
}
// When currentNumber is zero, override the value
if(currentNumber == 0) {
currentNumber = digit;
[numbers removeLastObject];
[numbers addObject: [NSNumber numberWithDouble: currentNumber ]];
// Else, add the digit to currentNumber
} else {
currentNumber = currentNumber * 10 + digit;
[numbers removeLastObject];
[numbers addObject: [NSNumber numberWithDouble: currentNumber ]];
}
// Update the screen
[self updateDisplay];
}
I have no clue what's wrong. Any suggestions?
Thanks in advance
UPDATE: it turns out that the clickClear method is automatically called after each button press. It sets the value zero. I linked the full source code below this post in the comment section. The only question is: why this method called? What calls this method?
UPDATE2: with The Saad's help i managed to solve this problem. Thanks to everyone! :)
The only possible way you get this problem is if sender.tag == 0 all the time. So you should definitely check that. My point here is that there is not other possible scenario that produces those symptoms, so it has to be it.
ok got it,
one thing here is that first check your sender's tag, either by braekpoint or by NSLog in click Digit method, i guess tags never gets up than zero, and hence the last object in array will always be zero, further, place nslog or breakpoint on all places where you are adding object to array.
in interface.
#property(nonatomic, retain) NSMutableArray* numberArray;
in implementation,
#synthesize numberArray = _numberArray;
in dealloc
[_numberArray release];
ok now next thing is to make an array in init which is
NSMutableArray* arr = [NSMutableArray alloc] init];
self.numberArray = arr;
[arr release];
[self.numberArray addObject:[NSNumber numberWithDouble:0]];

ReloadTable crashes app

This code causes the app to crash! I'm looping through a dictionary and everything logs out fine. It works when i write -1 in the for loop but not otherwise,
-(void)updateProjectTimes {
for(int i = 0; i < [projectsTable numberOfRowsInSection:0]-1; i++) {
NSString *currentValue = [[[projects objectForKey:#"activeProjects"] objectAtIndex:i] objectForKey:#"timepassed"];
NSString *finishValue = [[[projects objectForKey:#"activeProjects"] objectAtIndex:i] objectForKey:#"timeleft"];
if([currentValue intValue] < [finishValue intValue]) {
[[[projects objectForKey:#"activeProjects"] objectAtIndex:i] setObject:[NSString stringWithFormat:#"%d", ([currentValue intValue] + 1)] forKey:#"timepassed"];
} else {
[(NSMutableArray *)[projects objectForKey:#"activeProjects"] removeObjectAtIndex:i];
if([[projects objectForKey:#"activeProjects"] count] == 0) {
[projectTimer invalidate];
projectTimer = nil;
}
}
//[projectsTable reloadData]; works if i put it here!
}
[projectsTable reloadData]; //<- But not here!! :(
}
I assume you are wokring with tableView. Apparently you are modifing the data source of your tableView. When you remove an object from the data source, you have to adjust your tableView as well. Meaning either call reloadData, or call [tableView deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation].
The reason your app doesn't crash if you put -1, could be -- perhaps -- because there is only on item that matches the [currentValue intValue] < [finishValue intValue] condition, so that if you go through [projectsTable numberOfRowsInSection:0]-1, after removing that object, numberOfRowsInSection matches the count of projectsTable.
But it is good only for one cycle. When the next cycle happens, in the if...loop, you app crashes again, unless you include the [projectsTable reloadData] in the same if...loop.
While the reloadData method works just fine, but if you are simply removing a row, or adding a row to your table by adding or removing objects, its better to use deleteRowsAtIndexPaths or insertRowsAtIndexPaths methods. There will be less overhead and work for your app, and would make it smoother and faster.
The bottom line, to make your code work, right after [(NSMutableArray *)[projects objectForKey:#"activeProjects"] removeObjectAtIndex:i]; remove the corresponding object from your tableView by calling deleteRowsAtIndexPaths.
Alternatively, you can also use beginUpdates and endUpdates. For a complete reference, refer to http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableView_Class/Reference/Reference.html
Hope it helps.

How to show values form custome object in iphone app

I have custom object and I have stored my values in Array. but I am bit stuck to show objects values form array. My code definition is here.
for (int i = 0; i < 20; i++)
{
Person *myPerson = [[Person alloc] init];
myPerson.name = #"Brian";
myPerson.age = [NSNumber numberWithInteger:23];
[myArray addObject:myPerson];
[myPerson release];
}
Now I want to show all 20 values which is stored in Array (name and age of person).
How will I show that values?
There are many different ways of showing the customers depending on what you want.
1. Print to the console
If you just want to print them out to the console, you can use:
for (int i = 0; i < 20; i++)
{
Person *thisPerson = [myArray objectAtIndex:i];
NSLog(#"%# has an age of %d", thisPerson.name, thisPerson.age);
}
additionally, you can use Fast Enumerators to neaten things up:
for (Person *thisPerson in myArray)
{
NSLog(#"%# has an age of %d", thisPerson.name, thisPerson.age);
}
2. Showing in a table view
You'll need a UITableView with an instance of UITableViewController that conforms to the UITableViewDataSource protocol.
This tutorial gives you an excellent walkthrough:
http://www.icodeblog.com/2008/08/08/iphone-programming-tutorial-populating-uitableview-with-an-nsarray/
If neither of these solutions suits, please provide more information about what you're trying to achieve.

equaling indexPathForRow with UItextField

i am trying to implement something that user can insert an number then program show me the row number but i little bit confusing , i would be grateful if you help me , here is my code :
for(int i = 0; i < myTextField.text; i++) {
[myScrollTable selectRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0 ] animated:YES scrollPosition:UITableViewScrollPositionTop];
the compiler shows me a Warning and app crashes what can i do to equal my UtextField with indexPathForRow ?
warning alert: comparison between pointer and integer
You need to convert the textfield value to an int. That's what the compiler is warning you about.
for(int i = 0; i < [myTextField.text intValue]; i++) { ...
Not sure why you're using a loop if you only want to scroll to the row. Use scrollToRowAtIndexPath:atScrollPosition:animated: (Reference Doc)1