iphone自定义弹出式菜单(popoverView)

    在调用的地方如下代码调用:


    NSArray *menuList, *imgList;

    NSMutableArray *menuItems = [[NSMutableArray allocinit];


    menuList = @[@"扫一扫",@"设置",@"分享",@"退出"];

    imgList = @[@"扫一扫.png",@"设置.png",@"分享.png",@"退出.png"];

    

    for (int i = 0; i < menuList.count; i++)

    {

        [menuItems addObject:[KxMenuItem menuItem:menuList[i]

                                           image:[UIImage imageNamed:imgList[i]]

                                          target:self

                                           action:@selector(pushMenuItem:)]];

    }

    

    CGRect rect = CGRectMake(2906400);

    [KxMenu showMenuInView:self.view

                  fromRect:rect

                 menuItems:menuItems];


//回调方法

- (void)pushMenuItem:(id)sender

{

    NSLog(@"%@", sender);

}


----------------------------------------------------------------------------------------------------------


#import <Foundation/Foundation.h>


@interface KxMenuItem : NSObject


@property (readwritenonatomicstrongUIImage *image;

@property (readwritenonatomicstrongNSString *title;

@property (readwritenonatomicweakid target;

@property (readwritenonatomicSEL action;

@property (readwritenonatomicstrongUIColor *foreColor;

@property (readwritenonatomicNSTextAlignment 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;

        

        UITapGestureRecognizer *gestureRecognizer;

        gestureRecognizer = [[UITapGestureRecognizer allocinitWithTarget:self

                                                                    action:@selector(singleTap:)];

        [self addGestureRecognizer:gestureRecognizer];

    }

    return self;

}


- (void)singleTap:(UITapGestureRecognizer *)recognizer

{

    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 allocinit: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(22);

        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;

    

    const CGFloat kMargin = 5.f;

    

    if (heightPlusArrow < (outerHeight - rectY1)) {

    

        _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){kArrowSize0, 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

{

    _menuItems = menuItems;

    

    _contentView = [self mkContentView];

    [self addSubview:_contentView];

    

    [self setupFrameInView:view fromRect:rect];

        

    KxMenuOverlay *overlay = [[KxMenuOverlay allocinitWithFrame:view.bounds];

    [overlay addSubview:self];

    [view addSubview:overlay];

    

    _contentView.hidden = YES;

    const CGRect toFrame = self.frame;

    self.frame = (CGRect){self.arrowPoint11};

    

    [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.arrowPoint11};

            

            [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 preferredFontForTextStyle:UIFontTextStyleCaption1];

    

    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 = 20;

    }

    

    if (maxImageWidth) {

        maxImageWidth += 0;

    }

    

    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 > 20 ? 20 : imageSize.height) + kMarginY * 2;

        const CGFloat itemWidth = ((!menuItem.enabled && !menuItem.image) ? titleSize.width : maxImageWidth + 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;

    const CGFloat titleWidth = maxItemWidth - titleX - kMarginX * 2;

    

    UIImage *selectedImage = [KxMenuView selectedImage:(CGSize){maxItemWidth, maxItemHeight + 2}];

    UIImage *gradientLine = [KxMenuView gradientLine: (CGSize){maxItemWidth - kMarginX * 21}];

    

    UIView *contentView = [[UIView allocinitWithFrame: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 allocinitWithFrame: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,

                    20

                };

                

            } else {

                

                titleFrame = (CGRect){

                    titleX,

                    kMarginY,

                    titleWidth,

                    20

                };

            }

            

            UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleFrame];

            titleLabel.text = menuItem.title;

            titleLabel.font = titleFont;

            titleLabel.textAlignment = menuItem.alignment;

            titleLabel.textColor = menuItem.foreColor ? menuItem.foreColor : [UIColor blackColor];

            titleLabel.backgroundColor = [UIColor clearColor];

            titleLabel.autoresizingMask = UIViewAutoresizingNone;

            [itemView addSubview:titleLabel];

        }

        

        if (menuItem.image) {

            

            const CGRect imageFrame = {kMarginX , kMarginY, maxImageWidth, maxImageWidth};

            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 , kMarginY * 2 + maxImageWidth + 1 , gradientLine.size};

            gradientView.contentMode = UIViewContentModeLeft;

            [itemView addSubview:gradientView];

            

            itemY += 2;

        }

        

        itemY += maxImageWidth + kMarginY * 2;

        ++itemNum;

    }    

    

    contentView.frame = (CGRect){00, 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.2160.4710.8711,

        0.0590.3530.8391,

    };

    

    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

    };

    

    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, NO0);

    CGContextRef context = UIGraphicsGetCurrentContext();

    

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGGradientRef colorGradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 2);

    CGColorSpaceRelease(colorSpace);

    CGContextDrawLinearGradient(context, colorGradient, (CGPoint){00}, (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.995, G0 = 0.995, B0 = 0.995;

    CGFloat R1 = 0.925, G1 = 0.925, B1 = 0.925;

    

    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];

    

    // 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:1] 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;

        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:1] 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:1] 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:1] set];

        

        X1 -= kArrowSize;

    }

    

    [arrowPath fill];


    // render body

    

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

    

    UIBezierPath *borderPath = [UIBezierPath bezierPathWithRoundedRect:bodyFrame

                                                          cornerRadius:8];

        

    const CGFloat locations[] = {01};

    const CGFloat components[] = {

        R0, G0, B0, 1,

        R1, G1, B1, 1,

    };

    

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace,

                                                                 components,

                                                                 locations,

                                                                 sizeof(locations)/sizeof(locations[0]));

    CGColorSpaceRelease(colorSpace);

    

    

    [borderPath addClip];

    

    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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值