4

在 iOS 7 中,Apple 似乎改变了手势识别器的行为方式。以 UIPinchGestureRecognizer 为例。如果我在 UIGestureRecognizerStateChanged 中进行缓慢的重绘操作,这在旧版本的 iOS 下可以正常工作,但在较新的版本中,我的重绘通常不会在另一个 StateChanged 更新再次调用捏合手势之前呈现到屏幕上,并且再次调用慢速绘图操作。在系统使用我对视图的更改实际更新屏幕的可见部分之前,这种情况会反复发生很多次。

我发现一种解决方案是调用:

[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];

每当我收到 UIGestureRecognizerStateChanged 事件时。这样,每次完成时,绘图都会在屏幕上呈现。但是仍然存在“事件滞后”的问题,即一系列捏合事件排队,这样即使在我停止捏合屏幕很长时间后,图像也会继续缩放。

我的问题是是否有办法“刷新”排队的捏事件,所以每当我收到 UIGestureRecognizerStateChanged 事件时,我可以进行缓慢的绘图操作,然后刷新所有其他捏事件,因此只有最近的一个被处理。有谁知道这是否可能?我想我可以构建一个系统来查看 UIGestureRecognizerStateChanged 事件的时间,并抛出与最近重绘太接近的事件,但这似乎是一个 hack。

- (void) handleGlobalPinchGesture:(UIPinchGestureRecognizer*)_pinchGesture
{
    if (  _pinchGesture.state == UIGestureRecognizerStateBegan )
    {
       // stuff
    return;
    }

    if ( _pinchGesture.state == UIGestureRecognizerStateEnded || _pinchGesture.state == UIGestureRecognizerStateCancelled )
    {
       // end stuff
        return;
    }

    if (_pinchGesture.state == UIGestureRecognizerStateChanged )
    {
    doSlowRedrawingOperationHere();
    }
}
4

2 回答 2

1

我不认为这是手势识别器的问题,我在移动转换后的视图时遇到了同样的问题。我已经解决了,通过添加到视图 drawRect 方法,并在更改视图中心之前调用 -(void)setNeedsDisplay 方法: 在视图中:

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
}

在手势识别器的动作中:

[CATransaction begin];
[CATransaction setValue:@(YES) forKey:kCATransactionDisableActions];

_destinationIndicatorView.center = center;
[self.frameView setNeedsDisplay];
self.frameView.center = center;

[CATransaction commit];

这个对我有用。

于 2015-10-14T11:33:44.677 回答
0

我从来没有找到“刷新”这些事件的方法,但我确实找到了一个“hack”,可以确保每个渲染都反映在屏幕上,因此用户可以实时看到你的手势动作,即使这样的重绘操作很慢. 我的解决方案是致电:

[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];

“给操作系统时间”在屏幕上进行重绘。我在手势识别器回调中执行此操作,并且仅在 iOS 7 或更高版本上运行。

必须将上述调用添加到所有手势识别器的回调中(在呈现新内容之后)。希望这对某人有帮助!

太糟糕了,如果您想要良好的用户体验,当您的渲染速度较慢时,iOS 7 目前似乎需要这种“黑客”作为对手势的直接响应。

于 2014-06-27T00:47:25.707 回答