美文网首页
2014.04.26

2014.04.26

作者: 尘世书童 | 来源:发表于2017-04-26 07:56 被阅读6次

    发布页面动画

    发布.gif

    1.该动画有回弹效果,因此使用POP框架里的POPSpringAnimation,分别改变每个子控件的frame即可.

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 让控制器的view不能被点击
        self.view.userInteractionEnabled = NO;
        
        // 数据
        NSArray *images = @[@"publish-video", @"publish-picture", @"publish-text", @"publish-audio", @"publish-review", @"publish-offline"];
        NSArray *titles = @[@"发视频", @"发图片", @"发段子", @"发声音", @"审帖", @"离线下载"];
        
        // 中间的6个按钮
        int maxCols = 3;
        CGFloat buttonW = 72;
        CGFloat buttonH = buttonW + 30;
        CGFloat buttonStartY = (KScreenH - 2 * buttonH) * 0.5;
        CGFloat buttonStartX = 20;
        CGFloat xMargin = (KScreenW - 2 * buttonStartX - maxCols * buttonW) / (maxCols - 1);
        for (int i = 0; i<images.count; i++) {
            LXXVerticalButton *button = [[LXXVerticalButton alloc] init];
            button.tag = i;
            [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
            [self.view addSubview:button];
            // 设置内容
            button.titleLabel.font = [UIFont systemFontOfSize:14];
            [button setTitle:titles[i] forState:UIControlStateNormal];
            [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            [button setImage:[UIImage imageNamed:images[i]] forState:UIControlStateNormal];
            
            // 计算X\Y
            int row = i / maxCols;
            int col = i % maxCols;
            CGFloat buttonX = buttonStartX + col * (xMargin + buttonW);
            CGFloat buttonEndY = buttonStartY + row * buttonH;
            CGFloat buttonBeginY = buttonEndY - KScreenH;
            
            // 按钮动画
            POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame];
            anim.fromValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonBeginY, buttonW, buttonH)];
            anim.toValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonEndY, buttonW, buttonH)];
            anim.springBounciness = LXXSpringFactor;
            anim.springSpeed = LXXSpringFactor;
            anim.beginTime = CACurrentMediaTime() + LXXAnimationDelay * i;
            [button pop_addAnimation:anim forKey:nil];
        }
        
        // 添加标语
        UIImageView *sloganView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"app_slogan"]];
        sloganView.centerY = -1000;
        [self.view addSubview:sloganView];
        
        // 标语动画
        POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPViewCenter];
        CGFloat centerX = KScreenW * 0.5;
        CGFloat centerEndY = KScreenH * 0.2;
        CGFloat centerBeginY = centerEndY - 2* KScreenH;
        anim.fromValue = [NSValue valueWithCGPoint:CGPointMake(centerX, centerBeginY)];
        anim.toValue = [NSValue valueWithCGPoint:CGPointMake(centerX, centerEndY)];
        anim.beginTime = CACurrentMediaTime() + images.count * LXXAnimationDelay;
        anim.springBounciness = LXXSpringFactor;
        anim.springSpeed = LXXSpringFactor;
        [anim setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
            // 标语动画执行完毕, 恢复点击事件
            self.view.userInteractionEnabled = YES;
        }];
        [sloganView pop_addAnimation:anim forKey:nil];
    
    }
    

    值得注意的是动画执行过程中按钮时不可点击的,因此需要在动画执行之前,设置self.view.userInteractionEnabled = NO,在最后一个动画执行结束之后的block中设置 self.view.userInteractionEnabled = YES.
    2.点击取消按钮或者控制器的空白处的时候,页面的几个子控件分别动画弹出页面,最后一个子控件动画结束之后,dimiss掉该页面.同时,点击按钮时,也是执行相应的动画,但执行动画结束之后需要处理按钮点击之后的业务逻辑,此时需要在最后一个动画执行结束之后的block中处理相应的事件,可以通过block作为参数,将事件的代码块传到里面去.

    - (void)cancelWithCompletionBlock:(void (^)())completionBlock {
    
        self.view.userInteractionEnabled = NO;
        
        int beginIndex = 2;
        
        for (int i = beginIndex; i<self.view.subviews.count; i++) {
        
            UIView *subview = self.view.subviews[i];
            
            // 基本动画
            POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPViewCenter];
            CGFloat centerY = subview.centerY + KScreenH;
            // 动画的执行节奏(一开始很慢, 后面很快)
            anim.toValue = [NSValue valueWithCGPoint:CGPointMake(subview.centerX, centerY)];
            anim.beginTime = CACurrentMediaTime() + (i - beginIndex) * LXXAnimationDelay;
            [subview pop_addAnimation:anim forKey:nil];
            
            // 监听最后一个动画
            if (i == self.view.subviews.count - 1) {
                [anim setCompletionBlock:^(POPAnimation *anim, BOOL finished) {
                    [self dismissViewControllerAnimated:NO completion:nil];
                    
                    // 执行传进来的completionBlock参数
                    !completionBlock ? : completionBlock();
                }];
            }
        }
    }
    
    - (void)buttonClick:(UIButton *)btn {
    
        [self cancelWithCompletionBlock:^{ 
            NSLog(@"haha");
        }];
    }
    - (IBAction)cancleBtnClick:(UIButton *)sender {
        
        [self cancelWithCompletionBlock:nil];
    }
    

    这样在界面退出之后,会打印"haha".
    3.block定义
    在属性中:

    @property (nonatomic, copy) void (^completionBlock)();
    @property (nonatomic, assign) int age;
    

    与int类型的属性作对比,void表示block没有返回值,()代表block没有参数,completionBlock表示block的名字.
    在方法中使用block作为参数,就是把block的名字拿到括号外面:

    - (void)cancelWithCompletionBlock:(void (^)())completionBlock {
    }
    - (void)buttonClick:(UIButton *)btn { 
    }
    

    void (^)()代表block的类型,completionBlock是block的名字.

    相关文章

      网友评论

          本文标题:2014.04.26

          本文链接:https://www.haomeiwen.com/subject/seabzttx.html