iPhone UIView动画禁用UIButton子视图

7
所以,我在按钮和动画方面遇到了问题。基本上,我正在使用UIView动画来动画化一个视图,同时还尝试监听视图内的按钮点击。该视图与按钮一样大,实际上是UIImageView的子类,并带有按钮下方的图像。该视图是放置在用户交互启用和裁剪启用的容器视图中的子视图。所有动画和按钮处理都在此UIImageView子类中完成,而startFloating消息根据需要从单独的类发送。
如果我不进行动画,buttonTapped:消息会被正确发送,但在动画期间不会发送。我还尝试实现touchesEnded方法,但行为相同。
UIImageView子类init(我将按钮填充为颜色,以便可以看到框架是否正确设置):
- (id)initWithImage:(UIImage *)image {
    self = [super initWithImage:image];
    if (self != nil) {
        // ...stuffs

        UIButton *tapBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        tapBtn.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
        [tapBtn addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
        tapBtn.backgroundColor = [UIColor cyanColor];
        [self addSubview:tapBtn];

        self.userInteractionEnabled = YES;
    }
    return self;
}

动画方法,用于启动动画(如果我不调用此方法,按钮将正常工作):

- (void)startFloating {
    [UIView beginAnimations:@"floating" context:nil];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    [UIView setAnimationDuration:10.0f];
    self.frame = CGRectMake(self.frame.origin.x, -self.frame.size.height, self.frame.size.width, self.frame.size.height);
    [UIView commitAnimations];
}

因此,要明确:

  • 使用UIView动画有效地禁用了按钮。
  • 禁用动画会使按钮正常工作。
  • 按钮在屏幕上的大小和位置正确,并且可以正确地随着视图移动。
3个回答

21

这解决了问题:

[UIView animateWithDuration:20 delay: 0.0 options: UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
  ...

1
UIViewAnimationOptionAllowUserInteraction 是我所需的。谢谢! - buildsucceeded

8

这个动画只是为了好看。但实际移动视图的速度比动画慢。当动画开始时,按钮已经到达目标点。你只是看到一个视图/按钮移动的电影。

如果你想在动画期间使按钮可点击,你需要自己创建动画。


嗯,在经过一些测试后,我认为你是正确的。虽然这似乎相当令人不安,并违反了对动画的期望。当你说“自己制作动画”时,你是指NSTimer风格的动画吗?此外,我假设实现touches系列方法会展示相同的行为? - bensnider
所以,是的,使用NSTimer动画,我能够以这种方式使用按钮。谢谢。 - bensnider
你也可以自己进行触摸跟踪,而不依赖于按钮。这仍然需要一些手动动画,但可能会为交互提供更好的结果。 - axiixc

5

我的代码在每个块中执行一个大型动画,导致出现了同样的问题。我采用了一种基于NSTimer的解决方案,就像上面建议的那样,它确实可以解决问题...但是移动效果不平滑(除非在每个定时器事件触发时插入动画)。

所以,既然必须进行动画处理,我找到了一种无需计时器的解决方案。它仅对短距离进行动画处理,因此按钮点击仍然准确,仅有一个小误差,在我的情况下在UI中几乎不会被注意到,并且可以根据参数减小。

请注意,任何时候的误差都是 < 15.0,可以根据您的动画速度要求减少以提高精度。您还可以缩短持续时间以提高速度。

- (void)conveyComplete:(UIView*)v
{
    [self convey:v delay:0];
}

- (void)convey:(UIView*)v delay:(int)nDelay
{
    [UIView animateWithDuration:.5 
                          delay:nDelay
                        options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)  
                     animations: ^
                    {
                        CGRect rPos = v.frame; 
                        rPos.origin.x -= 15.0;
                        v.frame = rPos;
                    }
                    completion: ^(BOOL finished)
                    {
                        [self conveyComplete:v];
                    }];

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接