需求ide
封装一个自定义的弹出菜单,有背景图片,里面也能够放置UIView,点击外部会使菜单消失
atom
头文件设计思路设计
定义协议和可选的方法,用来传递点击菜单区域之外的事件
code
初始化方法中,须要一个contentView,放在菜单的内部,菜单的frame由- (void)showInRect:(CGRect)rect;中传递的rect参数决定事件
在- (id)initWithFrame:(CGRect)frame;中添加2个属性,一个是container是一个UIImageView,默认会带有一个背景图片,cover是接收container之外区域的点击事件的一个UIButton
图片
在外部调用时,能够在contentView中加上特定的点击事件rem
// 弹出菜单 UIButton *button = [UIButton buttonWithType:UIButtonTypeContactAdd]; [button addTarget:self action:@selector(clickOnButton) forControlEvents:UIControlEventTouchUpInside]; button.backgroundColor = [UIColor redColor]; HMPopMenu *menu = [[HMPopMenu alloc ] initWithContentView:button]; menu.delegate = self; [menu showInRect:CGRectMake(100, 100, 100, 200)];
#import <UIKit/UIKit.h> @class HMPopMenu; @protocol HMPopMenuDelegate <NSObject> @optional - (void)popMenuDidDismissed:(HMPopMenu *)popMenu; @end @interface HMPopMenu : UIView @property (nonatomic, weak) id<HMPopMenuDelegate> delegate; /** * 初始化方法 */ - (instancetype)initWithContentView:(UIView *)contentView; + (instancetype)popMenuWithContentView:(UIView *)contentView; /** * 设置菜单的背景图片 */ - (void)setBackground:(UIImage *)background; /** * 显示菜单 */ - (void)showInRect:(CGRect)rect; /** * 关闭菜单 */ - (void)dismiss; @end
#import "HMPopMenu.h" @interface HMPopMenu() @property (nonatomic, strong) UIView *contentView; /** * 最底部的遮盖 :屏蔽除菜单之外控件的事件 */ @property (nonatomic, weak) UIButton *cover; /** * 容器 :容纳具体要显示的内容contentView */ @property (nonatomic, weak) UIImageView *container; @end @implementation HMPopMenu #pragma mark - 初始化方法 - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { /** 添加菜单内部的2个子控件 **/ // 添加一个遮盖按钮 UIButton *cover = [[UIButton alloc] init]; cover.backgroundColor = [UIColor clearColor]; [cover addTarget:self action:@selector(dismiss) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:cover]; self.cover = cover; // 添加带箭头的菜单图片 UIImageView *container = [[UIImageView alloc] init]; container.userInteractionEnabled = YES; container.image = [UIImage resizedImage:@"popover_background"]; [self addSubview:container]; self.container = container; } return self; } - (instancetype)initWithContentView:(UIView *)contentView { if (self = [super init]) { self.contentView = contentView; } return self; } + (instancetype)popMenuWithContentView:(UIView *)contentView { return [[self alloc] initWithContentView:contentView]; } - (void)layoutSubviews { [super layoutSubviews]; self.cover.frame = self.bounds; } #pragma mark - 内部方法 - (void)coverClick { [self dismiss]; } #pragma mark - 公共方法 - (void)setBackground:(UIImage *)background { self.container.image = background; } - (void)showInRect:(CGRect)rect { // 添加菜单总体到窗口身上 UIWindow *window = [UIApplication sharedApplication].keyWindow; self.frame = window.bounds; [window addSubview:self]; // 设置容器的frame self.container.frame = rect; [self.container addSubview:self.contentView]; // 设置容器里面内容的frame CGFloat topMargin = 12; CGFloat leftMargin = 5; CGFloat rightMargin = 5; CGFloat bottomMargin = 8; self.contentView.y = topMargin; self.contentView.x = leftMargin; self.contentView.width = self.container.width - leftMargin - rightMargin; self.contentView.height = self.container.height - topMargin - bottomMargin; } - (void)dismiss { if ([self.delegate respondsToSelector:@selector(popMenuDidDismissed:)]) { [self.delegate popMenuDidDismissed:self]; } [self removeFromSuperview]; } @end