在不缩放叠加层的情况下缩放背景图像 [英] Zooming a background image without zooming the overlay

查看:102
本文介绍了在不缩放叠加层的情况下缩放背景图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是iOS开发的初学者,我正在尝试显示一个需要可缩放和可扩展的图像(实际上是一个地图)。我的问题是我不知道如何添加一个叠加层,它将跟随平移点始终表示相同的位置,但不会被缩放缩放。将有几个叠加层,每个叠加层必须是可点击的。



要放大并平移图像(地图),我添加了 UIImageView UIScrollView 中,效果很好,但我不知道如何添加此功能。



<我找到了这个帖子,但由于他的叠加层是静态的,所以它不是同一个问题:
带有两个图像的UIScrollview - 保持1个图像可缩放,1个图像静态(固定大小)



我在android中开发了相同的应用程序,为了完成这项工作,我通过转换矩阵在屏幕坐标中转换地图的像素,并且我覆盖了onDraw方法来显示它,但我不知道知道如何在iOS上做同样的事情,我不知道这是否是更好的解决方案。



感谢您的帮助。

解决方案

好的,所以我找到了一种方法,如果它可以帮助任何人:



我在scrollView中添加了我的叠加层,背景图片(地图) 。

  + CustomScrollView 
----> UIImageView(地图)
----> OverlayImageView(overlay)

为了缩放,自定义scrollview需要一个具有以下方法的委托:

   - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
//带有地图$ b的背景图片$ b返回mapView;
}

//当发生缩放时,移动叠加层
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
UIImageView * overlayView = [scroll。 subviews objectAtIndex:1];
浮动x;
浮动y;
浮动宽度;
浮动高度;

//保持叠加的宽度和高度
width = overlayView.frame.size.width;
height = overlayView.frame.size.height;
//移动它以保持在地图的同一像素上,并将其居中于
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);
}

有了这个,我们说缩放只发生在背景图像上,但由于叠加层位于 UIScrollView 中,因此它会平移。所以我们唯一需要注意的是在缩放变化时移动Overlay,我们用 scrollViewDidZoom 方法知道它。



要处理触摸事件,我们覆盖 touchEnded:withEvent: CustomScrollView ,我们转发它如果只有一个点击,则到叠加层。我没有显示 OverlayImageView 因为它只覆盖了同样的方法( toucheEnded:withEvent:)来处理触摸在它上面。

   - (void)touchesEnded:(NSSet *)触及withEvent:(UIEvent *)事件{
UITouch * touch = [触及anyObject];
//地图视图中的坐标
CGPoint point = [touch locationInView:[self.subviews objectAtIndex:0]];

//转发
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];

}
}

希望这会有所帮助。


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. 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.

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)

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.

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).

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

In order to zoom, the custom scrollview need a delegate with the following methods :

- (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. 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.

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. I don't show the OverlayImageView since it only override this same method (toucheEnded:withEvent:) to handle a touch on it.

- (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.

这篇关于在不缩放叠加层的情况下缩放背景图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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