UIButton子类:自定义动画完成后调用[super touchesEnded:]

时间:2015-07-19 19:36:43

标签: ios objective-c cocoa-touch uibutton touchesended

我有一个UIButton子类,可以做一些自定义绘图和动画。这一切都很好,花花公子。

但是,我的大多数按钮都会通过超级视图调用[self dismissViewControllerAnimated]来关闭当前视图,一旦确认模型无论按钮推送实际完成了什么,我希望有一个延迟到在解除视图之前允许动画完成。

我能够轻松地为touchesEnded上的UIButton子类设置动画,然后调用[super touchesEnded],除了在解除视图之前不让我的动画完成之外,它工作正常。像这样:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    CABasicAnimation *myAnimation = [CABasicAnimation animationWithKeyPath:@"transform.foo"];
    //set up myAnimation's properties

    [self.layer addAnimation:shakeAnimation forKey:nil];
    [super touchesEnded:touches withEvent:event]; //works! but no delay
}

我创建延迟的第一次尝试是使用CATransaction,如下所示:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{   
    CABasicAnimation *myAnimation = [CABasicAnimation animationWithKeyPath:@"transform.foo"];
    //set up myAnimation's properties

    [CATransaction begin];
    [CATransaction setCompletionBlock:^{
        [super touchesEnded:touches withEvent:event]; //doesn't seem to do anything :-/
    }];
    [self.layer addAnimation:shakeAnimation forKey:nil];
    [CATransaction commit];
}

据我所知,正在执行CATransaction的completionBlock,但它没有做任何事情。

我还尝试将touchesEnded中的touches和event参数分配给属性和全局变量,然后在NSTimer调用的另一个方法中执行[super touchesEnded]。在代码执行的地方似乎也发生了同样的事情,但我对[super touchesEnded]的调用没有做任何事情。

我在网上挖了好几个小时。添加了来自UIResponder的其他触摸方法的存根,其中包含[超级触摸...]。尝试为NSTimer调用的方法设置我的全局变量的方式不同(我很可能遗漏了关于全局变量的东西......)。这个按钮是由Storyboard创建的,但我已经将类设置为我的自定义类,所以我认为UIButton的+(UIButton *)buttonWithType方法不会影响它。

我错过了什么?是否有一些我忘记的小事或是否有办法延迟从UIButton子类调用[super touchesEnded]?

1 个答案:

答案 0 :(得分:1)

我无法解决这个问题,只能找到解决办法。

我解决这个问题的最后一步是弄清楚完成块中的[super touchesEnded ...]是否在一个线程中执行,该线程与完成块之外的线程不同。 ..并且不,它们似乎都是主线程(Apple的关于CATransaction的文档确实声明它的completionBlock总是在主线程中运行。)

所以万一其他人正在反对这个问题,这是我不太优雅的解决方案:

1。)在我的UIButton子类中,我创建了一个名为containsVC的弱属性。

2.。)在每个使用自定义按钮类的单个(ugh)VC中,我必须这样做:

$( document ).ready(function() {
    //your code.
});

3.)然后在我的自定义UIButton类中,我有类似的东西:

@implemenation VCThatUsesCustomButtonsOneOfWayTooMany

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    self.firstCustomButton.containingVC = self;
    self.secondCustomButton.containingVC = self;
    self.thirdCustomButton.containingVC = self;
    ....
    self.lastCustomButton.containingVC = self;
    //you're probably better off using an IBOutletColletion and NSArray's makeObjectPerformSelector:withObject...
}

@end

4。)然后在用户当前正在与之交互的任何VC中,确保按钮完成了它应该做的任何事情(在我的情况下,它检查模型以确认相关的更改已经完成),每个按钮都必须调用[someCustomButton animateForPushDismissCurrView],然后按下按钮,然后触发实际解除视图的UIStoryboardSegue。

显然,这可以用于更深入,而不仅仅是展开,但是您需要在自定义按钮中使用额外的逻辑 - (void)animateForPush方法或完全单独的方法。

同样,如果我在这里遗漏了一些东西,我很想知道它是什么。这似乎是一个荒谬的数目,可以完成看似简单的任务。

最后,最重要的是,如果它只是在CATransaction的completionBlock中使用[super touchesEnded ...]方法,我想知道为什么。我怀疑它与线程有关,或者与Objective-C的超级关键字有关。