0

我用 UIScrollView 制作了一张地图,我想在地图上放置其他小图像或按钮,并让它们在放大时位于地图上的相对位置,并且可以随时单击它们。因此,当缩小时,国家 A 上的按钮在放大时仍会在国家 A 上,而当您在放大时滚动出国家视图时会从屏幕上消失。我该怎么做呢?

4

1 回答 1

1

据我所知,您想在自己的自定义地图上放置自定义视图。并且您需要为视图保持相同的大小,但是当您滚动或缩放 imageView 时它们应该移动。您必须将视图放置到 scrollView 的超级视图并在缩放或滚动时重新计算位置:

CustomMapViewController.h:

@interface CustomMapViewController : UIViewController <UIScrollViewDelegate>
{
    UIScrollView *_scrollView;
    UIImageView *_mapImageView;

    NSArray *_customViews;
}

CustomMapViewController.m:

#import "CustomMapViewController.h"

enum {
    kAddContactButton = 1,
    kInfoDarkButton,
    kInfoLightButton,
    kLogoImage,
};

@implementation CustomMapViewController

- (void)dealloc
{
    [_scrollView release]; _scrollView = nil;
    [_mapImageView release]; _mapImageView = nil;
    [_customViews release]; _customViews = nil;
    [super dealloc];
}

- (void) loadView
{
    [super loadView];

    UIImageView *mapImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"map.png"]];

    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    scrollView.delegate = self;
    scrollView.minimumZoomScale = 0.2;
    scrollView.maximumZoomScale = 2.0;

    [scrollView addSubview:mapImageView];
    scrollView.contentSize = mapImageView.frame.size;

    [self.view addSubview:scrollView];

    _scrollView = scrollView;
    _mapImageView = mapImageView;

    // Add custom views
    UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeContactAdd];
    btn1.tag = kAddContactButton;
    [self.view addSubview:btn1];

    UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeInfoDark];
    btn2.tag = kInfoDarkButton;
    [self.view addSubview:btn2];

    UIButton *btn3 = [UIButton buttonWithType:UIButtonTypeInfoLight];
    btn3.tag = kInfoLightButton;
    [self.view addSubview:btn3];

    UIImageView *image = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"logo.png"]] autorelease];
    image.tag = kLogoImage;
    [self.view addSubview:image];

    _customViews = [[NSArray alloc] initWithObjects:btn1, btn2, btn3, image, nil];

    [self _zoomToFit];
}

- (void) _zoomToFit
{
    UIScrollView *scrollView = _scrollView;
    CGFloat contentWidth = scrollView.contentSize.width;
    CGFloat contentHeigth = scrollView.contentSize.height;
    CGFloat viewWidth = scrollView.frame.size.width;
    CGFloat viewHeight = scrollView.frame.size.height;

    CGFloat width = viewWidth / contentWidth;
    CGFloat heigth = viewHeight / contentHeigth;

    CGFloat scale = MIN(width, heigth); // to fit
    // CGFloat scale = MAX(width, heigth); // to fill

    // May be should add something like this
    if ( scale < _scrollView.minimumZoomScale ) {
        _scrollView.minimumZoomScale = scale;
    } else if ( scale > _scrollView.maximumZoomScale ) {
        _scrollView.maximumZoomScale = scale;
    }

    _scrollView.zoomScale = scale;
}
////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - Positions

- (void) _updatePositionForViews:(NSArray *)views
{
    CGFloat scale = _scrollView.zoomScale;
    CGPoint contentOffset = _scrollView.contentOffset;
    for ( UIView *view in views ) {
        CGPoint basePosition = [self _basePositionForView:view];
        [self _updatePositionForView:view scale:scale basePosition:basePosition offset:contentOffset];
    }
}

- (CGPoint) _basePositionForView:(UIView *)view
{
    switch (view.tag) {
        case kAddContactButton:
            return CGPointMake(50.0, 50.0);

        case kInfoDarkButton:
            return CGPointMake(250.0, 250.0);

        case kInfoLightButton:
            return CGPointMake(450.0, 250.0);

        case kLogoImage:
            return CGPointMake(650.0, 450.0);

        default:
            return CGPointZero;
    }
}


- (void) _updatePositionForView:(UIView *)view scale:(CGFloat)scale basePosition:(CGPoint)basePosition offset:(CGPoint)offset;
{
    CGPoint position;
    position.x = (basePosition.x * scale) - offset.x;
    position.y = (basePosition.y * scale) - offset.y;

    CGRect frame = view.frame;
    frame.origin = position;
    view.frame = frame;
}

//////////////////////////////////////////////////////////////////////////////////////
#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
    [self _updatePositionForViews:_customViews];
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [self _updatePositionForViews:_customViews];
}

- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView;
{
    return _mapImageView;
}

@end
于 2012-11-18T23:27:07.457 回答