新浪微博,按钮依次弹出动画

本文介绍如何在iOS应用中创建一个自定义按钮控件,并实现按钮动画效果。通过定义按钮模型和使用定时器,可以依次对每个按钮进行动画处理,提升用户体验。此外,展示了如何通过代码快速创建按钮模型,以及如何在按钮上添加图片和文字。最后,提供了一个实例演示如何使用这些功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.点击modal出一个控制器


//
//  ComposeItemViewController.h


#import <UIKit/UIKit.h>

@interface ComposeItemViewController : UIViewController

/**
 *  有多少个按钮
 */
//@property(nonatomic,assign) int itemCount;

/**
 *  菜单模型数组
 */
@property(nonatomic,strong)NSArray *items;

@end
//
//  ComposeItemViewController.m


#import "ComposeItemViewController.h"
#import "MenuItem.h"
#import "MenuItemButton.h"

@interface ComposeItemViewController ()

/**
 *  保存所有按钮菜单
 */
@property(nonatomic,strong)NSMutableArray *itemButtons;

@property(nonatomic,assign)int btnIndex;

@property(nonatomic,strong)NSTimer *timer;

@end

@implementation ComposeItemViewController

- (NSMutableArray *)itemButtons
{
    if (_itemButtons == nil) {
        _itemButtons = [NSMutableArray array];
    }
    return _itemButtons;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    
    // 1.添加所有的item按钮
    [self setupAllBtns];
    
    // 2.添加定时器依次让按钮动画
    _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timeChange) userInfo:nil repeats:YES];
}

- (void)timeChange
{
    if (_btnIndex == self.itemButtons.count) {
        // 定时器停止
        [_timer invalidate];
        
        return;
    }
    
    UIButton *btn = self.itemButtons[_btnIndex];
    [self btnAnimation:btn];
    
    _btnIndex++;
}


/**
 *  给一个按钮做动画
 */
- (void)btnAnimation:(UIButton *)btn
{
    [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{
        btn.transform = CGAffineTransformIdentity;
    } completion:nil];
}



/**
 *  创建所有按钮
 */
- (void)setupAllBtns
{
    int totalCols = 3; //总列数
    int col = 0;
    int row = 0;
    CGFloat x = 0;
    CGFloat y = 0;
    CGFloat wh = 100;
    CGFloat margin = ([UIScreen mainScreen].bounds.size.width - totalCols * wh) / (totalCols +1);
    CGFloat originY = 300;
    
    for (int i=0; i< _items.count; i++) {
        MenuItemButton  *btn = [MenuItemButton buttonWithType:UIButtonTypeCustom];
        col = i % totalCols;
        row = i / totalCols;
        x = margin + (margin + wh) * col;
        y = row * (margin + wh) + originY;
        btn.frame = CGRectMake(x, y, wh, wh);
        
        // 设置按钮的图片和文字
        MenuItem *item = _items[i];
        [btn setImage:item.image forState:UIControlStateNormal];
        [btn setTitle:item.title forState:UIControlStateNormal];
        
        // 偏移到底部
        btn.transform = CGAffineTransformMakeTranslation(0, self.view.bounds.size.height);
        
        // 添加监听
        [btn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchDown];
        
        [self.itemButtons addObject:btn];
        
        [self.view addSubview:btn];
    }
}

- (void)btnClicked:(UIButton *)btn
{
    [UIView animateWithDuration:0.5 animations:^{
        btn.transform = CGAffineTransformMakeScale(1.1, 1.1);
    } completion:nil];
}

@end
2.按钮需要外部传入图片和文字,所以定义一个按钮模型

//
//  MenuItem.h

//  按钮菜单模型

#import <UIKit/UIKit.h>

@interface MenuItem : NSObject

@property(nonatomic,strong)NSString *title;

@property(nonatomic,strong) UIImage *image;

/**
 *  快速创建一个菜单模型
 */
+ (instancetype)itemWithTitle:(NSString *)title image:(UIImage *)image;

@end
//
//  MenuItem.m

#import "MenuItem.h"

@implementation MenuItem

+ (instancetype)itemWithTitle:(NSString *)title image:(UIImage *)image
{
    MenuItem *item = [[self alloc] init];
    item.title = title;
    item.image = image;
    
    return item;
}

@end
3.按钮图片在上,文字在下,需要自定义

//
//  MenuItemButton.h

#import <UIKit/UIKit.h>

@interface MenuItemButton : UIButton

@end
//
//  MenuItemButton.m


#import "MenuItemButton.h"
#define kImageRatio 0.8

@implementation MenuItemButton

- (void)awakeFromNib
{
    [self setup];
}

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setup];
    }
    return self;
}

- (void)setup
{
    self.imageView.contentMode = UIViewContentModeCenter;
    self.titleLabel.textAlignment = NSTextAlignmentCenter;
}

- (void)setHighlighted:(BOOL)highlighted{}

// 如果通过代码设置子控件位置,都是在layoutSubviews里面
- (void)layoutSubviews
{
    [super layoutSubviews];
    
    // imageView
    CGFloat imageX = 0;
    CGFloat imageY = 0;
    CGFloat imageW = self.bounds.size.width;
    CGFloat imageH = self.bounds.size.height * kImageRatio;
    self.imageView.frame = CGRectMake(imageX, imageY, imageW, imageH);
    
    // titleLabel
    CGFloat labelY = imageH;
    CGFloat labelH = self.bounds.size.height - labelY;
    self.titleLabel.frame = CGRectMake(imageX, labelY, imageW, labelH);
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    
    [UIView animateWithDuration:0.5 animations:^{
        self.transform = CGAffineTransformMakeScale(2.0, 2.0);
        self.alpha = 0.0;
    } completion:nil];
}

@end
4.如何使用?

/**
 *  点击+号按钮
 */
- (IBAction)btnAction:(UIButton *)sender
{
    // 创建模型数组
    MenuItem *item0 = [MenuItem itemWithTitle:@"点评" image:[UIImage imageNamed:@"tabbar_compose_review"]];
    MenuItem *item1 = [MenuItem itemWithTitle:@"更多" image:[UIImage imageNamed:@"tabbar_compose_more"]];
    MenuItem *item2 = [MenuItem itemWithTitle:@"拍摄" image:[UIImage imageNamed:@"tabbar_compose_camera"]];
    MenuItem *item3 = [MenuItem itemWithTitle:@"相册" image:[UIImage imageNamed:@"tabbar_compose_photo"]];
    MenuItem *item4 = [MenuItem itemWithTitle:@"文字" image:[UIImage imageNamed:@"tabbar_compose_idea"]];
    MenuItem *item5 = [MenuItem itemWithTitle:@"签到" image:[UIImage imageNamed:@"tabbar_compose_lbs"]];
    
    ComposeItemViewController *vc = [[ComposeItemViewController alloc] init];
    vc.items = @[item0,item1,item2,item3,item4,item5];
    
    [self presentViewController:vc animated:YES completion:nil];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值