UIScrollView-自定义地图-防止地图上的标记子视图随地图缩放 [英] UIScrollView - Custom Map - Prevent marker subview on map from scaling with map

查看:147
本文介绍了UIScrollView-自定义地图-防止地图上的标记子视图随地图缩放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有限区域的自定义地图,并将其设置为正确显示用户的位置.该地图是UIScrollView中一个1600像素的正方形图像.

I have a custom map of a limited area, and have it set up to correctly show the users' location. The map is a 1600px square image within a UIScrollView.

我有一个十字准线图像来显示用户的当前位置,在zoomScale 1.0时它是所需的大小.当我捏住并缩放scrollView时,十字线会随之缩放.我希望子视图在屏幕上保持相同大小.

I have a crosshair image to show the current location of the user, which at zoomScale 1.0 is the desired size. When I pinch and zoom the scrollView, the crosshair scales with it. I would like to have the subview remain the same size on screen.

我至今无法找到任何信息,什么是最好的方法?

I haven't been able to find any information on this, what would be the best way to go about this?

如果有什么我可以为您提供帮助的答案,请告诉我.

If there is anything I can provide you with to help the answer, please let me know.

非常感谢!

编辑-

进一步研究了这个问题,我尝试使用UIScrollViewDelegate方法- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale来获取标记的当前中心和大小,然后进行调整,但这仅在缩放结束时缩放.我希望在用户缩放时让标记保持相同的大小.

Having looked in to this further, there is a UIScrollViewDelegate method - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale which I tried using to take the marker's current center and size, then adjust, but this only scales at the end of the zoom. I would prefer to have the marker remain the same size while the user is zooming.

编辑2-

Cake在下面提供了一个很好的答案,但是我无法按照我想象的那样实现.

Cake has provided a great answer below, but I haven't been able to implement this in the way I imagined it would be.

我将UIImageView用作占位符,并将alpha设置为0.该占位符相对于地图移动以显示用户位置.这按我预期的那样运行.不幸的是,它随地图调整大小,因为它是地图的子视图(因此它保持在原位).

I have the UIImageView as a placeholder, with alpha set to 0. This placeholder moves around relative to the map to show the user location. This operates as I expect it to. Unfortunately, this resizes with the map, as it is a subview of the map (so it stays in place).

根据Cake的以下回答,我创建了非缩放十字线图像,并将其作为同级子视图添加到了滚动视图中.一旦Cake指出了数学,就可以很简单地为十字准线找到新的框架:

Taking Cake's below answer, I have created the non-scaling crosshair image, and added it as a sibling subview to the scrollview. The maths, once Cake had pointed them out, were quite simple to get the new frame for the crosshair:

    CGPoint ULPC = userLocationPlaceholder.center;
    float zs = scrollView.zoomScale;
    CGRect newFrame = CGRectMake(((ULPC.x * zs) - scrollView.contentOffset.x) - 20, ((ULPC.y * zs) - scrollView.contentOffset.y) - 20, 40, 40);

图像宽40点.这完全匹配中心.

Where the image is 40points wide. This matches the centers perfectly.

我现在出现的问题是我无法使十字准线图像保持锁定在占位符上.

The problem I now have is that I cannot get the crosshair image to stay locked to the placeholder.

我曾经尝试使用自调用动画:

I have tried using a self calling animation as such:

-(void)animeUserLocationAttachment
{
[UIView animateWithDuration:0.05 
                      delay:0 
                    options:(UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveLinear )
                 animations:^{
                     userLocationDotContainer.frame = newFrame;
               } completion:^(BOOL finished){
                     // Call self
                     [self animateUserLocationAttachment];
                 }];
}

一旦我开始滚动/缩放,这将锁定动画,以便十字准线就位,直到我释放滚动/缩放,然后它会正确更新其位置.

As soon as I start scrolling/zooming, this locks the animation so that the crosshair just sits in place until I release the scrolling/zooming, then it correctly updates it's location.

有什么办法可以解决这个问题,或者可以应用其他方法吗?

Is there any way I can get around this, or an alternative method I can apply?

非常感谢

编辑3-

我已经接受了Cake的回答,因为它涵盖了问题的90%.除了他的答案,我还实现了ScrollViewDelegate方法scrollViewWillBeginDragging:scrollViewWillBeginDecelerating:来缩放占位符,以匹配十字准线相对于地图的当前大小,显示占位符(即地图图像的子视图)并隐藏十字线图像.委托方法scrollviewWillBeginZooming:withView:不显示占位符,因为它随地图缩放.如Cake所建议,我将对此问题提出一个新问题.

I've re-accepted Cake's answer as it covers 90% of the issue. Further to his answer I have implemented the ScrollViewDelegate methods scrollViewWillBeginDragging: andscrollViewWillBeginDecelerating: to scale the placeholder to match the current size of the crosshair relative to the map, show the placeholder (that is a subview of the map image) and hide the crosshair image. The delegate method scrollviewWillBeginZooming:withView: does not show the placeholder because it scales with the map. As Cake recommends, I'll make a new question for this issue.

对应的方法(scrollViewDidEndZooming:withView:atScale:scrollViewDidEndDragging:willDecelerate:和-scrollViewDidEndDecelerating:`)都隐藏了占位符,并重新显示了十字准线.

The counterpart methods (scrollViewDidEndZooming:withView:atScale:, scrollViewDidEndDragging:willDecelerate: and -scrollViewDidEndDecelerating:`) all hide the placeholder, and re-show the crosshair.

推荐答案

创建另一个与包含滚动视图的视图或视图控制器关联的十字线图像.然后,使该图像始终对齐到您已有的十字线图像的中心.然后,隐藏您的原始十字准线图像.然后,您可以避免让scrollview缩放未关联的十字准线,并且它应该保持相同的大小.

Create another crosshair image that's associated with the view or view controller that contains the scrollview. Then have this one always snap to the center of the crosshair image you already have. Then, hide your original crosshair image. Then you can avoid having the scrollview scale the disassociated crosshair, and it should stay the same size.

相对坐标系

可可触摸中的每个视图都有一个框架属性,该属性具有起点.为了将一个视图拥有的对象相对于另一视图正确放置,您要做的就是找出它们的原点之间的差异.如果一个视图是另一个视图的子视图,那么这并不困难.

Each view in cocoa touch has a frame property that has an origin. In order to position an object owned by one view properly relative to another view, all you have to do is figure out the differences in their origins. If one view is a subview of another, then this isn't too difficult.

  • 获取容器视图的原点
  • 获取子视图在容器视图内部的位置
  • 获取子视图的来源
  • 计算原点位置的差异
  • 获取要重叠的对象的位置(相对于子视图)
  • 计算要重叠的对象相对于容器视图的位置
  • 将十字准线移至该位置

这篇关于UIScrollView-自定义地图-防止地图上的标记子视图随地图缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆