模仿微信的Actionsheet

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模仿微信的Actionsheet相关的知识,希望对你有一定的参考价值。

技术分享

最近需要写一个类似微信的actionsheet然后就模仿写了个,实现方法简单,下面是代码:

@class GKDActionSheet;
typedef void(^GKDActionSheetBlock)(NSInteger buttonIndex);

@protocol GKDActionSheetDelegate <NSObject>
@optional
/**
 *  新增一个协议方法
 */
- (void)actionSheet:(GKDActionSheet *)actionSheet didClickedButtonAtIndex:(NSInteger)buttonIndex;

@end

@interface GKDActionSheet : UIView

@property (nonatomic ,copy) GKDActionSheetBlock clickBlock;

@property (nonatomic ,weak) id<GKDActionSheetDelegate> delegate;
#pragma mark - 构造方法
/**
 *  初始化方法
 *
 *  @param buttonTitles 需要以数组形式传入
 *  @param cancleTitle  取消按钮的名称
 *  @param clicked      回调的block
 */

+ (instancetype)sheetWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle clicked:(GKDActionSheetBlock)clicked;

- (instancetype)initWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle  clicked:(GKDActionSheetBlock)clicked;

/**
 *  初始化方法
 *
 *  @param buttonTitles   传入参数数组
 *  @param cancleTitle    取消按钮
 *  @param redButtonIndex 红色字体按钮
 *  @param clicked        点击的回调
 */
+ (instancetype)sheetWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle redButtonIndex:(NSInteger)redButtonIndex clicked:(GKDActionSheetBlock)clicked;

- (instancetype)initWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle redButtonIndex:(NSInteger)redButtonIndex clicked:(GKDActionSheetBlock)clicked;
/**
 *  初始化方法
 *
 *  @param buttonTitles   参数数组
 *  @param cancleTitle    取消按钮
 *  @param redButtonIndex 红色按钮的索引
 *  @param delegate       协议
 */
+ (instancetype)sheetWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle redButtonIndex:(NSInteger)redButtonIndex delegate:(id<GKDActionSheetDelegate>)delegate;

- (instancetype)initWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle redButtonIndex:(NSInteger)redButtonIndex delegate:(id<GKDActionSheetDelegate>)delegate;
/**
 *  添加红色字体按钮
 */
@property (nonatomic, assign)NSInteger redButtonIndex;

/**
 *  show的方法
 */
- (void)show;

- (void)showInView:(UIView *)view;
@property (nonatomic, copy) NSString *cancleTitle;


@property (nonatomic, strong) NSMutableArray *buttonTitles;


@property (nonatomic, strong) UIView *maskView;


@property (nonatomic, strong) UIView *backgroundView;


@property (nonatomic, strong) UIWindow *backgroundWindow;

@end


@implementation GKDActionSheet

+ (instancetype)sheetWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle clicked:(GKDActionSheetBlock)clicked{
    return [[self alloc] initWithButtonTitles:buttonTitles andCancleTitle:cancleTitle clicked:clicked];
}

- (instancetype)initWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle  clicked:(GKDActionSheetBlock)clicked{
    self = [super init];
    if (self) {
        self.redButtonIndex = -1;
        self.cancleTitle = cancleTitle;
        self.buttonTitles = [[NSMutableArray alloc] initWithArray:buttonTitles];
        self.clickBlock = clicked;
    }
    return self;
}

+ (instancetype)sheetWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle redButtonIndex:(NSInteger)redButtonIndex clicked:(GKDActionSheetBlock)clicked {
    return [[self alloc] initWithButtonTitles:buttonTitles andCancleTitle:cancleTitle
                               redButtonIndex:redButtonIndex clicked:clicked];
}

- (instancetype)initWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle redButtonIndex:(NSInteger)redButtonIndex clicked:(GKDActionSheetBlock)clicked {
    
    self = [super init];
    if (self) {
        self.redButtonIndex = redButtonIndex;
        self.cancleTitle = cancleTitle;
        self.buttonTitles = [[NSMutableArray alloc] initWithArray:buttonTitles];
        self.clickBlock = clicked;
    }
    return self;
}
+ (instancetype)sheetWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle redButtonIndex:(NSInteger)redButtonIndex delegate:(id<GKDActionSheetDelegate>)delegate{
    return [[self alloc]initWithButtonTitles:buttonTitles andCancleTitle:cancleTitle redButtonIndex:redButtonIndex delegate:delegate];
}

- (instancetype)initWithButtonTitles:(NSArray *)buttonTitles andCancleTitle:(NSString *)cancleTitle redButtonIndex:(NSInteger)redButtonIndex delegate:(id<GKDActionSheetDelegate>)delegate{
    self = [super init];
    if (self) {
        self.redButtonIndex = redButtonIndex;
        self.cancleTitle = cancleTitle;
        self.buttonTitles = [[NSMutableArray alloc] initWithArray:buttonTitles];
        self.delegate = delegate;
    }
    return self;
}

- (void)setUpMainView {
    UIView *maskView = [UIView new];
    maskView.alpha = 0;
    maskView.userInteractionEnabled = NO;
    maskView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
    maskView.backgroundColor = [UIColor blackColor];
    [self addSubview:maskView];
    
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss:)];
    [maskView addGestureRecognizer:tap];
    _maskView = maskView;
    
    UIView *backgroundView = [UIView new];
    backgroundView.backgroundColor = [UIColor clearColor];
    
    if (self.buttonTitles.count > 0) {
        for (int i = 0; i < self.buttonTitles.count; i++) {
            // 添加按钮
            
            if(((NSString *)self.buttonTitles[i]).length == 0){ //为空的话就不显示
                continue;
            }
            UIButton *btn = [UIButton new];
            btn.tag = i;
            btn.backgroundColor = [UIColor whiteColor];
            btn.titleLabel.font = [UIFont systemFontOfSize:17];
            [btn setBackgroundImage:[self createImageWithColor:RGB(217, 217, 217)] forState:UIControlStateHighlighted];
            [btn setTitle:self.buttonTitles[i] forState:UIControlStateNormal];
            
            //红色文字
            UIColor *titleColor = nil;
            if (i == self.redButtonIndex) {
                titleColor = DefalutMainColorRed;
            } else {
                titleColor = [UIColor blackColor];
            }
            
            [btn setTitleColor:titleColor forState:UIControlStateNormal];
            [btn addTarget:self action:@selector(didClickBtn:) forControlEvents:UIControlEventTouchUpInside];
            
            CGFloat y = BTN_H * i;
            [btn setFrame:CGRectMake(0, y, SCREEN_W, BTN_H)];
            
            [backgroundView addSubview:btn];
        }
    }
    for (int i = 0; i < self.buttonTitles.count; i++) {
        // 分割线
        if (i == 0) continue;
        
        UIView *line = [UIView new];
        line.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.6];
        CGFloat y = i * BTN_H;
        line.frame = CGRectMake(0, y, SCREEN_W, DefaultLineWidth);
        [backgroundView addSubview:line];
    }
    //放个取消按钮
    UIButton *cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    cancelBtn.tag = self.buttonTitles.count;
    cancelBtn.backgroundColor = [UIColor whiteColor];
    cancelBtn.titleLabel.font = [UIFont systemFontOfSize:17];
    [cancelBtn setTitle:self.cancleTitle forState:UIControlStateNormal];
    [cancelBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [cancelBtn setBackgroundImage:[self createImageWithColor:RGB(217, 217, 217)] forState:UIControlStateHighlighted];
    [cancelBtn addTarget:self action:@selector(didClickCancelBtn) forControlEvents:UIControlEventTouchUpInside];
    
    CGFloat y = BTN_H * self.buttonTitles.count + 5.0f;
    cancelBtn.frame = CGRectMake(0, y, SCREEN_W, BTN_H);
    [backgroundView addSubview:cancelBtn];
    
    CGFloat bottomH = BTN_H * self.buttonTitles.count + BTN_H + 5.0f;
    //放在屏幕下
    [backgroundView setFrame:CGRectMake(0, SCREEN_H, SCREEN_W, bottomH)];
    _backgroundView = backgroundView;
    
    self.frame = CGRectMake(0, 0, SCREEN_W, SCREEN_H);
}

- (void)didClickCancelBtn{
    
    [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        //变下去
        _maskView.alpha = 0;
        _maskView.userInteractionEnabled = NO;
        CGRect frame = _backgroundView.frame;
        frame.origin.y += frame.size.height;
        _backgroundView.frame = frame;
        
    } completion:^(BOOL finished) {
        if ([self.delegate respondsToSelector:@selector(actionSheet:didClickedButtonAtIndex:)]) {
            [self.delegate actionSheet:self didClickedButtonAtIndex:self.buttonTitles.count];
        }
        __weak typeof(self) weakSelf = self;
        if (self.clickBlock) {
            self.clickBlock(weakSelf.buttonTitles.count);
        }
        self.backgroundWindow.hidden = YES;
        [self removeFromSuperview];
    }];
    
}
- (void)didClickBtn:(UIButton *)btn {
    [self dismiss:nil];
    if ([self.delegate respondsToSelector:@selector(actionSheet:didClickedButtonAtIndex:)]) {
        [self.delegate actionSheet:self didClickedButtonAtIndex:btn.tag];
    }
    if (self.clickBlock) {
        self.clickBlock(btn.tag);
    }
}

- (void)dismiss:(UITapGestureRecognizer *)tap {
    
    [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        //变下去
        _maskView.alpha = 0;
        _maskView.userInteractionEnabled = NO;
        CGRect frame = _backgroundView.frame;
        frame.origin.y += frame.size.height;
        _backgroundView.frame = frame;
        
    } completion:^(BOOL finished) {
        
        self.backgroundWindow.hidden = YES;
        
        [self removeFromSuperview];
    }];
}

- (void)showInView:(UIView *)view {
    [self setUpMainView];
    [self addSubview:self.backgroundView];
    [view addSubview:self];
    
    [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        //从下面冒出来
        _maskView.alpha = 0.5;
        _maskView.userInteractionEnabled = YES;
        CGRect frame = _backgroundView.frame;
        frame.origin.y -= frame.size.height;
        _backgroundView.frame = frame;
        
    } completion:nil];
}

- (void)show {
    [self setUpMainView];
    
    self.backgroundWindow.hidden = NO;
    [self addSubview:self.backgroundView];
    [self.backgroundWindow addSubview:self];
    
    [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        //从下面冒出来
        _maskView.alpha = 0.5;
        _maskView.userInteractionEnabled = YES;
        CGRect frame = _backgroundView.frame;
        frame.origin.y -= frame.size.height;
        _backgroundView.frame = frame;
        
    } completion:nil];
    
}

//生成一个纯色图片
- (UIImage *)createImageWithColor:(UIColor *)color{
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

- (UIWindow *)backgroundWindow {
    if (!_backgroundWindow) {
        _backgroundWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        _backgroundWindow.windowLevel = UIWindowLevelAlert;
        _backgroundWindow.backgroundColor  = [UIColor clearColor];
        _backgroundWindow.hidden = NO;
    }
    return _backgroundWindow;
}

 

以上是关于模仿微信的Actionsheet的主要内容,如果未能解决你的问题,请参考以下文章

iOS模仿微信的那个视频眼睛动画

如何用微信小程序模仿豆瓣首页

玩转Android之加速度传感器的使用,模仿微信摇一摇

百度AI框架飞桨这个声音克隆的机器人,能模仿你说话

各位大神,在H5页面中怎么调取微信的地图定位功能啊,有没有详细代码

Android基础控件——PopupWindow模仿ios底部弹窗