卡片菜单

卡片菜单组件用于在用户单击客户端页面上的卡片时弹出选择菜单。在 iOS 中,beeviews:BEEPopMenuView 需要替换为 AUCardMenu.h

效果图

  • 多行组合样式

  • 按压效果

  • 双行

  • 选择按钮

接口说明

  • AUCardMenu.h

    //
    //  AUCardMenu.h
    //  AntUI
    //
    
    
    @class AUMultiStyleCellView;
    @class AUWindow;
    /*!
     @class       AUCardMenu
     @abstract    AUWindow
     @discussion  带蒙层 + 方向角的弹出菜单
    */
    
    @interface AUCardMenu : AUWindow
    {
    
    }
    
    /**
     *  若需要响应单击事件,需要对 cellView 实现 AUMultiStyleCellDelegate 协议
     *  在自己的 viewcontroller 中赋值 popMenuView.cellView.delegate = self;
     */
    @property (nonatomic, strong) AUMultiStyleCellView *cellView;
    
    /**
     *   
     
    初始化方法(强烈推荐此方法) 
     
    
     *
     *  @param data      数组存放对象模型 CellDataModel
     *  @param location  方向角的基准点
     *  @param offset    方向角相对基准点的偏移量
     *
     *  @return self
     */
    
    - (instancetype)initWithData:(NSArray *)data
                        location:(CGPoint)location
                          offset:(CGFloat)offset;
    
    /**
     * 展示弹出菜单
     *
     *  @param superView  PopMenuView的superView
     */
    - (void)showPopMenu:(UIView *)superView;
    
    // 隐藏弹出菜单,最好在 dealloc 方法里也调用
    - (void)hidePopMenu;
    
    // 注意:带动画方式的展示或消失必须成对使用,即:动画出现必须动画消失,非动画出现必须非动画消失
    
    // 带有动画方式的展示菜单
    - (void)showPopMenu:(UIView *)superView animation:(BOOL) isAnimation;
    
    // 带动画方式的消失菜单
    - (void)hidePopMenuWithAnimation:(BOOL)isAnimation;
    
    @end
  • AUCellDataModel.h

    //
    //  AUCellDataModel.h
    //  AntUI
    //
    
    #import <Foundation/Foundation.h>
    
    /*!
     @class       AUMultiStyleCellView
     @abstract    UIView
     @discussion  menu 中的子 view
     */
    
    @interface AUCellDataModel : NSObject
    
    @property (nonatomic, strong) NSString *iconUrl;
    @property (nonatomic, strong) NSString *titleText;
    @property (nonatomic, strong) NSString *descText;
    @property (nonatomic, strong) NSString *checkMarkUrl;  // 对勾
    @property (nonatomic, strong) NSString *indicatorUrl;  // 右指示箭头
    @property (nonatomic, strong) NSArray *buttonsArray;   // NSArray<NSString>
    @property (nonatomic, strong) NSDictionary *extendDic; // 给业务方使用的扩展字段
    @property (nonatomic, assign) BOOL selectedState;      // 当前 model 选中状态,默认为 NO,即不选中
    
    @end
  • AUMultiStyleCellView.h

    //
    //  AUMultiStyleCellView.h
    //  AntUI
    //
    
    #import <UIKit/UIKit.h>
    #import "AUCellDataModel.h"
    
    @class AUMultiStyleCellView;
    @protocol AUMultiStyleCellDelegate <NSObject>
    
    @optional
    /**
     *  单击事件回调
     *
     *  @param dataModel 单击的 view 对应的数据模型
     *  @param indexPath 单击的 view 在 CellDataModel 中的下标(若 CellDataModel.buttonsArray == nil,则 row 默认取值为 -1)
     */
    - (void)DidClickCellView:(AUCellDataModel *)dataModel ForRowAtIndexpath:(NSIndexPath *)indexPath;
    - (void)DidClickCellButton:(AUCellDataModel *)dataModel ForRowAtIndexpath:(NSIndexPath *)indexPath;
    - (void)DidClickCellView:(AUCellDataModel *)dataModel ForRowAtIndexpath:(NSIndexPath *)indexPath cellView:(AUMultiStyleCellView *)cellView;
    @end
    
    
    /**
     *  融合多样式的 cellview
     *  1. 图标 + 主标题
     *  2. 图标 + 主标题 + 位于主标题下方的副标题
     *  3. 图标 + 主标题 + 多行多列的带边框按钮控件
     */
    
    @interface AUMultiStyleCellView : UIView
    
    @property (nonatomic, weak) id<AUMultiStyleCellDelegate> delegate;
    @property (nonatomic, strong) NSArray *cellDataArray;
    
    // 如果 cellDataArray 为空等同于调用 initWithFrame 方法
    - (instancetype)initWithFrame:(CGRect)frame
                    cellDataArray:(NSArray *)cellDataArray
                         isUpward:(BOOL)isUpward;
    
    // 提供处理当前 cellView 选中与否的状态
    - (void)updateSelectedState;
    
    
    @end

代码示例

//
//  cardMenuController.m
//  AntUI
//

#import "cardMenuController.h"
#import "AUCardMenu.h"
#import "AUCellDataModel.h"
#import "AUMultiStyleCellView.h"

@interface cardMenuController ()<AUMultiStyleCellDelegate>

@property (nonatomic,strong)     AUCardMenu * popMenuView;

@end

@implementation cardMenuController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = RGB(0xF5F5F9);
    UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setFrame:CGRectMake(0, 100, self.view.width, 100)];
    [button setTitle:@"弹出菜单/多行组合样式" forState:UIControlStateNormal];
    [button setTitleColor:RGB(0x888888) forState:UIControlStateNormal];
    [button addTarget:self
               action:@selector(handleButton:)
     forControlEvents:UIControlEventTouchUpInside];
    [button.titleLabel setTextAlignment:NSTextAlignmentLeft];
    [button.titleLabel setFont:[UIFont systemFontOfSize:14]];
    [button setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
    [button setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];

    [self.view addSubview:button];

    UIButton * button2 = [UIButton buttonWithType:UIButtonTypeCustom];
    [button2 setFrame:CGRectMake(0, 220, self.view.width, 100)];
    [button2 setTitle:@"弹出菜单/按压效果" forState:UIControlStateNormal];
    [button2 addTarget:self
               action:@selector(handleButton2:)
     forControlEvents:UIControlEventTouchUpInside];
    [button2.titleLabel setTextAlignment:NSTextAlignmentLeft];
    [button2 setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
    [button2 setContentMode:UIViewContentModeLeft];
    [button2 setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];

    [button2 setTitleColor:RGB(0x888888) forState:UIControlStateNormal];
    [button2.titleLabel setFont:[UIFont systemFontOfSize:14]];

    [self.view addSubview:button2];

    UIButton * button3 = [UIButton buttonWithType:UIButtonTypeCustom];
    [button3 setFrame:CGRectMake(0, 320, self.view.width, 100)];
    [button3 setTitle:@"弹出菜单/双行" forState:UIControlStateNormal];
    [button3 addTarget:self
                action:@selector(handleButton3:)
      forControlEvents:UIControlEventTouchUpInside];
    [button3.titleLabel setTextAlignment:NSTextAlignmentLeft];
    [button3 setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
    [button3 setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
    [button3.titleLabel setFont:[UIFont systemFontOfSize:14]];


    [button3 setTitleColor:RGB(0x888888) forState:UIControlStateNormal];

    [self.view addSubview:button3];


    UIButton * button4 = [UIButton buttonWithType:UIButtonTypeCustom];
    [button4 setFrame:CGRectMake(0, 420, self.view.width, 100)];
    [button4 setTitle:@"弹出菜单+选择按钮" forState:UIControlStateNormal];
    [button4 addTarget:self
                action:@selector(handleButton4:)
      forControlEvents:UIControlEventTouchUpInside];
    [button4.titleLabel setTextAlignment:NSTextAlignmentLeft];
    [button4 setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
    [button4 setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
    [button4.titleLabel setFont:[UIFont systemFontOfSize:14]];

    [button4 setTitleColor:RGB(0x888888) forState:UIControlStateNormal];

    [self.view addSubview:button4];

}

- (void)handleButton4:(UIButton *)button
{
    AUCellDataModel * model = [[AUCellDataModel alloc] init];
    model.iconUrl = @"APCommonUI_ForDemo.bundle/hc_popmenu_dislike.png";
    model.titleText = @"我不感兴趣";
    model.buttonsArray = @[@"过时",@"看过了",@"质量差"];
    model.extendDic = @{@"type":@"reject",@"cardId":@"201609261515032720200000091128291606950000902688",@"CCard":@""};


    AUCardMenu *tmpView=[[AUCardMenu alloc]initWithData:@[model] location:CGPointMake(button.width - 20, button.centerY) offset:13];
    tmpView.cellView.delegate=self;
    [tmpView showPopMenu:button animation:YES];
    self.popMenuView=tmpView;

}

- (void)handleButton3:(UIButton *)button
{
    AUCellDataModel * model = [[AUCellDataModel alloc] init];
    model.iconUrl = @"APCommonUI_ForDemo.bundle/hc_popmenu_ignore.png";
    model.titleText = @"忽略";
    //    model.buttonsArray = @[@"你好",@"口吃吗",@"我不饿",@"你好吗",@"我很好"];
    model.extendDic = @{@"type":@"reject",@"cardId":@"201609261515032720200000091128291606950000902688",@"CCard":@""};

    AUCellDataModel * model4 = [[AUCellDataModel alloc] init];
    model4.iconUrl = @"APCommonUI_ForDemo.bundle/hc_popmenu_reject.png";
    model4.titleText = @"不再接受此类消息";
    model4.descText = @"减少此类消息的接收";
    model4.extendDic = @{@"type":@"reject",@"cardId":@"201609261515032720200000091128291606950000902688",@"CCard":@""};
    AUCardMenu *tmpView=[[AUCardMenu alloc]initWithData:@[model,model4] location:CGPointMake(button.width - 20, button.centerY) offset:13];
    tmpView.cellView.delegate=self;
    [tmpView showPopMenu:button animation:YES];
    self.popMenuView=tmpView;

}

- (void)handleButton2:(UIButton *)button
{
    AUCellDataModel * model = [[AUCellDataModel alloc] init];
    model.iconUrl = @"APCommonUI_ForDemo.bundle/hc_popmenu_ignore.png";
    model.titleText = @"忽略";
    //    model.buttonsArray = @[@"你好",@"口吃吗",@"我不饿",@"你好吗",@"我很好"];
    model.extendDic = @{@"type":@"reject",@"cardId":@"201609261515032720200000091128291606950000902688",@"CCard":@""};
    AUCellDataModel * model2 = [[AUCellDataModel alloc] init];
    model2.iconUrl = @"APCommonUI_ForDemo.bundle/hc_popmenu_dislike.png";
    model2.titleText = @"我不感兴趣";
    model2.extendDic = @{@"type":@"reject",@"cardId":@"201609261515032720200000091128291606950000902688",@"CCard":@""};
    model2.highlightState = YES;
    AUCellDataModel * model3 = [[AUCellDataModel alloc] init];
    model3.iconUrl = @"APCommonUI_ForDemo.bundle/hc_popmenu_inform.png";
    model3.titleText = @"投诉";
    model3.extendDic = @{@"type":@"reject",@"cardId":@"201609261515032720200000091128291606950000902688",@"CCard":@""};
    AUCellDataModel * model4 = [[AUCellDataModel alloc] init];
    model4.iconUrl = @"APCommonUI_ForDemo.bundle/hc_popmenu_reject.png";
    model4.titleText = @"不再接受此类消息";
    model4.descText = @"减少此类消息的接收";
    model4.extendDic = @{@"type":@"reject",@"cardId":@"201609261515032720200000091128291606950000902688",@"CCard":@""};
    AUCardMenu *tmpView=[[AUCardMenu alloc]initWithData:@[model,model2,model3,model4] location:CGPointMake(button.width - 20, button.centerY) offset:13];
    tmpView.cellView.delegate=self;
    [tmpView showPopMenu:button animation:YES];
    self.popMenuView=tmpView;

}
- (void)handleButton:(UIButton *)button
{
    AUCellDataModel * model = [[AUCellDataModel alloc] init];
    model.iconUrl = @"APCommonUI_ForDemo.bundle/hc_popmenu_ignore.png";
    model.titleText = @"忽略";
//    model.buttonsArray = @[@"你好",@"口吃吗",@"我不饿",@"你好吗",@"我很好"];
    model.extendDic = @{@"type":@"reject",@"cardId":@"201609261515032720200000091128291606950000902688",@"CCard":@""};
    AUCellDataModel * model2 = [[AUCellDataModel alloc] init];
    model2.iconUrl = @"APCommonUI_ForDemo.bundle/hc_popmenu_dislike.png";
    model2.titleText = @"我不感兴趣";
    model2.extendDic = @{@"type":@"reject",@"cardId":@"201609261515032720200000091128291606950000902688",@"CCard":@""};
    AUCellDataModel * model3 = [[AUCellDataModel alloc] init];
    model3.iconUrl = @"APCommonUI_ForDemo.bundle/hc_popmenu_inform.png";
    model3.titleText = @"投诉";
    model3.extendDic = @{@"type":@"reject",@"cardId":@"201609261515032720200000091128291606950000902688",@"CCard":@""};
    AUCardMenu *tmpView=[[AUCardMenu alloc]initWithData:@[model,model2,model3] location:CGPointMake(button.width - 20, button.centerY) offset:13];
    tmpView.cellView.delegate=self;
    [tmpView showPopMenu:button animation:YES];
    self.popMenuView=tmpView;


}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)hidePopMenu
{
    if (self.popMenuView) {
        [self.popMenuView hidePopMenuWithAnimation:YES];
        self.popMenuView.cellView.delegate = nil;
        self.popMenuView = nil;

    }
}


#pragma mark --- AUMultiStyleCellDelegate
/**
 *  单击事件回调
 *
 *  @param dataModel 单击的 view 对应的数据模型
 *  @param indexPath 单击的 view 在 CellDataModel 中的下标(若 CellDataModel.buttonsArray == nil,则 row 默认取值为 -1)
 */
- (void)DidClickCellView:(AUCellDataModel *)dataModel ForRowAtIndexpath:(NSIndexPath *)indexPath
{
    [self hidePopMenu];
}
- (void)DidClickCellButton:(AUCellDataModel *)dataModel ForRowAtIndexpath:(NSIndexPath *)indexPath
{
    [self hidePopMenu];
}
- (void)DidClickCellView:(AUCellDataModel *)dataModel ForRowAtIndexpath:(NSIndexPath *)indexPath cellView:(AUMultiStyleCellView *)cellView
{
    [self hidePopMenu];
}


- (void)dealloc
{
    self.popMenuView = nil;

}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end