3 倍缩放的 UIScrollView 与 UIView 叠加

Posted

技术标签:

【中文标题】3 倍缩放的 UIScrollView 与 UIView 叠加【英文标题】:UIScrollView at 3x zoom with UIView overlay 【发布时间】:2013-05-14 17:33:57 【问题描述】:

我有一个 UIScrollView 包含大小为 3354 x 2082 的大图像。我将 UIScrollView 缩小以显示整个图像。我正在添加这样的红色圆圈:

CGRect positionFrame = CGRectMake(500,500,5,5);
RedCircle * circleView = [[RedCircle alloc] initWithFrame:positionFrame];
[self.scrollView addSubview:circleView];

问题 - 红色圆圈在缩小 (newZoomScale = 0.305307f;) 和完全缩放 (newZoomScale = 3.0f;) 中的位置不同。

这更像是一个逻辑问题而不是语法问题。有哪位大神可以帮忙吗?

编辑:发布整个代码:

@interface MainMap ()
@property (nonatomic, strong) UIImageView *imageView;

- (void)centerScrollViewContents;
- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer;
@end

@implementation MainMap
@synthesize scrollView = _scrollView;
@synthesize imageView = _imageView;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) 
    // Custom initialization

return self;


- (void)viewDidLoad
[super viewDidLoad];

// Set up the image we want to scroll & zoom and add it to the scroll view
UIImage *image = [UIImage imageNamed:@"worldMap.jpg"];
self.imageView = [[UIImageView alloc] initWithImage:image];
self.imageView.frame = (CGRect).origin=CGPointMake(0.0f, 0.0f), .size=image.size;
[self.scrollView addSubview:self.imageView];

// Tell the scroll view the size of the contents
self.scrollView.contentSize = image.size;
//self.scrollView.scrollEnabled = NO;

UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewDoubleTapped:)];
doubleTapRecognizer.numberOfTapsRequired = 2;
doubleTapRecognizer.numberOfTouchesRequired = 1;
[self.scrollView addGestureRecognizer:doubleTapRecognizer];

UITapGestureRecognizer *twoFingerTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewTwoFingerTapped:)];
twoFingerTapRecognizer.numberOfTapsRequired = 1;
twoFingerTapRecognizer.numberOfTouchesRequired = 2;
[self.scrollView addGestureRecognizer:twoFingerTapRecognizer];


- (void)viewWillAppear:(BOOL)animated
[super viewWillAppear:animated];

// Set up the minimum & maximum zoom scales
CGRect scrollViewFrame = self.scrollView.frame;
CGFloat scaleWidth = scrollViewFrame.size.width / self.scrollView.contentSize.width;
CGFloat scaleHeight = scrollViewFrame.size.height / self.scrollView.contentSize.height;
CGFloat minScale = MIN(scaleWidth, scaleHeight);

self.scrollView.minimumZoomScale = minScale;
self.scrollView.maximumZoomScale = 3.0f;
self.scrollView.zoomScale = minScale;

[self centerScrollViewContents];


CGRect positionFrame = CGRectMake(500,500,5,5);
RedCircle * circleView = [[RedCircle alloc] initWithFrame:positionFrame];
[self.scrollView addSubview:circleView];



- (void)centerScrollViewContents
CGSize boundsSize = self.scrollView.bounds.size;
CGRect contentsFrame = self.imageView.frame;

if (contentsFrame.size.width < boundsSize.width) 
    contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
 else 
    contentsFrame.origin.x = 0.0f;


if (contentsFrame.size.height < boundsSize.height) 
    contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
 else 
    contentsFrame.origin.y = 0.0f;


self.imageView.frame = contentsFrame;


- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer
// Get the location within the image view where we tapped
CGPoint pointInView = [recognizer locationInView:self.imageView];

// Get a zoom scale that's zoomed in slightly, capped at the maximum zoom scale specified by the scroll view
CGFloat newZoomScale = 0.0f;
if(self.scrollView.zoomScale == 3.0f)

    newZoomScale = 0.305307f;
 else

    newZoomScale = 3.0f;


newZoomScale = MIN(newZoomScale, self.scrollView.maximumZoomScale);

// Figure out the rect we want to zoom to, then zoom to it
CGSize scrollViewSize = self.scrollView.bounds.size;

CGFloat w = scrollViewSize.width / newZoomScale;
CGFloat h = scrollViewSize.height / newZoomScale;
CGFloat x = pointInView.x - (w / 2.0f);
CGFloat y = pointInView.y - (h / 2.0f);

CGRect rectToZoomTo = CGRectMake(x, y, w, h);

[self.scrollView zoomToRect:rectToZoomTo animated:YES];


float scale = self.scrollView.zoomScale;
CGRect positionFrame = CGRectMake(500 * scale, 500 * scale ,50,50);
RedCircle * circleView = [[RedCircle alloc] initWithFrame:positionFrame];
[self.scrollView addSubview:circleView];


- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
// Return the view that we want to zoom
return self.imageView;


- (void)scrollViewDidZoom:(UIScrollView *)scrollView
// The scroll view has zoomed, so we need to re-center the contents
[self centerScrollViewContents];



- (void)viewDidUnload
[super viewDidUnload];
// Release any retained subviews of the main view.


- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.


@end

【问题讨论】:

【参考方案1】:

使用 UIScrollView 的 zoomScale 属性。

float scale = self.scrollView.zoomScale;
CGRect positionFrame = CGRectMake(500 * scale, 500 * scale ,5,5);

scrollViewDidZoom:委托方法中调整位置。

【讨论】:

不工作。我发布了所有代码供您参考。我也确实在委托方法中添加了您的代码,但没有任何乐趣。 双击后看不到红色圆圈。 @sangony,看起来你只是在scrollViewDidZoom 中调用centerScrollViewContents 并且没有代码可以重新调整圆圈。 我听到了,不明白,但我听到了。我绕过了 centerScrollViewContents 但问题仍然存在。对我能做什么有什么建议吗?【参考方案2】:

代替

[self.scrollView addSubview:circleView];

我应该有

[self.imageView addSubview:circleView];

这解决了我所有的问题。

【讨论】:

以上是关于3 倍缩放的 UIScrollView 与 UIView 叠加的主要内容,如果未能解决你的问题,请参考以下文章

UIscrollView 上的绘图视图需要无限缩放

在 UIScrollView 中绘制 UIBezierPath

UIImageView 与 UIScrollView 的 viewForZoomingInScrollView 同步缩放:

iPhone iOS如何在启用缩放时使UIScrollView与UIRotationGestureRecognizer一起工作?

IOS - UIScrollView 边框和缩放

实现UIScrollView的缩放 Objective-C语言