您的位置:首页 > 运维架构

iPhone->类似于popoverView的一个菜单组件

2015-12-04 18:03 190 查看

一.说明

在iPad上,苹果提供的有专门的菜单显示的控制器。而在iphone上却没有。所以需要我们自定义。下面就是我所介绍的这么一个菜单组件的大概样子:
![组件概览](http://img.blog.csdn.net/20151204180632512)


二.组件代码

KxMenu.h

#import <Foundation/Foundation.h>

@interface KxMenuItem : NSObject

@property (readwrite, nonatomic, strong) UIImage *image;
@property (readwrite, nonatomic, strong) NSString *title;
@property (readwrite, nonatomic) id target;
@property (readwrite, nonatomic) SEL action;
@property (readwrite, nonatomic, strong) UIColor *foreColor;
@property (readwrite, nonatomic) NSTextAlignment alignment;

+ (instancetype) menuItem:(NSString *) title
image:(UIImage *) image
target:(id)target
action:(SEL) action;

@end

@interface KxMenu : NSObject

+ (void) showMenuInView:(UIView *)view
fromRect:(CGRect)rect
menuItems:(NSArray *)menuItems;

+ (void) dismissMenu;

+ (UIColor *) tintColor;
+ (void) setTintColor: (UIColor *) tintColor;

+ (UIFont *) titleFont;
+ (void) setTitleFont: (UIFont *) titleFont;

@end


#import "KxMenu.h"
#import <QuartzCore/QuartzCore.h>

const CGFloat kArrowSize = 12.f;

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

@interface KxMenuView : UIView
@end

@interface KxMenuOverlay : UIView
@end

@implementation KxMenuOverlay

// - (void) dealloc { NSLog(@"dealloc %@", self); }

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.opaque = NO;
}
return self;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UIView *touched = [[touches anyObject] view];
if (touched == self) {

for (UIView *v in self.subviews) {
if ([v isKindOfClass:[KxMenuView class]]
&& [v respondsToSelector:@selector(dismissMenu:)]) {

[v performSelector:@selector(dismissMenu:) withObject:@(YES)];
}
}
}
}

@end

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

@implementation KxMenuItem

+ (instancetype) menuItem:(NSString *) title
image:(UIImage *) image
target:(id)target
action:(SEL) action
{
return [[KxMenuItem alloc] init:title
image:image
target:target
action:action];
}

- (id) init:(NSString *) title
image:(UIImage *) image
target:(id)target
action:(SEL) action
{
NSParameterAssert(title.length || image);

self = [super init];
if (self) {

_title = title;
_image = image;
_target = target;
_action = action;
}
return self;
}

- (BOOL) enabled
{
return _target != nil && _action != NULL;
}

- (void) performAction
{
__strong id target = self.target;

if (target && [target respondsToSelector:_action]) {

[target performSelectorOnMainThread:_action withObject:self waitUntilDone:YES];
}
}

- (NSString *) description
{
return [NSString stringWithFormat:@"<%@ #%p %@>", [self class], self, _title];
}

@end

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

typedef enum {

KxMenuViewArrowDirectionNone,
KxMenuViewArrowDirectionUp,
KxMenuViewArrowDirectionDown,
KxMenuViewArrowDirectionLeft,
KxMenuViewArrowDirectionRight,

} KxMenuViewArrowDirection;

@implementation KxMenuView {

KxMenuViewArrowDirection    _arrowDirection;
CGFloat                     _arrowPosition;
UIView                      *_contentView;
NSArray                     *_menuItems;
}

- (id)init
{
self = [super initWithFrame:CGRectZero];
if(self) {

self.backgroundColor = [UIColor clearColor];
self.opaque = YES;
self.alpha = 0;

//        self.layer.shadowOpacity = 0.5;
//        self.layer.shadowOffset = CGSizeMake(2, 2);
//        self.layer.shadowRadius = 2;
}

return self;
}

// - (void) dealloc { NSLog(@"dealloc %@", self); }

- (void) setupFrameInView:(UIView *)view
fromRect:(CGRect)fromRect
{
const CGSize contentSize = _contentView.frame.size;

const CGFloat outerWidth = view.bounds.size.width;
const CGFloat outerHeight = view.bounds.size.height;

const CGFloat rectX0 = fromRect.origin.x;
const CGFloat rectX1 = fromRect.origin.x + fromRect.size.width;
const CGFloat rectXM = fromRect.origin.x + fromRect.size.width * 0.5f;
const CGFloat rectY0 = fromRect.origin.y;
const CGFloat rectY1 = fromRect.origin.y + fromRect.size.height;
const CGFloat rectYM = fromRect.origin.y + fromRect.size.height * 0.5f;;

const CGFloat widthPlusArrow = contentSize.width + kArrowSize;
const CGFloat heightPlusArrow = contentSize.height + kArrowSize;
const CGFloat widthHalf = contentSize.width * 0.5f;
const CGFloat heightHalf = contentSize.height * 0.5f;
// NSLog(@"%f   %f   %f  \n%f  %f  %f  \n%f  %f   \n%f  %f",rectX0,rectX1,rectXM,rectY0,rectY1,rectYM,widthPlusArrow,heightPlusArrow,outerWidth,outerHeight);
const CGFloat kMargin = 5.f;

if (heightPlusArrow < (outerHeight - rectY1)) {

if(rectX0 <= 0)
{
_arrowDirection = KxMenuViewArrowDirectionLeft;
CGPoint point = (CGPoint){
rectX1,
rectYM - heightHalf
};

if (point.y < kMargin)
point.y = kMargin;

if ((point.y + contentSize.height + kMargin) > outerHeight)
point.y = outerHeight - contentSize.height - kMargin;

_arrowPosition = rectYM - point.y;
_contentView.frame = (CGRect){kArrowSize, 0, contentSize};

self.frame = (CGRect) {
point,
contentSize.width + kArrowSize,
contentSize.height
};
}
else
{
_arrowDirection = KxMenuViewArrowDirectionUp;
CGPoint point = (CGPoint){
rectXM - widthHalf,
rectY1
};

if (point.x < kMargin)
point.x = kMargin;

if ((point.x + contentSize.width + kMargin) > outerWidth)
point.x = outerWidth - contentSize.width - kMargin;

_arrowPosition = rectXM - point.x;
//_arrowPosition = MAX(16, MIN(_arrowPosition, contentSize.width - 16));
_contentView.frame = (CGRect){0, kArrowSize, contentSize};

self.frame = (CGRect) {

point,
contentSize.width,
contentSize.height + kArrowSize
};
}

} else if (heightPlusArrow < rectY0) {

_arrowDirection = KxMenuViewArrowDirectionDown;
CGPoint point = (CGPoint){
rectXM - widthHalf,
rectY0 - heightPlusArrow
};

if (point.x < kMargin)
point.x = kMargin;

if ((point.x + contentSize.width + kMargin) > outerWidth)
point.x = outerWidth - contentSize.width - kMargin;

_arrowPosition = rectXM - point.x;
_contentView.frame = (CGRect){CGPointZero, contentSize};

self.frame = (CGRect) {

point,
contentSize.width,
contentSize.height + kArrowSize
};

} else if (widthPlusArrow < (outerWidth - rectX1)) {

_arrowDirection = KxMenuViewArrowDirectionLeft;
CGPoint point = (CGPoint){
rectX1,
rectYM - heightHalf
};

if (point.y < kMargin)
point.y = kMargin;

if ((point.y + contentSize.height + kMargin) > outerHeight)
point.y = outerHeight - contentSize.height - kMargin;

_arrowPosition = rectYM - point.y;
_contentView.frame = (CGRect){kArrowSize, 0, contentSize};

self.frame = (CGRect) {

point,
contentSize.width + kArrowSize,
contentSize.height
};

} else if (widthPlusArrow < rectX0) {

_arrowDirection = KxMenuViewArrowDirectionRight;
CGPoint point = (CGPoint){
rectX0 - widthPlusArrow,
rectYM - heightHalf
};

if (point.y < kMargin)
point.y = kMargin;

if ((point.y + contentSize.height + 5) > outerHeight)
point.y = outerHeight - contentSize.height - kMargin;

_arrowPosition = rectYM - point.y;
_contentView.frame = (CGRect){CGPointZero, contentSize};

self.frame = (CGRect) {

point,
contentSize.width  + kArrowSize,
contentSize.height
};

} else {

_arrowDirection = KxMenuViewArrowDirectionNone;

self.frame = (CGRect) {

(outerWidth - contentSize.width)   * 0.5f,
(outerHeight - contentSize.height) * 0.5f,
contentSize,
};
}
}

- (void)showMenuInView:(UIView *)view
fromRect:(CGRect)rect
menuItems:(NSArray *)menuItems
{
if (_menuItems)
{
[_menuItems release];
_menuItems = Nil;
}
_menuItems = menuItems.copy;

_contentView = [self mkContentView];
[self addSubview:_contentView];

[self setupFrameInView:view fromRect:rect];

KxMenuOverlay *overlay = [[KxMenuOverlay alloc] initWithFrame:view.bounds];
[overlay addSubview:self];
[view addSubview:overlay];

_contentView.hidden = YES;
const CGRect toFrame = self.frame;
self.frame = (CGRect){self.arrowPoint, 1, 1};

[UIView animateWithDuration:0.2
animations:^(void) {

self.alpha = 1.0f;
self.frame = toFrame;

} completion:^(BOOL completed) {
_contentView.hidden = NO;
}];

}

- (void)dismissMenu:(BOOL) animated
{
if (self.superview) {

if (animated) {

_contentView.hidden = YES;
const CGRect toFrame = (CGRect){self.arrowPoint, 1, 1};

[UIView animateWithDuration:0.2
animations:^(void) {

self.alpha = 0;
self.frame = toFrame;

} completion:^(BOOL finished) {

if ([self.superview isKindOfClass:[KxMenuOverlay class]])
[self.superview removeFromSuperview];
[self removeFromSuperview];
}];

} else {

if ([self.superview isKindOfClass:[KxMenuOverlay class]])
[self.superview removeFromSuperview];
[self removeFromSuperview];
}
}
}

- (void)performAction:(id)sender
{
[self dismissMenu:YES];

UIButton *button = (UIButton *)sender;
KxMenuItem *menuItem = _menuItems[button.tag];
[menuItem performAction];
}

- (UIView *) mkContentView
{
for (UIView *v in self.subviews) {
[v removeFromSuperview];
}

if (!_menuItems.count)
return nil;

const CGFloat kMinMenuItemHeight = 32.f;
const CGFloat kMinMenuItemWidth = 32.f;
const CGFloat kMarginX = 10.f;
const CGFloat kMarginY = 5.f;

UIFont *titleFont = [KxMenu titleFont];
if (!titleFont) titleFont = [UIFont boldSystemFontOfSize:16];

CGFloat maxImageWidth = 0;
CGFloat maxItemHeight = 0;
CGFloat maxItemWidth = 0;

for (KxMenuItem *menuItem in _menuItems) {

const CGSize imageSize = menuItem.image.size;
if (imageSize.width > maxImageWidth)
maxImageWidth = imageSize.width;
}

for (KxMenuItem *menuItem in _menuItems) {

const CGSize titleSize = [menuItem.title sizeWithFont:titleFont];
const CGSize imageSize = menuItem.image.size;

const CGFloat itemHeight = MAX(titleSize.height, imageSize.height) + kMarginY * 2;
const CGFloat itemWidth = (menuItem.image ? maxImageWidth + kMarginX : 0) + titleSize.width + kMarginX * 4;

if (itemHeight > maxItemHeight)
maxItemHeight = itemHeight;

if (itemWidth > maxItemWidth)
maxItemWidth = itemWidth;
}

maxItemWidth  = MAX(maxItemWidth, kMinMenuItemWidth);
maxItemHeight = MAX(maxItemHeight, kMinMenuItemHeight);

const CGFloat titleX = kMarginX * 2 + (maxImageWidth > 0 ? maxImageWidth + kMarginX : 0);
const CGFloat titleWidth = maxItemWidth - titleX - kMarginX;

UIImage *selectedImage = [KxMenuView selectedImage:(CGSize){maxItemWidth, maxItemHeight + 2}];
UIImage *gradientLine = [KxMenuView gradientLine: (CGSize){maxItemWidth - kMarginX * 4, 1}];

UIView *contentView = [[UIView alloc] initWithFrame:CGRectZero];
contentView.autoresizingMask = UIViewAutoresizingNone;
contentView.backgroundColor = [UIColor clearColor];
contentView.opaque = NO;

CGFloat itemY = kMarginY * 2;
NSUInteger itemNum = 0;

for (KxMenuItem *menuItem in _menuItems) {

const CGRect itemFrame = (CGRect){0, itemY, maxItemWidth, maxItemHeight};

UIView *itemView = [[UIView alloc] initWithFrame:itemFrame];
itemView.autoresizingMask = UIViewAutoresizingNone;
itemView.backgroundColor = [UIColor clearColor];
itemView.opaque = NO;

[contentView addSubview:itemView];

if (menuItem.enabled) {

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.tag = itemNum;
button.frame = itemView.bounds;
button.enabled = menuItem.enabled;
button.backgroundColor = [UIColor clearColor];
button.opaque = NO;
button.autoresizingMask = UIViewAutoresizingNone;

[button addTarget:self
action:@selector(performAction:)
forControlEvents:UIControlEventTouchUpInside];

[button setBackgroundImage:selectedImage forState:UIControlStateHighlighted];

[itemView addSubview:button];
}

if (menuItem.title.length) {

CGRect titleFrame;

if (!menuItem.enabled && !menuItem.image) {

titleFrame = (CGRect){
kMarginX * 2,
kMarginY,
maxItemWidth - kMarginX * 4,
maxItemHeight - kMarginY * 2
};

} else {

titleFrame = (CGRect){
titleX,
kMarginY,
titleWidth,
maxItemHeight - kMarginY * 2
};
}

UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleFrame];
titleLabel.text = menuItem.title;
titleLabel.font = titleFont;
titleLabel.textAlignment = menuItem.alignment;
titleLabel.textColor = menuItem.foreColor ? menuItem.foreColor : [UIColor whiteColor];
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.autoresizingMask = UIViewAutoresizingNone;
//titleLabel.backgroundColor = [UIColor greenColor];
[itemView addSubview:titleLabel];
}

if (menuItem.image) {

const CGRect imageFrame = {kMarginX * 2, kMarginY, maxImageWidth, maxItemHeight - kMarginY * 2};
UIImageView *imageView = [[UIImageView alloc] initWithFrame:imageFrame];
imageView.image = menuItem.image;
imageView.clipsToBounds = YES;
imageView.contentMode = UIViewContentModeCenter;
imageView.autoresizingMask = UIViewAutoresizingNone;
[itemView addSubview:imageView];
}

if (itemNum < _menuItems.count - 1) {

UIImageView *gradientView = [[UIImageView alloc] initWithImage:gradientLine];
gradientView.frame = (CGRect){kMarginX * 2, maxItemHeight + 1, gradientLine.size};
gradientView.contentMode = UIViewContentModeLeft;
[itemView addSubview:gradientView];

itemY += 2;
}

itemY += maxItemHeight;
++itemNum;
}

contentView.frame = (CGRect){0, 0, maxItemWidth, itemY + kMarginY * 2};

return contentView;
}

- (CGPoint) arrowPoint
{
CGPoint point;

if (_arrowDirection == KxMenuViewArrowDirectionUp) {

point = (CGPoint){ CGRectGetMinX(self.frame) + _arrowPosition, CGRectGetMinY(self.frame) };

} else if (_arrowDirection == KxMenuViewArrowDirectionDown) {

point = (CGPoint){ CGRectGetMinX(self.frame) + _arrowPosition, CGRectGetMaxY(self.frame)};

} else if (_arrowDirection == KxMenuViewArrowDirectionLeft) {

point = (CGPoint){ CGRectGetMinX(self.frame), CGRectGetMinY(self.frame) + _arrowPosition  };

} else if (_arrowDirection == KxMenuViewArrowDirectionRight) {

point = (CGPoint){ CGRectGetMaxX(self.frame), CGRectGetMinY(self.frame) + _arrowPosition  };

} else {

point = self.center;
}

return point;
}

+ (UIImage *) selectedImage: (CGSize) size
{
const CGFloat locations[] = {0,1};
const CGFloat components[] = {
0.216, 0.471, 0.871, 1,
0.059, 0.353, 0.839, 1,
};

return [self gradientImageWithSize:size locations:locations components:components count:2];
}

+ (UIImage *) gradientLine: (CGSize) size
{
const CGFloat locations[5] = {0,0.2,0.5,0.8,1};

//    const CGFloat R = 0.44f, G = 0.44f, B = 0.44f;
//
//    const CGFloat components[20] = {
//        R,G,B,0.1,
//        R,G,B,0.4,
//        R,G,B,0.7,
//        R,G,B,0.4,
//        R,G,B,0.1
//    };
const CGFloat R = 0, G = 0, B = 0;
const CGFloat components[20] =
{
R,G,B,0.2,
R,G,B,0.2,
R,G,B,0.2,
R,G,B,0.2,
R,G,B,0.2
};
return [self gradientImageWithSize:size locations:locations components:components count:5];
}

+ (UIImage *) gradientImageWithSize:(CGSize) size
locations:(const CGFloat []) locations
components:(const CGFloat []) components
count:(NSUInteger)count
{
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef colorGradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 2);
CGColorSpaceRelease(colorSpace);
CGContextDrawLinearGradient(context, colorGradient, (CGPoint){0, 0}, (CGPoint){size.width, 0}, 0);
CGGradientRelease(colorGradient);

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

- (void) drawRect:(CGRect)rect
{
[self drawBackground:self.bounds
inContext:UIGraphicsGetCurrentContext()];
}

- (void)drawBackground:(CGRect)frame
inContext:(CGContextRef) context
{
CGFloat R0 = 0.267, G0 = 0.303, B0 = 0.335;
CGFloat R1 = 0.040, G1 = 0.040, B1 = 0.040;

UIColor *tintColor = [KxMenu tintColor];
if (tintColor) {

CGFloat a;
[tintColor getRed:&R0 green:&G0 blue:&B0 alpha:&a];
}

CGFloat X0 = frame.origin.x;
CGFloat X1 = frame.origin.x + frame.size.width;
CGFloat Y0 = frame.origin.y;
CGFloat Y1 = frame.origin.y + frame.size.height;

// render arrow

UIBezierPath *arrowPath = [UIBezierPath bezierPath];
[[UIColor whiteColor]setStroke];
// fix the issue with gap of arrow's base if on the edge
const CGFloat kEmbedFix = 3.f;

if (_arrowDirection == KxMenuViewArrowDirectionUp) {

const CGFloat arrowXM = _arrowPosition;
const CGFloat arrowX0 = arrowXM - kArrowSize;
const CGFloat arrowX1 = arrowXM + kArrowSize;
const CGFloat arrowY0 = Y0;
const CGFloat arrowY1 = Y0 + kArrowSize + kEmbedFix;

[arrowPath moveToPoint:    (CGPoint){arrowXM, arrowY0}];
[arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY1}];
[arrowPath addLineToPoint: (CGPoint){arrowX0, arrowY1}];
[arrowPath addLineToPoint: (CGPoint){arrowXM, arrowY0}];

[[UIColor colorWithRed:R0 green:G0 blue:B0 alpha:0.4] set];

Y0 += kArrowSize;

} else if (_arrowDirection == KxMenuViewArrowDirectionDown) {

const CGFloat arrowXM = _arrowPosition;
const CGFloat arrowX0 = arrowXM - kArrowSize;
const CGFloat arrowX1 = arrowXM + kArrowSize;
const CGFloat arrowY0 = Y1 - kArrowSize - kEmbedFix + 3.f;
const CGFloat arrowY1 = Y1;

[arrowPath moveToPoint:    (CGPoint){arrowXM, arrowY1}];
[arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY0}];
[arrowPath addLineToPoint: (CGPoint){arrowX0, arrowY0}];
[arrowPath addLineToPoint: (CGPoint){arrowXM, arrowY1}];

[[UIColor colorWithRed:R1 green:G1 blue:B1 alpha:0.4] set];

Y1 -= kArrowSize;

} else if (_arrowDirection == KxMenuViewArrowDirectionLeft) {

const CGFloat arrowYM = _arrowPosition;
const CGFloat arrowX0 = X0;
const CGFloat arrowX1 = X0 + kArrowSize + kEmbedFix;
const CGFloat arrowY0 = arrowYM - kArrowSize;;
const CGFloat arrowY1 = arrowYM + kArrowSize;

[arrowPath moveToPoint:    (CGPoint){arrowX0, arrowYM}];
[arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY0}];
[arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY1}];
[arrowPath addLineToPoint: (CGPoint){arrowX0, arrowYM}];

[[UIColor colorWithRed:R0 green:G0 blue:B0 alpha:0.4] set];

X0 += kArrowSize;

} else if (_arrowDirection == KxMenuViewArrowDirectionRight) {

const CGFloat arrowYM = _arrowPosition;
const CGFloat arrowX0 = X1;
const CGFloat arrowX1 = X1 - kArrowSize - kEmbedFix;
const CGFloat arrowY0 = arrowYM - kArrowSize;;
const CGFloat arrowY1 = arrowYM + kArrowSize;

[arrowPath moveToPoint:    (CGPoint){arrowX0, arrowYM}];
[arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY0}];
[arrowPath addLineToPoint: (CGPoint){arrowX1, arrowY1}];
[arrowPath addLineToPoint: (CGPoint){arrowX0, arrowYM}];

[[UIColor colorWithRed:R1 green:G1 blue:B1 alpha:0.4] set];

X1 -= kArrowSize;
}

[arrowPath fill];
[arrowPath stroke];
// render body

const CGRect bodyFrame = {X0, Y0, X1 - X0, Y1 - Y0};

UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect:bodyFrame
cornerRadius:8];

const CGFloat locations[] = {0, 1};
const CGFloat components[] = {
R0, G0, B0, 0.4,
R1, G1, B1, 0.4,
};

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace,
components,
locations,
sizeof(locations)/sizeof(locations[0]));
CGColorSpaceRelease(colorSpace);

[borderPath addClip];
[borderPath stroke];

CGPoint start, end;

if (_arrowDirection == KxMenuViewArrowDirectionLeft ||
_arrowDirection == KxMenuViewArrowDirectionRight) {

start = (CGPoint){X0, Y0};
end = (CGPoint){X1, Y0};

} else {

start = (CGPoint){X0, Y0};
end = (CGPoint){X0, Y1};
}

CGContextDrawLinearGradient(context, gradient, start, end, 0);

CGGradientRelease(gradient);
}

@end

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

static KxMenu *gMenu;
static UIColor *gTintColor;
static UIFont *gTitleFont;

@implementation KxMenu {

KxMenuView *_menuView;
BOOL        _observing;
}

+ (instancetype) sharedMenu
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{

gMenu = [[KxMenu alloc] init];
});
return gMenu;
}

- (id) init
{
NSAssert(!gMenu, @"singleton object");

self = [super init];
if (self) {
}
return self;
}

- (void) dealloc
{
if (_observing) {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}

- (void) showMenuInView:(UIView *)view
fromRect:(CGRect)rect
menuItems:(NSArray *)menuItems
{
NSParameterAssert(view);
NSParameterAssert(menuItems.count);

if (_menuView) {

[_menuView dismissMenu:NO];
_menuView = nil;
}

if (!_observing) {

_observing = YES;

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(orientationWillChange:)
name:UIApplicationWillChangeStatusBarOrientationNotification
object:nil];
}

_menuView = [[KxMenuView alloc] init];
[_menuView showMenuInView:view fromRect:rect menuItems:menuItems];
}

- (void) dismissMenu
{
if (_menuView) {

[_menuView dismissMenu:NO];
_menuView = nil;
}

if (_observing) {

_observing = NO;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
}

- (void) orientationWillChange: (NSNotification *) n
{
[self dismissMenu];
}

+ (void) showMenuInView:(UIView *)view
fromRect:(CGRect)rect
menuItems:(NSArray *)menuItems
{
[[self sharedMenu] showMenuInView:view fromRect:rect menuItems:menuItems];
}

+ (void) dismissMenu
{
[[self sharedMenu] dismissMenu];
}

+ (UIColor *) tintColor
{
return gTintColor;
}

+ (void) setTintColor: (UIColor *) tintColor
{
if (tintColor != gTintColor) {
gTintColor = tintColor;
}
}

+ (UIFont *) titleFont
{
return gTitleFont;
}

+ (void) setTitleFont: (UIFont *) titleFont
{
if (titleFont != gTitleFont) {
gTitleFont = titleFont;
}
}

@end


三.具体用法

其用法非常简单,只需要在项目中导入以上文件。然后构造参数调用之:

以下代码的目的是让菜单显示在m_addbutton的下方:

CGRect addbtnframe = m_popupload.m_addbutton.frame;
CGRect frame = CGRectMake(addbtnframe.origin.x, addbtnframe.origin.y-30, addbtnframe.size.width, addbtnframe.size.height);
//frame.size.width -= 90;
NSArray *menuItems =
@[
[KxMenuItem menuItem:NSLocalizedString(@"Album",nil)
image:nil//[UIImage imageNamed:@"action_icon"]
target:self
action:@selector(layonAlbumPicker)],
[KxMenuItem menuItem:NSLocalizedString(@"Voice Memos",nil)
image:nil//[UIImage imageNamed:@"check_icon"]
target:self
action:@selector(layonVoiceMemos)],
[KxMenuItem menuItem:@"哈哈哈"
image:nil
target:self
action:nil]

];
[KxMenu showMenuInView:m_popupload.view
fromRect:frame
menuItems:menuItems];
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: