为UIScrollView实现自定义缩放

时间:2009-10-07 13:38:40

标签: iphone cocoa-touch uiscrollview

我有一个UIScrollView,要求在缩放时,contentSize.height应该保持不变。从200x100放大应该会导致新的contentSize为400x100而不是400x200。我想在用户缩放时做自己的绘图。

我认为我不能使用UIScrollView的正常缩放行为来实现这一点,所以我试图自己动手。 (我可以让它做它的事情,然后在-scrollViewDidEndZooming:withView:atScale:被调用时重绘我的内容,但这不会很漂亮)。

目前我正在继承UIScrollView并尝试在屏幕上有两根手指时进行自己的缩放:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if ([touches count] != 2) {
        [super touchesMoved:touches withEvent:event];
    } else {
     // do my own stuff
    }
}

我认为通过覆盖touchesBegan:withEvent:,touchesMoved:withEvent:,touchesEnded:withEvent:和touchesCancelled:withEvent:以这种方式应该有效,但事实并非如此。

之前尝试失败的尝试是在滚动视图顶部放置一个透明视图,并将我不感兴趣的内容发送到滚动视图:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if ([touches count] != 2) {
        [self.theScrollView touchesMoved:touches withEvent:event];
    } else {
     // do my own stuff
    }
}

任何帮助都将不胜感激。

谢谢, 托马斯

3 个答案:

答案 0 :(得分:3)

如果您尝试在缩放缩放事件的每一帧上重绘内容,则在缩放过程中可能无法保持良好的性能。我建议采用让UIScrollView缩放图形的缩放版本的方法,然后在缩放结束时将内容重绘为-scrollViewDidEndZooming:withView:atScale:delegate方法。这就是我在我的应用程序中所做的,它最终运行得很好。

在缩放结束时,有一些技巧可以正确调整内容视图的大小,我在this answer中对此进行了描述。基本上,您需要截取转换设置到内容视图,以便在重绘内容时将其设置为比例因子1。您还需要跟踪该比例因子,因为UIScrollView没有,并使用该比例因子来调整UIScrollView尝试通过后续缩放操作应用于内容视图的转换。

您可以使用此技术的修改来强制在缩放期间重绘您的内容,但在我的测试中,这最终太过于不稳定而无法提供良好的用户体验。

答案 1 :(得分:0)

我不确定你的意思是什么:

  

我认为这是压倒一切的   的touchesBegan:withEvent:,   touchesMoved:withEvent:,   touchesEnded:withEvent:和   touchesCancelled:withEvent:在此   方式应该有效,但事实并非如此。

你没有参加活动吗?您应该收到这些事件,但我认为您的if语句中存在一个逻辑错误,可能是因为它无法正常工作。

if ([touches count] != 2)

这是一个问题,因为两次触摸恰好同时发生的可能性很低。您希望能够在触摸独立发生时以及用户握住手指时移动另一个手指。在这些场景(这是常见的)中,您可能只能在该NSSet中进行一次触摸,即使另一个仍然有效。

正确处理触摸的解决方案是记住一些关于哪些触摸进来和哪些触摸留下的事情。请记住,UITouch的地址在触摸生命周期内不会改变,因此您可以安全地比较地址,以确保您仍然处理与以前相同的触摸,并跟踪它的生命周期。

如果您没有收到触摸事件,那么完全是另一个问题,您可能需要设置multiTouchEnabled:YES

答案 2 :(得分:0)

我正在尝试做同样的事情,我真的希望能够在缩放时进行重绘。在scrollViewDidEndZooming的最后修复它:withView:atScale还不够好。

我这样做的方法是在viewForZoomingInScrollView中传递一个虚拟视图:并读取这个虚拟视图的高度,并将实际内容视图上的帧设置为我想要的任何内容。因为框架发生了变化,这意味着每次都会调用drawRect。在模拟器上看起来很好,我只画了几行。但我实际上并没有拥有一台设备,所以我无法正确测试它。

同样在你已经获得的代码中,你有touchesBegan:withEvent:但是你转发到super touchesMoved:withEvent:而不是touchesBegan:withEvent: