我有这样的观点:
// .h file
@interface LayerBubbleView : UIView
/**
* click handler
*/
@property (nonatomic, copy) void (^clickHandler)(NSString* identifier, CAShapeLayer* layer);
-(instancetype)initWithFrame:(CGRect)frame withDataArray:(NSArray *)dataArray;
@end
// .m file
#import "BDPLayerBubbleView.h"
@interface BDPLayerBubbleView ()
@property (nonatomic, strong) NSMutableArray *paths;
@property (nonatomic, strong) NSMutableArray *identifiers;
@end
@implementation BDPLayerBubbleView
-(instancetype)initWithFrame:(CGRect)frame withDataArray:(NSArray *)dataArray {
self = [self initWithFrame:frame];
if (self) {
_paths = [[NSMutableArray alloc] init];
_identifiers = [[NSMutableArray alloc] init];
for (int i = 0; i < dataArray.count; i++) {
NSArray *data = dataArray[i];
CGRect frame = [data[0] CGRectValue]; // please ignore here, just for demo
CGFloat radius = [data[1] doubleValue];
CGPoint center = [data[2] CGPointValue];
UIColor *fillColor = data[3];
UIColor *borderColor = data[4];
NSString *identifier = data[5];
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:frame cornerRadius:radius];
[_paths addObject:bezierPath];
[_identifiers addObject:identifier];
shapeLayer.path = [bezierPath CGPath];
shapeLayer.strokeColor = [borderColor CGColor];
shapeLayer.fillColor = [fillColor CGColor];
shapeLayer.lineWidth = 0.5;
shapeLayer.bounds = frame;
shapeLayer.position = center;
[self.layer addSublayer:shapeLayer];
}
}
return self;
}
#pragma mark - Touch handling
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint touchPoint = [touch locationInView:self];
for(int i=0;i<[_paths count];i++) {
UIBezierPath* path = _paths[i];
CAShapeLayer *shapeLayer = self.layer.sublayers[i];
if ([path containsPoint:touchPoint] || [shapeLayer containsPoint:touchPoint])
{
NSString *identifier = _identifiers[i];
if([self.layer.sublayers[i] isKindOfClass:CAShapeLayer.class] && [identifier length] > 0) {
CAShapeLayer* l = self.layer.sublayers[i];
if(_clickHandler) {
_clickHandler(identifier, l);
}
}
}
}
}
逻辑是,视图上有很多气泡层,当用户点击气泡时,我可以检测到哪个气泡层用户点击,这样我就可以触发相应的clickHandler并突出显示气泡层。
但是,[path containsPoint:touchPoint]
和[shapeLayer containsPoint:touchPoint]
都不会为所有子图层返回YES。我不确定我的代码有什么问题?
所以我建议使用CGPathContainsPoint
和CGRectContainsPoint
进行检测。我测试过,CGPathContainsPoint
在CGRectContainsPoint
DID工作时无效。
我现在对CG API和UIKit包装API之间的差异感到困惑。任何专家都能解释一下吗?我仍然希望containsPoint
能够发挥作用。