我有一个UIButton子类,它做一些自定义绘图和动画。这一切都工作得很好。
然而,我的大多数按钮解散当前视图通过他们的父视图调用[self解散viewcontrolleranimated]一旦它与模型确认,无论按钮按下应该完成实际上已经完成,我希望有一个延迟,以允许动画在解散视图之前完成。
我能够很容易地在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
}
我第一次尝试创建延迟是通过使用cattransaction,如下所示:
-(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];
}
,据我所知,它正在执行cattransaction的completionBlock,但它只是没有做任何事情。
我也试过分配触摸和事件参数从touchesEnded属性和全局变量,然后执行[超级touchesEnded]在另一个方法由一个NSTimer调用。同样的事情似乎发生在代码正在执行的地方,但我对[super touchesEnded]的调用没有做任何事情。
我在网上搜了好几个小时。添加了来自UIResponder的其他触摸方法的存根,它们只包含[super touches…]。尝试为NSTimer调用的方法设置我的全局变量(我很可能在全局变量方面缺少一些东西…)。这个按钮是由Storyboard创建的,但是我已经将类设置为我的自定义类,所以我不认为UIButton的+(UIButton *)buttonWithType方法会影响这个。
我错过了什么?是否有一些小事情我忘记了,或者只是没有办法延迟调用[超级touchesEnded]从UIButton子类?
我无法解决这个问题,只能找到一个绕过它的方法。
我在解决这个问题的最后一次尝试是弄清楚是否[super touchesEnded…在完成块内执行的线程与在完成块外执行的线程不同……不,它们似乎都是主线程(Apple关于cattransaction的文档确实声明它的completionBlock总是在主线程中运行)。
所以,如果有人不同意,我有一个不太优雅的解决方案:
1)。在UIButton的子类中,我创建了一个弱属性containingVC。
2)。在每个使用自定义按钮类的VC中,我必须这样做:
@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
3)。然后在我的自定义UIButton类中我有这样的东西:
-(void)animateForPushDismissCurrView
{
CAAnimation *buttonAnimation = ...make animation
[CATransaction begin];
[CATransaction setCompletionBlock:^{
[self.containingVC performSegueWithIdentifier:@"segueID" sender:self.containingVC];
}];
[self.layer addAnimation:buttonAnimation forKey:nil];
[CATransaction commit];
}
4)。然后在任何VC中,用户目前正在与之交互,在确保按钮已经完成了它应该做的任何事情(在我的情况下,它检查模型以确认相关的更改),每个按钮必须调用[someCustomButton animateForPushDismissCurrView],然后动画按钮按下,然后触发UIStoryboardSegue,实际上解散视图。
显然,这可以更深入地工作,而不仅仅是展开,但你需要在自定义按钮的-(void)animateForPush方法或一个单独的方法中添加额外的逻辑。
如果我在这里遗漏了什么,我很想知道是什么。为了完成一项看似简单的任务,这似乎是一个荒谬的数字。最后,也是最重要的,如果它不能与[super touchesEnded…]方法在cattransaction的completionBlock,我想知道为什么。我怀疑这与线程或Objective-C的超级关键字的怪异有关。