在我的iPad应用程序Universal Combat Log(新布局分支)中,我有一个UIView子类(UCLLineChartView),它包含一个UIScrollView,而scrollview又包含另一个UIView子类(ChartView)。 ChartView有多个子图层,每个子图层对应于已添加到图表的每行数据。 UCLLineChartView绘制轴和标记。这些视图/图层的内容完全是自定义绘制的,没有使用库存视图(例如UIImageView)。
我遇到缩放问题 - 它将ChartView缩放为图像,这使得绘制的线条变得模糊和拉伸。我希望线条保持清晰,最好是在用户进行缩放时,但是经过3天的黑客攻击后,我无法让它工作。
如果我覆盖ChartView上的setTransform以从变换中获取比例因子但不调用[super setTransform]
,则scrollview的zoomScale保持为1.我尝试保留给定的变换并覆盖transform方法以返回它。我尝试通过更改ChartView的中心和边界来复制setTransform的效果但是我无法使行为完全正确并且它似乎仍然没有影响scrollview的zoomScale。似乎scrollview的zoomScale取决于setTransform的效果,但我无法确定如何。
非常感谢任何协助。
答案 0 :(得分:1)
您需要做的是更新chartView的contentScaleFactor
。您可以通过在scrollViewDidEndZooming:withView:atScale:
或scrollViewDidZoom:
中添加以下代码来实现此目的。
CGFloat newScale = scrollView.zoomScale * [[UIScreen mainScreen] scale];
[self.chartView setContentScaleFactor:newScale];
答案 1 :(得分:0)
我已经找到了一个解决我的问题的方法,这个解决方案并不太严重。在您的UIScrollViewDelegate中:
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
[_contentView beginZoom];
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
CGSize size = scrollView.bounds.size;
CGPoint contentOffset = _scrollView.contentOffset;
CGFloat newScale = _contentView.scale;
newScale = MAX(newScale, kMinZoomScale);
newScale = MIN(newScale, kMaxZoomScale);
[_scrollView setZoomScale:1.0 animated:NO];
_scrollView.minimumZoomScale = kMinZoomScale / newScale;
_scrollView.maximumZoomScale = kMaxZoomScale / newScale;
_contentView.scale = newScale;
CGSize newContentSize = CGSizeMake(size.width * newScale, size.height);
_contentView.frame = CGRectMake(0, 0, newContentSize.width, newContentSize.height);
_scrollView.contentSize = newContentSize;
[_scrollView setContentOffset:contentOffset animated:NO];
[_contentView updateForNewSize];
[_contentView setNeedsDisplay];
}
在内容视图中,声明一个scale属性和以下方法:
- (void)beginZoom
{
_sizeAtZoomStart = CGSizeApplyAffineTransform(self.frame.size, CGAffineTransformMakeScale(1/self.scale, 1));
_scaleAtZoomStart = self.scale;
}
- (void)setTransform:(CGAffineTransform)transform
{
self.scale = _scaleAtZoomStart * transform.a;
self.frame = CGRectMake(0, 0, _sizeAtZoomStart.width * self.scale, _sizeAtZoomStart.height);
[self updateForNewSize];
[self setNeedsDisplay];
}
如果您的内容视图使用子图层,则需要通过将以下内容添加到子图层的委托来禁用其隐式动画:
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event
{
// prevent animation of the individual layers so that zooming doesn't cause weird jitter
return (id<CAAction>)[NSNull null];
}
这里的基本思想是被覆盖的setTransform使用转换矩阵中的比例因子来计算内容视图的新比例因子,然后相应地调整内容视图的大小。 scrollview会自动调整内容偏移量以使内容视图居中。
scrollViewDidEndZooming代码保持缩放范围。
例如,在旋转设备时,处理调整滚动视图的大小还有其他复杂性。