简体   繁体   English

在不缩放叠加层的情况下缩放背景图像

[英]Zooming a background image without zooming the overlay

I'm a beginner to the iOS development, and I'm trying to display an image (a map in fact) which need to be zoomable and pannable. 我是iOS开发的初学者,我正在尝试显示一个需要可缩放和可扩展的图像(实际上是一个地图)。 My problem is that I don't know how to add an overlay which will follow the pan to always represent the same location, but won't be scaled by the zoom. 我的问题是我不知道如何添加一个叠加层,它将跟随平移线始终代表相同的位置,但不会被缩放缩放。 There will be several overlays, and each one must be clickable. 将有几个叠加层,每个叠加层必须是可点击的。

To zoom and pan the image (map), I added my UIImageView in a UIScrollView and it works great, but I have no idea how to add this feature. 为了缩放和平移图像(地图),我在UIScrollView添加了我的UIImageView并且效果很好,但我不知道如何添加此功能。

I found this thread but it is not really the same problem since his overlay is static : UIScrollview with two images - Keeping 1 image zoomable and 1 image static (fixed size) 我发现这个线程,但它不是真的相同的问题,因为他的叠加是静态的: 带有两个图像的UIScrollview - 保持1个图像可缩放和1个图像静态(固定大小)

I've developped the same application in android, and to make this work I was converting a pixel of the map in screen coordinates thanks to the transformation matrix, and I overrode the onDraw method to display it, but I don't know how to do the same on iOS, and I don't know if this is the better solution. 我在android中开发了相同的应用程序,并且为了完成这项工作,我在屏幕坐标中转换了一个像素,这要归功于转换矩阵,并且我覆盖了onDraw方法来显示它,但我不知道如何在iOS上做同样的事情,我不知道这是否是更好的解决方案。

Thanks for any help. 谢谢你的帮助。

Ok so I found a way to do it, if it can helps anybody : 好的,所以我找到了一种方法,如果它可以帮助任何人:

I added my overlay in the scrollView, with the background image (the map). 我在scrollView中添加了我的叠加层,带有背景图像(地图)。

+CustomScrollView
----> UIImageView (map)
----> OverlayImageView (overlay)

In order to zoom, the custom scrollview need a delegate with the following methods : 要进行缩放,自定义scrollview需要具有以下方法的委托:

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    //The background image with the map
    return mapView;
}

//When a zoom occurs, move the overlay
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    UIImageView* overlayView = [scroll.subviews objectAtIndex:1];
    float x;
    float y;
    float width;
    float height;

    //keep the width and height of the overlay
    width = overlayView.frame.size.width;
    height = overlayView.frame.size.height;
    //Move it to stay over the same pixel of the map, and centers it
    x = (self.overlay.point.x * scroll.zoomScale - width/2);
    y = (self.overlay.point.y * scroll.zoomScale - height/2);

    overlayView.frame = CGRectMake(x,y,width,height);
} 

With this, we are saying that the zoom only occurs on the background image, but as the overlay is in the UIScrollView , it pans with it. 有了这个,我们说缩放只发生在背景图像上,但是当叠加层在UIScrollView ,它会平移。 So the only thing we need to care is to move the Overlay when the zoom change, and we know it with the scrollViewDidZoom method. 所以我们唯一需要注意的是在缩放变化时移动Overlay,我们用scrollViewDidZoom方法知道它。

To handle the touch events, we override the touchEnded:withEvent: of CustomScrollView and we forward it to the overlay if there is only one tap. 为了处理触摸事件,我们覆盖了CustomScrollViewtouchEnded:withEvent:如果只有一个tap,我们将它转​​发到叠加层。 I don't show the OverlayImageView since it only override this same method ( toucheEnded:withEvent: ) to handle a touch on it. 我没有显示OverlayImageView因为它只覆盖了同样的方法( toucheEnded:withEvent:来处理它的触摸。

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch* touch = [touches anyObject];
    // Coordinates in map view
    CGPoint point = [touch locationInView:[self.subviews objectAtIndex:0]];

    //forward
    if(touch.tapCount == 1){
        OverlayImageView* overlayView = [self.subviews objectAtIndex:1];
        CGPoint newPoint = [touch locationInView:overlayView];

        BOOL isInside = [overlayView pointInside:newPoint withEvent:event];

        if(isInside){
            [overlayView touchesEnded:touches withEvent:event];
        }
    }
    // zoom
    else if(touch.tapCount == 2){


        if(self.zoomScale == self.maximumZoomScale){
            [self setZoomScale:[self minimumZoomScale] animated:YES];
        } else {
            CGRect zoomRect = [self zoomRectForScrollView:self withScale:self.maximumZoomScale withCenter:point];            

            [self zoomToRect:zoomRect animated:YES];
            //[self setZoomScale:[self maximumZoomScale] animated:YES];
        }

        [self setNeedsDisplay];

    }
}

Hope this will help. 希望这会有所帮助。

You can put an imageView on top as an overLay and set its userInteractionEnabled property to NO. 您可以将imageView作为overLay放在顶部,并将其userInteractionEnabled属性设置为NO。 Then you have to pan it programmatically. 然后你必须以编程方式平移它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM