UIScrollView ImageView 顶部有针脚
我有一个 UIScrollView
,它有一个 UIImageView
。我想在这个imageView
上显示图钉。当我将图钉添加为 ImageView 的子视图时,一切都很好,除了缩放时图钉上也会发生比例变换。我不希望出现这种行为,并希望我的引脚保持不变。
因此,我选择将 Pins 添加到另一个视图,该视图位于 ImageView 之上,也是 UIScrollView
的子视图。如果您能想象,这里的想法是有一个图层悬停在地图上,并且不会缩放,但会在我绘制它们的位置显示图钉。
如果 ImageView
缩放,则添加到图层视图时的图钉不会缩放。然而,问题就变成了引脚的位置与原始原点 x/y 不匹配,因为 ImageView 进行了缩放变换。
基本上,这是带有图钉的地点的自定义地图。我试图让 Pins 漂浮在上面,而不是在 ImageView 上放大和缩小,但记住缩放发生时我将它们放置在哪里。
一些代码:
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];
稍后在某些事件中添加 Pin 图的代码。
[iconsView addSubview:pinIcon];
我一直在尝试弄清楚如何让我的图钉在比例发生时悬停在地图上而不移动。
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 becomes 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我喜欢您将所有引脚保留在专用于引脚的视图(iconsView)中的想法,但我决定将它们添加为您所谓的 imageViewMap 的子视图。
将 QuartzCore.framework 文件导入到您的项目中。
调用您的视图控制器 MyViewController。
// 依此类推,
我假设您有一个 pin 视图或一个名为 DropPinViewController 的视图控制器。如果你只是使用图像,它可以是 UIImageView,但我的引脚有标签,所以我使用了 xib。引脚应该指向 xib 的底部中心,因为我们要在那里放置一个锚点。
在 MyViewController 的 viewDidLoad 中,将 pin 视图添加为 imageView 的子视图。将 imageView 作为子视图添加到滚动视图中。设置scrollView的内容大小。
使用这些委托方法:
I like your idea of keeping all the pins in a view dedicated to pins (iconsView), but I decided to just add them as subviews of what you called imageViewMap.
Import the QuartzCore.framework file to your project.
Call your view controller MyViewController.
// and so on
I'll assume you have a pin view or a view controller called DropPinViewController. If you're just using an image, it can be a UIImageView, but my pins have labels, so I used a xib. The pin should point to the bottom center of the xib because we're going to put an anchor point there.
In your viewDidLoad of your MyViewController, add your pin views as subviews of imageView. Add the imageView as a subview to the scrollView. Set the content size of scrollView.
Use these delegate methods:
因此,我已经实现的一件事并没有解决我的问题,但我认为它是正确的,来自这篇文章。
锚定 UIView
我的视图层次结构如下。
我需要解决的下一步是当
UIImageView
放大和缩小时,将添加到IconsView
的图钉固定在同一位置。我有一个 for 循环,它遍历了所有作为
IconsView
的子视图的引脚,并更新了它们的原点 X 和 Y。这是在UIScrollView
代表的scrollViewDidScroll< /代码> 方法。
问题是这种技术在设备上的性能很糟糕,因为当地图上有很多引脚时,需要进行太多的处理。
So one thing I have implemented which hasn't solved my issue but I think it's down the right path is from this article.
Anchor a UIView
I have my view hierarchy as follows.
The next step I need to solve is to keep my pins added to
IconsView
anchored in the same spot when theUIImageView
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 theUIScrollView
delegates'sscrollViewDidScroll
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.
一些建议:
1) 您会注意到,在 Google 地图应用程序中,它限制了默认情况下尝试显示的图钉数量。即使有更多可能的匹配,它也只会显示最接近中心点的结果。
2) 您可以在任何滚动或捏合操作期间短暂隐藏图钉,以便界面保持响应并在图像视图停止移动时重新绘制它们。
3) 如果您必须显示大量引脚并为其设置动画,您还可以考虑使用 CABasicAnimations 同时为引脚和背景设置动画,使用与转换背景比例相同的数学方法来转换引脚位置。这可以通过更平滑地传播动画并在相当低的级别上运行它们来平滑显示,但会带来其他挑战和限制。
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Animation_Types_Timing/Articles/PropertyAnimations.html#//apple_ref/doc/uid/TP40006672-SW1
巴尼
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
我有同样的问题,我发现手动纠正引脚位置的想法不太好。然后,我宁愿将图钉绘制到委托函数
viewForZoomingInScrollView:
返回的视图上,并在缩放完成后更新子视图(标记)大小。然而,它让我烦恼,这在 Google 地图应用程序中是可能的,但我无法重新创建它。
还有一件事:
当我向 UIScrollView 添加不是“viewForZoomingInScrollView”的子视图时,任何人都可以解释一下行为表现吗?例如:
这对于初始视图和平移时似乎效果很好。缩放时,这些子视图不会调整大小,这实际上是我们的目标,但问题是 UIView 框架原点以某种相当奇怪的方式在滚动视图上移动。看起来,如果放大,
marker.frame.size.origin
总是向左上角(超级视图的 (0,0))移动,给人一种我们实际上正在缩小的印象。这也很奇怪,因为“缩放中心”应该始终位于屏幕的中心,不是吗?嗯,我暂时不明白。撞。 ;)
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:
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. ;)
感谢大卫·布劳恩。除了我必须注释掉的一行之外,您的代码可以正常工作。我的项目涉及有一个 UIScrollView,然后是顶部的 UIImageView,显示地图,最后,在感应到双击手势后固定代码所在的位置(按钮)。您的代码帮助我解释了缩放比例。但限制是,当我捏合缩放时,每个引脚不会“粘”到我双击的绘图的特定部分。当我注释掉这一行时,我偶然发现了解决方案:
//[dropPinView.layer setAnchorPoint:CGPointMake(0.5, 1)];
我没有完全理解,但我的代码现在可以工作了!我希望其他人能从我的经验中受益。谢谢大卫!
Thanks to David Braun. Your code works except for one line that I had to comment out. My project involved having a UIScrollView, then a UIImageView on top that shows a map, then lastly, pins (buttons) that the code positions after sensing a double tap gesture. Your code helped me account for the zoom scale. The limitation though was that when I pinch to zoom, each pin does not "stick" to the specific part of the drawing where I double tapped. I stumbled on the solution when I commented out this line:
//[dropPinView.layer setAnchorPoint:CGPointMake(0.5, 1)];
I don't have the complete understanding but my code now works! I hope others will benefit from my experience. Thanks David!