1

我一直在尝试在 UIScrollView 中获取 UIView 的转换后的 CGRect。如果我不放大它就可以正常工作,但是一旦我放大,新的 CGRect 就会发生变化。这是让我接近的代码:

CGFloat zoomScale = (scrollView.zoomScale);    
CGRect newRect = [self.view convertRect:widgetView.frame fromView:scrollView];
CGPoint newPoint = [self.view convertPoint:widgetView.center fromView:scrollView];

//  Increase the size of the CGRect by multiplying by the zoomScale
CGSize newSize = CGSizeMake(newRect.size.width * zoomScale, newRect.size.height * zoomScale);
//  Subtract the offset of the UIScrollView for proper positioning
CGPoint newCenter = CGPointMake(newPoint.x - scrollView.contentOffset.x, newPoint.y - scrollView.contentOffset.y);

//  Create rect with the proper width/height (x and y set by center)
newRect = CGRectMake(0, 0, newSize.width, newSize.height);    

[self.view addSubview:widgetView];

widgetView.frame = newRect;
widgetView.center = newCenter;

我相当确定我的问题在于 zoomScale - 我可能应该根据 zoomScale 值修改 x 和 y 坐标。不过,到目前为止,我所做的一切都没有成功。

4

2 回答 2

10

我在 iOS 开发论坛上收到了来自用户 Brian2012 的以下回答:

我做了什么:

  1. 创建了一个覆盖视图控制器主视图的 UIScrollView。
  2. 在滚动视图中放置一个桌面视图(标准 UIView)。桌面的原点在 0,0 并且大小比滚动视图大,所以我可以滚动而不需要先缩放。
  3. 将一些小部件视图 (UIImageView) 放入不同位置的桌面视图中。
  4. 将滚动视图的 contentSize 设置为桌面视图的大小。
  5. 实现 viewForZoomingInScrollView 以将桌面视图作为要滚动的视图返回。
  6. 将 NSLogs 放入 scrollViewDidZoom 以打印出桌面视图的框架和其中一个小部件视图。

我发现了什么:

  1. 小部件框架永远不会改变我设置的初始值。因此,例如,如果一个小部件从位置 108、108 开始,大小为 64x64,则无论缩放或滚动,帧总是报告为 108,108,64,64。
  2. 桌面框架原点永远不会改变。我在滚动视图中将桌面的原点设置为 0,0,无论缩放或滚动,原点总是报告为 0,0。
  3. 唯一改变的是桌面视图的框架大小,大小只是原始大小乘以滚动视图的缩放比例。

结论:

要确定小部件相对于视图控制器主视图的坐标系的位置,您需要自己进行数学计算。在这种情况下,convertRect 方法没有任何用处。这里有一些代码可以尝试

- (CGRect)computePositionForWidget:(UIView *)widgetView fromView:(UIScrollView *)scrollView
{
    CGRect frame;
    float  scale;

    scale = scrollView.zoomScale;

    // compute the widget size based on the zoom scale
    frame.size.width  = widgetView.frame.size.width  * scale;
    frame.size.height = widgetView.frame.size.height * scale;

    // compute the widget position based on the zoom scale and contentOffset
    frame.origin.x = widgetView.frame.origin.x * scale - scrollView.contentOffset.x + scrollView.frame.origin.x;
    frame.origin.y = widgetView.frame.origin.y * scale - scrollView.contentOffset.y + scrollView.frame.origin.y;

    // return the widget coordinates in the coordinate system of the view that contains the scroll view
    return( frame );
}
于 2012-05-07T13:15:55.560 回答
0

我也有类似的问题,我用不同的技巧解决了它。我在一个临时变量中捕获缩放比例,并将scrollView的缩放比例设置为最小值(1.0),然后使用convertRect()计算我的帧并再次设置原始缩放比例

CGFloat actualZoomScal = self.baseVideoView.zoomScale;
CGPoint actualOffset = self.baseVideoView.contentOffset;

self.baseVideoView.zoomScale = 1.0;
CGRect iFrame = [[RGLayout layout] rectToPixels:[self recordingIndicatorFrame]];
self.recordIndicator =  [[RiscoRecordingIndicatorView alloc] initWithFrame:[self convertRect:iFrame fromView:self.previewView]];
[self addSubview:self.recordIndicator] ;
[self bringSubviewToFront:self.recordIndicator] ;
self.baseVideoView.zoomScale = actualZoomScal;
self.baseVideoView.contentOffset = actualOffset;
于 2021-12-17T09:24:29.283 回答