IOS 动画例子(Path 菜单按钮)

来源:互联网 发布:中医宝典大全软件 编辑:程序博客网 时间:2024/06/08 16:04


例子是我 从 code4app 上找的 是当时很火的 Path2 菜单按钮  我现在来学习他

http://code4app.com/ios/QuadCurve-Menu/4f67ef546803fa6d45000000

当你下载完打开是这样的 


我们是来学习他那动画效果的 所以我们要开的 核心文件就 一个

QuadCurveMenu

打开 QuadCurveMenu.m 文件  看 初始方法


 QuadCurveMenuItem *item = [_menusArray objectAtIndex:i];            item.tag = 1000 + i;            item.startPoint = STARTPOINT; //开始坐标            //最终停留的坐标            item.endPoint = CGPointMake(STARTPOINT.x + ENDRADIUS * cosf(i * M_PI_2 / (count - 1)), STARTPOINT.y - ENDRADIUS * sinf(i * M_PI_2 / (count - 1)));            //靠近停留坐标的位置            item.nearPoint = CGPointMake(STARTPOINT.x + NEARRADIUS * cosf(i * M_PI_2 / (count - 1)), STARTPOINT.y - NEARRADIUS * sinf(i * M_PI_2 / (count - 1)));            //超过 停留坐标的位置   这些坐标用来做 物体 惯性的  使得动画看起来更自然也更美观            item.farPoint = CGPointMake(STARTPOINT.x + FARRADIUS * cosf(i * M_PI_2 / (count - 1)), STARTPOINT.y - FARRADIUS * sinf(i * M_PI_2 / (count - 1)));            /*             坐标算法就是 圆的极坐标方程             x = a+r*cos(@)             y = b+r*sin(@)             因为该动画 是从上到下的 把 cos 和 sin 换了个位置  有兴趣的 可以把他们换回来  看看效果             */            item.center = item.startPoint;            item.delegate = self;            [self addSubview:item];

这个只是 算坐标的方法

下面 我们看他的动画是怎么设计的

当你点击了 AddButton

- (void)quadCurveMenuItemTouchesBegan:(QuadCurveMenuItem *)item

{

    if (item == _addButton

    {

        self.expanding = !self.isExpanding;

    }

}


好我们在看 

- (void)setExpanding:(BOOL)expanding{    _expanding = expanding;            // rotate add button    float angle = self.isExpanding ? -M_PI_4 : 0.0f;    [UIView animateWithDuration:0.2f animations:^{        //把 AddButton 按钮旋转 angle 度。        //这个是 矩阵变换   看名字大家应该就知道做什么用的了//        Creating an Affine Transformation Matrix        //        CGAffineTransformMake              //这个最牛  想要什么自己弄  可惜水平不够 只会用下面的方法//        CGAffineTransformMakeRotation//        CGAffineTransformMakeScale//        CGAffineTransformMakeTranslation                _addButton.transform = CGAffineTransformMakeRotation(angle);    }];        // expand or close animation    if (!_timer)     {        _flag = self.isExpanding ? 0 : 5;        //真正的动画还是 藏在 _expand 和 _close 里面        SEL selector = self.isExpanding ? @selector(_expand) : @selector(_close);                //对每一个 Item 做延迟处理  做时差效果        _timer = [[NSTimer scheduledTimerWithTimeInterval:TIMEOFFSET target:self selector:selector userInfo:nil repeats:YES] retain];    }}

看下 _expand 方法

- (void)_expand{    if (_flag == 6) //这边设死了  固定6个Item  可自行更改    {        [_timer invalidate];        [_timer release];        _timer = nil;        return;    }        int tag = 1000 + _flag;    QuadCurveMenuItem *item = (QuadCurveMenuItem *)[self viewWithTag:tag];        //按 Z 轴旋转  可以改成 x,y  改成什么 就是按什么轴旋转   大家可以自己 改改看效果    CAKeyframeAnimation *rotateAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];    //关键帧 就是赋值 跟 keyTimes 配合    rotateAnimation.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:M_PI],[NSNumber numberWithFloat:0.0f], nil];    //动画时间    rotateAnimation.duration = 0.5f;    //跟关键帧配合    rotateAnimation.keyTimes = [NSArray arrayWithObjects:                                [NSNumber numberWithFloat:.3],                                 [NSNumber numberWithFloat:.4], nil];         //路线的动画    CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];        positionAnimation.duration = 0.5f;    CGMutablePathRef path = CGPathCreateMutable();    //移动到开始坐标    CGPathMoveToPoint(path, NULL, item.startPoint.x, item.startPoint.y);    //添加路劲坐标点   先移动到 靠近位置    CGPathAddLineToPoint(path, NULL, item.farPoint.x, item.farPoint.y);    //移动到  超出位置  看起来有反弹效果    CGPathAddLineToPoint(path, NULL, item.nearPoint.x, item.nearPoint.y);    //最终的坐标    CGPathAddLineToPoint(path, NULL, item.endPoint.x, item.endPoint.y);     positionAnimation.path = path;    CGPathRelease(path);        CAAnimationGroup *animationgroup = [CAAnimationGroup animation];    animationgroup.animations = [NSArray arrayWithObjects:positionAnimation, rotateAnimation, nil];    animationgroup.duration = 0.5f;    animationgroup.fillMode = kCAFillModeForwards;    //EaseIn 前端慢  EaseInEaseOut 两端慢 中间快 EaseOut 后端慢    animationgroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];    [item.layer addAnimation:animationgroup forKey:@"Expand"];    item.center = item.endPoint;        _flag ++; // 下一个Item    }

_close

 的做法 跟_expand 差不多就不说了 


在点击了 Item 按钮后 会有个 Item 放大 其他按钮缩小的动画


- (CAAnimationGroup *)_blowupAnimationAtPoint:(CGPoint)p{    //位置保持不变    CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];    positionAnimation.values = [NSArray arrayWithObjects:[NSValue valueWithCGPoint:p], nil];    positionAnimation.keyTimes = [NSArray arrayWithObjects: [NSNumber numberWithFloat:.3], nil];         //放大3倍    CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];    scaleAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(3, 3, 1)];    //透明    CABasicAnimation *opacityAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];    opacityAnimation.toValue  = [NSNumber numberWithFloat:0.0f];        CAAnimationGroup *animationgroup = [CAAnimationGroup animation];    animationgroup.animations = [NSArray arrayWithObjects:positionAnimation, scaleAnimation, opacityAnimation, nil];    animationgroup.duration = 0.3f;    animationgroup.fillMode = kCAFillModeForwards;    return animationgroup;}


缩小跟这写法 差不多 大家自己看


感觉我就是在注释!

 曹操。。

教新手个 实用的  如果你要 改变 这控件的位置这么办呢?

如果你要改成 右上角 像这样




你只要改


#define STARTPOINT CGPointMake(50, 430)

改成

#define STARTPOINT CGPointMake(270, 50)

接下来是 位置   位置 简单 只要更改下 + - 号就行了  

    //最终停留的坐标

            item.endPoint = CGPointMake(STARTPOINT.x -ENDRADIUS * cosf(i * M_PI_2 / (count - 1)), STARTPOINT.y +ENDRADIUS * sinf(i * M_PI_2 / (count - 1)));

            //靠近停留坐标的位置

            item.nearPoint = CGPointMake(STARTPOINT.x -NEARRADIUS * cosf(i * M_PI_2 / (count - 1)), STARTPOINT.y +NEARRADIUS * sinf(i * M_PI_2 / (count - 1)));

            //超过停留坐标的位置   这些坐标用来做 物体惯性的  使得动画看起来更自然也更美观

            item.farPoint = CGPointMake(STARTPOINT.x -FARRADIUS * cosf(i * M_PI_2 / (count - 1)), STARTPOINT.y +FARRADIUS * sinf(i * M_PI_2 / (count - 1)));

OVER
原创粉丝点击