如何在UIScrollView缩放后重置? [英] How do I reset after a UIScrollView zoom?

查看:286
本文介绍了如何在UIScrollView缩放后重置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个图形绘制在 UIScrollView 。这是一个大 UIView 使用 CATiledLayer 的自定义子类作为其图层。

I have a Graph being drawn inside a UIScrollView. It's one large UIView using a custom subclass of CATiledLayer as its layer.

当我放大和缩小的 UIScrollView ,我想要的图形动态调整大小,当它返回图从 viewForZoomingInScrollView 。但是,图表在新的缩放级别重绘本身,并且我想将变换缩放重置为1x1,以便下次用户缩放时,变换从当前视图开始。如果我在 scrollViewDidEndZooming 中重置变换为Identity,它在模拟器中工作,但在设备上引发 EXC_BAD_ACCSES

When I zoom in and out of the UIScrollView, I want the graph to resize dynamically like it does when I return the graph from viewForZoomingInScrollView. However, the Graph redraws itself at the new zoom level, and I want to reset the transform scale to 1x1 so that the next time the user zooms, the transform starts from the current view. If I reset the transform to Identity in scrollViewDidEndZooming, it works in the simulator, but throws an EXC_BAD_ACCSES on the device.

这甚至不能在模拟器上完全解决问题,因为下次用户缩放时,变换会将自身重置为任何缩放级别,所以看起来像,如果我被放大到2x,例如,突然在4x。当我完成缩放,它以正确的比例结束,但实际的缩放动作看起来不错。

This doesn't even solve the issue entirely on the simulator either, because the next time the user zooms, the transform resets itself to whatever zoom level it was at, and so it looks like, if I was zoomed to 2x, for example, it's suddenly at 4x. When I finish the zoom, it ends up at the correct scale, but the actual act of zooming looks bad.

首先:如何允许图形重绘本身

So first: how do I allow the graph to redraw itself at the standard scale of 1x1 after zooming, and how do I have a smooth zoom throughout?

编辑:新发现
在缩放之后,错误似乎是 [CALayer retainCount]:message sent to deallocated instance

层我自己。以前,我甚至没有删除任何意见或任何东西。此错误被抛出在缩放和旋转。如果我在旋转之前删除对象,然后重新添加它,它不会抛出异常。这不是缩放的选项。

I'm never deallocating any layers myself. Before, I wasn't even deleting any views or anything. This error was being thrown on zoom and also on rotate. If I delete the object before rotation and re-add it afterward, it doesn't throw the exception. This is not an option for zooming.

推荐答案

我不能帮助你崩溃,除了告诉你检查和请确保您不是无意中在代码中某处自动释放视图或图层。我已经看到模拟器处理autoreleases的时间不同于设备(通常当线程涉及)。

I can't help you with the crashing, other than tell you to check and make sure you aren't unintentionally autoreleasing a view or layer somewhere within your code. I've seen the simulator handle the timing of autoreleases differently than on the device (most often when threads are involved).

视图缩放是一个问题与 UIScrollView 我遇到,虽然。在捏缩放事件期间, UIScrollView 将接受您在 viewForZoomingInScrollView:委托方法中指定的视图,并应用变换到它。此变换提供视图的平滑缩放,而不必每帧重绘它。在缩放操作结束时,您的委托方法 scrollViewDidEndZooming:withView:atScale:将被调用,并给您一个更高质量的渲染视图的机会新的比例因子。一般来说,建议您将视图上的转换重置为 CGAffineTransformIdentity ,然后在新尺寸范围内手动重新绘制视图。

The view scaling is an issue with UIScrollView I've run into, though. During a pinch-zooming event, UIScrollView will take the view you specified in the viewForZoomingInScrollView: delegate method and apply a transform to it. This transform provides a smooth scaling of the view without having to redraw it each frame. At the end of the zoom operation, your delegate method scrollViewDidEndZooming:withView:atScale: will be called and give you a chance to do a more high-quality rendering of your view at the new scale factor. Generally, it's suggested that you reset the transform on your view to be CGAffineTransformIdentity and then have your view manually redraw itself at the new size scale.

但是,这会导致一个问题,因为 UIScrollView 不会显示监视内容视图转换,因此在下一个缩放操作它设置转换内容视图到任何整体比例因子。由于您已在最后一个比例因子手动重新绘制视图,因此它会合并缩放,这是您看到的。

However, this causes a problem because UIScrollView doesn't appear to monitor the content view transform, so on the next zoom operation it sets the transform of the content view to whatever the overall scale factor is. Since you've manually redrawn your view at the last scale factor, it compounds the scaling, which is what you're seeing.

作为解决方法,我使用UIView我的内容视图的子类,定义了以下方法:

As a workaround, I use a UIView subclass for my content view with the following methods defined:

- (void)setTransformWithoutScaling:(CGAffineTransform)newTransform;
{
    [super setTransform:newTransform];
}

- (void)setTransform:(CGAffineTransform)newValue;
{
    [super setTransform:CGAffineTransformScale(newValue, 1.0f / previousScale, 1.0f / previousScale)];
}

其中previousScale是视图的float实例变量。我然后实现缩放委托方法如下:

where previousScale is a float instance variable of the view. I then implement the zooming delegate method as follows:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale;
{
    [contentView setTransformWithoutScaling:CGAffineTransformIdentity];
// Code to manually redraw view at new scale here
    contentView.previousScale = scale;
    scrollView.contentSize = contentView.frame.size;
}

通过这样做,发送到内容视图的变换基于视图上次重绘的比例。当捏缩放大完成时,通过绕过正常 setTransform:方法中的调整,将转换重置为1.0的比例。这似乎提供了正确的缩放行为,同时让你在缩放完成时绘制一个清晰的视图。

By doing this, the transforms sent to the content view are adjusted based on the scale at which the view was last redrawn. When the pinch-zooming is done, the transform is reset to a scale of 1.0 by bypassing the adjustment in the normal setTransform: method. This seems to provide the correct scaling behavior while letting you draw a crisp view at the completion of a zoom.

UPDATE(7/23/2010):iPhone OS 3.2和上面已经改变了关于缩放的滚动视图的行为。现在, UIScrollView 将尊重您应用于内容视图的身份转换,并且仅在中提供相对比例因子:-scrollViewDidEndZooming:withView:atScale: / code>。因此, UIView 子类的上述代码只对运行iPhone操作系统版本低于3.2的设备是必需的。

UPDATE (7/23/2010): iPhone OS 3.2 and above have changed the behavior of scroll views in regards to zooming. Now, a UIScrollView will respect the identity transform you apply to a content view and only provide the relative scale factor in -scrollViewDidEndZooming:withView:atScale:. Therefore, the above code for a UIView subclass is only necessary for devices running iPhone OS versions older than 3.2.

这篇关于如何在UIScrollView缩放后重置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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