底部旋轉菜單

Main.storyboardide

ViewController.m動畫

//atom

//  ViewController.mspa

//  8A07.底部旋轉菜單3d

//code

//  Created by huan on 16/2/6.orm

//  Copyright © 2016 huanxi. All rights reserved.對象

//blog

 

#import "ViewController.h"圖片

#import "CZBottomMenu.h"

@interface ViewController ()

 

@end

 

@implementation ViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    

    //添加底部View

    CZBottomMenu *menu = [CZBottomMenu buttomMenu];

    CGFloat menuX = 0;

    CGFloat menuY = self.view.bounds.size.height - menu.bounds.size.height;

    CGFloat menuW = self.view.bounds.size.width;

    CGFloat menuH = menu.bounds.size.height;

    menu.frame = CGRectMake(menuX, menuY, menuW, menuH);

    [self.view addSubview:menu];

}

 

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

@end

CZBottomMenu.h

#import <UIKit/UIKit.h>

 

@interface CZBottomMenu : UIView

 

+(instancetype)buttomMenu;

    

 

@end

CZBottomMenu.m

//

//  CZBottomMenu.m

//  8A07.底部旋轉菜單

//

//  Created by huan on 16/2/6.

//  Copyright © 2016 huanxi. All rights reserved.

//

 

#import "CZBottomMenu.h"

#define AnimationDuration 5

#define delta 90 //按鈕間的間距

@interface CZBottomMenu()

/**

 * Items存在三個隱藏的按鈕

 */

@property (nonatomic, strong) NSMutableArray *itmes;

@property (weak, nonatomic) IBOutlet UIButton *mainBtn;

- (IBAction)mainBtnClick:(id)sender;

 

@end

@implementation CZBottomMenu

 

/*

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {

    // Drawing code

}

*/

 

-(NSMutableArray *)itmes{

    if (!_itmes) {

        _itmes = [NSMutableArray array];

    }

    return _itmes;

}

 

+(instancetype)buttomMenu{

    //bundle里加載xib

    return [[[NSBundle mainBundle] loadNibNamed:@"CZBottomMenu" owner:nil options:nil]lastObject];

}

#pragma mark 對象是從xib/storyboard加載的時候,就好調用這個方法

-(id)initWithCoder:(NSCoder *)aDecoder{

    if (self = [super initWithCoder:aDecoder]) {

        [self initItems];

    }

    return self;

}

 

#pragma mark 初始化三個隱藏的按鈕

-(void)initItems{

    [self addBtnWithBgImage:@"menu_btn_call"tag:0];

    [self addBtnWithBgImage:@"menu_btn_cheyou"tag:1];

    [self addBtnWithBgImage:@"menu_btn_tixing"tag:2];

 

}

 

/**

 * 經過一張圖片來添加按鈕

 */

-(void)addBtnWithBgImage:(NSString *)bgImage tag:(NSInteger)tag{

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

    [btn setBackgroundImage:[UIImage imageNamed:bgImage] forState:UIControlStateNormal];

    btn.tag = tag;

    [self.itmes addObject:btn];

    [self addSubview:btn];

}

 

#pragma mark 設置三個隱藏按鈕的尺寸和位置

-(void)layoutSubviews{

    //全部隱藏按鈕的大小是同樣的

    CGRect btnBounds = CGRectMake(0, 0, 43, 43);

    //遍歷三個隱藏的按鈕

    for (UIButton * btn in self.itmes) {

        btn.bounds = btnBounds;

        btn.center = self.mainBtn.center;

    }

    //紅色按鈕置頂

    [self bringSubviewToFront:self.mainBtn];

}

 

 

- (IBAction)mainBtnClick:(id)sender {

    

    BOOL show = CGAffineTransformIsIdentity(self.mainBtn.transform);

    // 1.實現 按鈕 動畫效果

    [UIView animateWithDuration:AnimationDuration animations:^{

        if (show) {//表明transform未被改變

            self.mainBtn.transform = CGAffineTransformMakeRotation(M_PI_4);

        }else{//恢復

            self.mainBtn.transform = CGAffineTransformIdentity;

        }

    }];

    [self showItems:show];

    

}

 

-(void)showItems:(BOOL)show{

 

#warning 默認狀況 按鈕的中心與按鈕的圖層的position是同樣

    NSLog(@"主按鈕中心點 %@", NSStringFromCGPoint(self.mainBtn.center));

    NSLog(@"主按鈕的圖層的position %@", NSStringFromCGPoint(self.mainBtn.layer.position));

    // 3.實現 items 的顯示位置

    for (UIButton *btn in self.itmes) {

#warning 一個按鈕對應一個組動畫

        //2.建立動畫

        //2.1 建立組動畫

        CAAnimationGroup *group = [CAAnimationGroup animation];

        group.duration = AnimationDuration;

        //2.2 添加一個平移動畫

        CAKeyframeAnimation *positionAni = [CAKeyframeAnimation animation];

        positionAni.keyPath = @"position";

        

        //2.3 添加一個旋轉的動畫

        CAKeyframeAnimation *rotationAni = [CAKeyframeAnimation animation];

        rotationAni.keyPath = @"transform.rotation";

        

        

        //從新設置每個按鈕的x

        CGFloat btnCenterX = self.mainBtn.center.x + (btn.tag + 1) * delta;

        CGFloat btnCenterY = self.mainBtn.center.y;

        // 最終顯示的位置

        CGPoint showPosition = CGPointMake(btnCenterX, btnCenterY);

        //設置平移動畫的路徑

        NSValue *value1 = [NSValue valueWithCGPoint:self.mainBtn.center];

        NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(btnCenterX * 0.5, btnCenterY)];

        NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(btnCenterX * 1.1, btnCenterY)];

        NSValue *value4 = [NSValue valueWithCGPoint:showPosition];

        //顯示

        if (show) {

            

            positionAni.values = @[value1, value2, value3, value4];

            //設置 旋轉的路徑

            rotationAni.values = @[@0, @(M_PI * 2), @(M_PI * 4), @(M_PI * 2)];

            btn.center = showPosition;

        }else{

            // 隱藏

            //設置平移動畫的路徑

            positionAni.values = @[value4, value3, value2, value1];

            //設置 旋轉的路徑

            rotationAni.values = @[@0, @(M_PI * 2), @0, @(-M_PI * 2)];

            btn.center = self.mainBtn.center;

        }

        //添加子動畫

        group.animations = @[positionAni, rotationAni];

        //執行組動畫

        [btn.layer addAnimation:group forKey:nil];

        

    }

    

    

 

}

@end

CZBottomMenu.xib

 

結果

相關文章
相關標籤/搜索