iOS_UIButton可點範圍爲六邊形

思路:

1、創建UIButton分類,重寫layoutSubviews方法;

2、繪製六邊形路徑,將繪製的六邊形path賦值給新建的CAShapeLayer;

3、將新建的CAShapeLayer覆蓋self.layer.mask。

4、重寫hitTest方法:判斷點擊的point是否在六邊形path內。

具體代碼如下:

 

#import <UIKit/UIKit.h>

@interface UIButton (Extension)

@property (nonatomic, assign) BOOL drawHexagon;    // 是否繪製六邊形

@end

 

#import "UIButton+Extension.h"
#import <objc/runtime.h>

@interface UIButton ()
@property (nonatomic, strong) UIBezierPath *path;
@end

@implementation UIButton (Extension)

// 利用runtime爲category生成setter和getter
- (void)setPath:(UIBezierPath *)path {
    objc_setAssociatedObject(self, @"path", path, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIBezierPath *)path {
    return objc_getAssociatedObject(self, @"path");
}

- (void)setDrawHexagon:(BOOL)drawHexagon {
    objc_setAssociatedObject(self, @"drawHexagon", @(drawHexagon), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)drawHexagon {
    NSNumber *num = objc_getAssociatedObject(self, @"drawHexagon");
    return num.boolValue;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    NSLog(@"drawHexagon %i", self.drawHexagon);
    if (self.drawHexagon) {
        CGFloat width = self.frame.size.width;
        CGFloat longSide = width * 0.5 * cosf(M_PI * 30 / 180);
        CGFloat shortSide = width * 0.5 * sin(M_PI * 30 / 180);
        CGFloat k = width * 0.5 - longSide;     // 爲了使個邊相等
        
        // 繪製六邊形曲線 6個點
        self.path = [UIBezierPath bezierPath];
        [self.path moveToPoint:CGPointMake(0, longSide  + k)];
        [self.path addLineToPoint:CGPointMake(shortSide, + k)];
        [self.path addLineToPoint:CGPointMake(shortSide + shortSide + shortSide,  k)];
        [self.path addLineToPoint:CGPointMake(width, longSide + k)];
        [self.path addLineToPoint:CGPointMake(shortSide * 3, longSide * 2 + k)];
        [self.path addLineToPoint:CGPointMake(shortSide, longSide * 2 + k)];
        [self.path closePath];
        
        CAShapeLayer *maskLayer = [CAShapeLayer layer];
        maskLayer.path = [self.path CGPath];
        
        self.layer.mask = maskLayer;
    }
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    // 判斷點擊的point 是否在六邊形內
    if (CGPathContainsPoint(self.path.CGPath, NULL, point, NO)) {
        return [super hitTest:point withEvent:event];
    }
    return nil;
}

@end

導入該分類,將button的屬性drawHexagon設爲YES,就會將該按鈕畫成六邊形了,並且可點擊訪問也是在六邊形內。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章