需求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