I have an array of annotations.
NSArray *annotations = [mapView annotations];
I can show or hide them by looping through the array.
for (i=0; i<[annotations count]; i++)
{
annotation = (AddressAnnotation*)[annotations objectAtIndex:i];
[[mapView viewForAnnotation:annotation] setHidden:YES];
}
But is there any way to do that without looping?
We can add annotations by the method
- (void)addAnnotations:(NSArray *)annotations;
Also we can remove the annotations by like below:
- (void)removeAnnotations:(NSArray *)annotations;
But i cant find out any method to show or hide an array of annotations :(
not sure if you solved this, but in MapKit you can use
NSArray *annotationsOnMap = mapView.annotations;
if ([annotationsOnMap count] > 0) {
[mapView removeAnnotations:annotationsOnMap];
}
Related
So I'm using iCarousel to display some images in my app and I need a label to show current image index when I scroll (e.g. "3/10"). This is my code:
- (void)carouselCurrentItemIndexDidChange:(iCarousel *)carousel
{
NSLog(#"index: %i", currentItemIndex);
imageNumber.text = #"";
imageNumber.text = [[[imageNumber.text
stringByAppendingString:[NSString stringWithFormat:#"%i", currentItemIndex+1]]
stringByAppendingString:#"/" ]
stringByAppendingString:[NSString stringWithFormat:#"%i", carousel.numberOfItems]];
}
Although this method is being called whenever I scroll, the currentItemIndex never change. It remains 0.
Does anybody know why is this or can suggest another way I can update the index when the user scrolls the carousel?
First, you need to have
carousel.currentItemIndex
and not currentItemIndex.
Second, you may also implement carouselDidEndScrollingAnimation: delegate and check for the index:
- (void)carouselDidEndScrollingAnimation:(iCarousel *)carousel
{
NSLog(#"index: %i", carousel.currentItemIndex);
}
I am using a UICollectionView with a custom layout that lays out cells in a grid format. There can be well over 50 rows and 50 columns. Scrolling occurs both vertically and horizontally. Currently, I am doing all of the layout setup in prepareLayout and storing it in arrays:
- (void)prepareLayout {
NSMutableArray *newLayoutInfo = [[NSMutableArray alloc] init];
NSMutableArray *newLinearLayoutInfor = [[NSMutableArray alloc] init];
NSInteger sectionCount = [self.collectionView numberOfSections];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
self.heightForRows = [delegate collectionViewHeightForAllRows];
self.totalWidthsForRows = [[NSMutableArray alloc] init];
for (int i = 0; i < sectionCount; i++) {
[self.totalWidthsForRows addObject:[NSNumber numberWithInt:0]];
}
for (NSInteger section = 0; section < sectionCount; section++) {
NSMutableArray *cellLayoutInfo = [[NSMutableArray alloc] init];
NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
for (NSInteger item = 0; item < itemCount; item++) {
indexPath = [NSIndexPath indexPathForItem:item inSection:section];
UICollectionViewLayoutAttributes *itemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
itemAttributes.frame = [self frameForCellAtIndexPath:indexPath];
[cellLayoutInfo addObject:itemAttributes];
[newLinearLayoutInfor addObject:itemAttributes];
}
[newLayoutInfo addObject:cellLayoutInfo];
}
self.layoutInfo = newLayoutInfo;
self.linearLayoutInfo = newLinearLayoutInfor;
}
Then in layoutAttributesForElementsInRect I have:
- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *rows = [self.linearLayoutInfo filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UICollectionViewLayoutAttributes *evaluatedObject, NSDictionary *bindings) {
return CGRectIntersectsRect(rect, [evaluatedObject frame]);
}]];
This works okay, but it is laggy and jumpy when I have over 50 columns and 50 rows. The problem I now have is that I must set
-(BOOL)shouldInvalidateLayoutForBoundsChange {
return YES;
}
This makes it prepare the entire layout every time the bounds change, which, needless to say, has a huge impact on performance and you can barely scroll. The cells consist of just text with an opaque background, so there is no issue there.
I am sure I am not doing this right and that there must be a better way. Thanks for the help in advance.
In custom flow layout I do this and it seems to help:
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return !(CGSizeEqualToSize(newBounds.size, self.collectionView.frame.size));
}
-(BOOL)shouldInvalidateLayoutForBoundsChange {
return YES;
}
Causes the layout to do prepareLayout() every time it scrolls, which means anything of heavy computing in prepare will lead to a laggy practice, so one possible direction to solve this is to check what's really taking much time. One possibility is what's inside
for (NSInteger section = 0; section < sectionCount; section++)
{
// generate attributes ...
}
in order to generate attributes for the layout. Every time it scrolls, every time this generalization reruns, so that it impacts on the scroll appear to be jumpy and clumsy. So in order to solve this issue, or at least sort out that this is not the really trouble, I suggest setting a flag in this layout algorithm, say, isScrolling, standing for the situation where the layout needs to prepare. Every time in prepareLayout() check the flag, if it is YES, then we'll know there's no need to do for loop to regenerate all the attributes, which alreay exsit ever since the first time the layout is initialised.
ok--I understand now. Here's what I recommend: create 3 collection views... one for the column headers (where each cell is column header), one for the row leaders (each cell = 1 row leader) and one collection view for your cells. Then when the scroll position of any collection view is changed by the user, update the scroll positions for the other 2 collection views as appropriate.
I am trying to make a method in which the data source for my NATableView is cleared, but I cannot figure out how to do this anywhere.
Here is the code I am using to send an array called final to my table view.
// I want to clear it here before filling it again.
for (int i = 0; i < [final count]; i++) {
[myArrayController addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:final[i], #"File Name", nil]];
}
Any help would be great!
If you are using an NSMutableArray and myArrayController is your mutable array you want to call
[myArrayController removeAllObjects];
before you enter the for-loop.
Can I write code like the following? It seems to work, but I want to make sure that it is allowed/safe:
// menu is a NSMenu*
for (NSMenuItem *item in [menu itemArray]) {
if (some condition) {
[menu removeItem:item];
}
}
If it doesn't immediately throw an exception (as modifying an array directly when enumerating it does) then it's probably okay. NSMenu may be giving you a copy of its internal array (assuming it's keeping its items in an NSArray).
For guaranteed safety, however, you might like to do this in two steps. Create another array to hold the items for removal, then enumerate that and do the removal:
NSMutableArray * itemsToRemove = [NSMutableArray array];
for( NSMenuItem *item in [menu itemArray] ){
if( some condition ){
[itemsToRemove addObject:item];
}
}
for( NSMenuItem * item in itemsToRemove ){
[menu removeItem:item];
}
Just for the record:
if you care about memory and dont want to create a secondary array use this:
for (int i = menu.itemArray.count - 1; i >= 0; --i)
{
if( some condition for index i ){
[menu removeItemAtIndex:i];
}
}
Could someone point out what is wrong with my for loop? I'm trying to loop thru UIImageViews to make all hidden. All the subviews are UIImageViews. Thanks in advance.
int i;
int num = [[self myView]subviews];
for (i=0; i<num; i++)
{
UIImageView *currentView = [self.tabber.subviews objectAtIndex:i];
currentView.hidden = YES;
}
Ian, Martin and Aram pointed out the error in your code.
I want to point out another way of iterating through an array: Fast Enumeration
for (UIView *view in [self.myView subviews])
{
view.hidden = YES;
}
It has several advantages over C-style counting variable based iterating, such as
cleaner code — no counter variable needed.
Enumeration is “safe”—the enumerator has a mutation guard so that if you attempt to modify the collection during enumeration, an exception is raised.
[[self myView] subviews] refers to the list of subviews, not the number of them. What you want is
for(i = 0; i < [[[self myView] subviews] count]; i++)
A UIView's subview property returns an NSArray.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html
[[self myView]subviews]; returns a NSArray of views, not an int.