Tyl*_*den 6 animation objective-c synchronized uiviewanimation ios
我有一个UIViewController和一个类别,用于向UIViewController添加方法.该类别中有一种方法:
@implementation UIViewController (AlertAnimationsAndModalViews)
-(void)someAddedMethod
{
UIView *someView;
//do some animation with the view that lasts 3 seconds
//remove the view and return
}
Run Code Online (Sandbox Code Playgroud)
在任何视图控制器中我都可以调用此方法
[self someAddedMethod];
Run Code Online (Sandbox Code Playgroud)
但是,我只想让这个方法一次运行一个.例如,如果我一个接一个地打两个电话
[self someAddedMethod];//call1
[self someAddedMethod];//call2
Run Code Online (Sandbox Code Playgroud)
我希望第二个电话等到第一个电话完成.我知道UIView animationWithduration ...是在一个单独的线程中运行,并且看到我无法在类别中创建iVars我真的不能使用@synchronized(someObject)..
有什么建议?
提前致谢!
该方法如下所示:
-(void)showTopBannerWithHeight:(CGFloat)height andWidth:(CGFloat)width andMessage:(NSString *)message andDuration:(CGFloat)duration
{
UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, -height, width, height)];
[self.view.superview addSubview:messageLabel];
[UIView animateWithDuration:0.5
delay:0
options: UIViewAnimationOptionBeginFromCurrentState
animations:^{
messageLabel.frame = CGRectMake(0, 0, SCREEN_WIDTH, height);
}
completion:^(BOOL finished){
[UIView animateWithDuration: 0.5
delay:duration
options: UIViewAnimationOptionBeginFromCurrentState
animations:^{
messageLabel.frame = CGRectMake(0, -height, SCREEN_WIDTH, height);
}
completion:^(BOOL finished){
[messageLabel removeFromSuperview];
}];
}];
Run Code Online (Sandbox Code Playgroud)
}
所以我从屏幕顶部显示一个"横幅",等待一段时间(CGFloat)然后将视图滑出屏幕并移除.因为这是一个类别我不能添加实例变量..所以我想要实现的是,如果进行多次调用此方法,我希望第一次调用执行而不等待,但每次调用之后,等到上次通话结束.
假设您想在上一个动画完成后开始下一个动画。这样你就可以使用一些共享NSMutableArray* _animationQueue存储:
-(void)someAddedMethod
{
NSTimeInterval duration = 3.0;
void (^animationBlock)() = ^{
//do some animations here
self.view.frame = CGRectOffset(self.view.frame, 40, 0);
};
__block void (^completionBlock)(BOOL) = ^(BOOL finished){
[_animationQueue removeObjectAtIndex:0];
if([_animationQueue count]>0) {
[UIView animateWithDuration:duration animations:_animationQueue[0] completion:completionBlock];
}
};
[_animationQueue addObject:animationBlock];
if([_animationQueue count]==1) {
[UIView animateWithDuration:duration animations:animationBlock completion:completionBlock];
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,您不需要任何@synchronized功能,因为一切都在主线程上进行。
更新:下面的代码正是您所需要的:
-(void)showTopBannerWithHeight:(CGFloat)height andWidth:(CGFloat)width andMessage:(NSString *)message andDuration:(CGFloat)duration
{
static NSMutableArray* animationQueue = nil;
if(!animationQueue) {
animationQueue = [[NSMutableArray alloc] init];
}
void (^showMessageBlock)() = ^{
UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, height)];
messageLabel.text = message;
[self.view.superview addSubview:messageLabel];
[UIView animateWithDuration: 0.5
delay:duration
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
messageLabel.frame = CGRectOffset(messageLabel.frame, 0, -height);
}
completion:^(BOOL finished){
[messageLabel removeFromSuperview];
[animationQueue removeObjectAtIndex:0];
if([animationQueue count]>0) {
void (^nextAction)() = [animationQueue objectAtIndex:0];
nextAction();
}
}];
};
[animationQueue addObject:showMessageBlock];
if([animationQueue count]==1) {
showMessageBlock();
}
}
Run Code Online (Sandbox Code Playgroud)