views:

1138

answers:

4

To all,

I have a UIScrollView which has a UIImageView. I want to show pins on this imageView. When I add pins as subviews of the ImageView everything is great except for when you zoom the scale transform happens on the pins also. I don't want this behavior and want my pins to stay the same.

So I choose to add the Pins to another view which sits on top of the ImageView and is also a subview of the UIScrollView. The idea here if you will imagine is to have a layer which hovers over the map and won't scale yet show pins over where I plot them.

The pin when added to the layer view don't cale if the ImageView scales. However the issue then bceomes the position of the pins doesn't match the original origin x/y as the ImageView has had a scale transform.

Basically this is a custom map of a place with Pins. I am trying to have the Pins float over and not zoom in and out over my ImageView yet remember where I placed them when the zoom happens.

Some code

scrollView = [[UIScrollView alloc] initWithFrame:viewRect];

scrollView.delegate = self;
scrollView.pagingEnabled = NO;
scrollView.scrollsToTop = NO;
[scrollView setBackgroundColor:[UIColor clearColor]];
scrollView.clipsToBounds = YES; // default is NO, we want to restrict drawing within our scrollview
scrollView.bounces = YES;
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;

imageViewMap = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.png"]];

imageViewMap.userInteractionEnabled = YES;

viewRect = CGRectMake(0,0,imageViewMap.image.size.width,imageViewMap.image.size.height);

//viewRect = CGRectMake(0,0,2976,3928);

[scrollView addSubview:imageViewMap];

[scrollView setContentSize:CGSizeMake(viewRect.size.width, viewRect.size.height)];

iconsView = [[UIView alloc] initWithFrame:imageViewMap.frame];

[scrollView addSubview:iconsView];

Code to add Pin later on some event.

[iconsView addSubview:pinIcon];

I am stuck in trying tp figure out how to to get my pins to hover on the map without moving when the scale happens.

Thanks

+1  A: 

To all,

So one thing I have implemented which hasn't solved my issue but I think its down the right path is from this article.

http://stackoverflow.com/questions/716923/anchor-a-uiview

I have my view hierarchy as follows.

UIScrollView
- UIImageView (map image)
- IconsView (layer image to hold icons)

The next step I need to solve is to keep my pins added to IconsView anchored in the same spot when the UIImageVew is being zoomed in and out.

I had a for loop that went through all of my pins which are Subviews of IconsView and updated their Origin X and Y. This was in the UIScrollView delegates's scrollViewDidScroll method.

The problem was this technique has horrible performance on the device as when there are a lot of pins on the map there is too much processing that needs to happen.

Koppo
A: 

A few recommendations:

1) You will notice in the Google Maps application that it limits the number of pins that it tries to display by default. It will only display the results closest the the center point even if there are more possible matches.

2) You could briefly hide the pins during any scroll or pinch action so that the interface remains responsive and redraw them the moment the image view stops moving.

3) If you must display a large number of pins and animate them, you might also look into using CABasicAnimations to animate the pins and the backdrop at the same time, transforming the pins position using the same math that transforms the backdrops scale. This might smooth the display by spreading animations more smoothly and running them at a fairly low level, but introduces other challenges and limitations.

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Animation_Types_Timing/Articles/PropertyAnimations.html#//apple_ref/doc/uid/TP40006672-SW1

Barney

Barney Mattox
A: 

I have the same problem and I find the idea of manually correcting the pin's location not very pretty. Then, I rather draw my pins onto the view returned in the delegate function viewForZoomingInScrollView: and update the subview (markers) size after zooming has finished.

However, it nags me that this is possible in the Google Maps App, but I can't recreate it.

One more thing: Can anyone explain me the behaviour exhibitet when I add subviews to the UIScrollView that are not the 'viewForZoomingInScrollView'..? For example:

UIImageView* marker = [[UIImageView alloc] initWithImage: myMarkerImage];
[marker setCenter: CGPointMake(250,150)];
[myScrollView addSubview: marker];

This seems to work fine for the initial view and when panning. When zooming, those subviews are not resized, which is actually what we are aiming for, but the problem is that the UIView frame origin is moved across the scroll view in some rather weird way. It appears that if one zooms in, the marker.frame.size.origin is always moving towards the upper left corner (superview's (0,0)), creating the impression that we are actually zooming out. This is also weird, because the "zoom center" should always be at the center of the screen, no? Well, I don't get it for now.

bump. ;)

Efrain
A: 

Hi!

I wonder if there is a way to rollback the transformation at the time of the zooming... (with the

Another solution could be not to transform but to really resize the zoomed UIImageView. (or scrollview) But unfortunately I don't know how...

Maybe somebody could help us! I really need to get this issue fixed!

It's a bit sad that Apple doesn't allow us to build in the same functionality for our applications. Everything would be much better and more consistent.

Jelle

Fousa