思路:
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,就會將該按鈕畫成六邊形了,並且可點擊訪問也是在六邊形內。