1

hitTest withEvent を使用して、マスクされた UIImageView の下にある UImageView への参照を取得しようとしています。これが私が持っているもので、機能していません:

サブビューとして 3 つの UIImageViews (panelOne、panelTwo、および panelThree) を含む UIView A。panelThree はフレーム全体を占めますが、三角形にマスクされ、パネル 1 と 2 の一部が表示されます。そのため、ユーザーがその長方形の外側をタップしたことを検出し、タッチを適切な UIImageView に送信する必要があります。

コード: (CollagePanel は UIImageView のサブクラスです)

-(void)triangleInASquare
{
    CGSize size = self.frame.size;
    CollagePanel *panelOne = [[CollagePanel alloc] initWithFrame:CGRectMake(0,0, size.width/2, size.height)];
    panelOne.panelScale = panelOne.frame.size.width/self.frame.size.width;
    panelOne.backgroundColor = [UIColor greenColor];

    CollagePanel *panelTwo = [[CollagePanel alloc] initWithFrame:CGRectMake(size.width/2,0, size.width/2, size.height)];
    panelTwo.panelScale = panelOne.frame.size.width/self.frame.size.width;
    panelTwo.backgroundColor = [UIColor purpleColor];

    CollagePanel *panelThree = [[CollagePanel alloc] initWithFrame:CGRectMake(0,0, size.width, size.height)];
    panelThree.backgroundColor = [UIColor orangeColor];

    UIBezierPath* trianglePath = [UIBezierPath bezierPath];
    [trianglePath moveToPoint:CGPointMake(0, panelThree.frame.size.height)];
    [trianglePath addLineToPoint:CGPointMake(panelThree.frame.size.width/2,0)];
    [trianglePath addLineToPoint:CGPointMake(panelThree.frame.size.width, panelTwo.frame.size.height)];
    [trianglePath closePath];

    // Mask the panels's layer to triangle.
    CAShapeLayer *triangleMaskLayer = [CAShapeLayer layer];
    [triangleMaskLayer setPath:trianglePath.CGPath];
    triangleMaskLayer.strokeColor = [[UIColor whiteColor] CGColor];
    panelThree.layer.mask = triangleMaskLayer;

    //Add border
    CAShapeLayer *borderLayer = [CAShapeLayer layer];
    borderLayer.strokeColor = [[UIColor whiteColor] CGColor];
    borderLayer.fillColor = [[UIColor clearColor] CGColor];
    borderLayer.lineWidth = 6;
    [borderLayer setPath:trianglePath.CGPath];

    [panelThree.layer addSublayer:borderLayer];

    NSMutableArray *tempArray = [[NSMutableArray alloc] init];
    [tempArray addObject:panelOne];
    [tempArray addObject:panelTwo];
    [tempArray addObject:panelThree];

    [self addGestureRecognizersToPanelsInArray:tempArray];
    [self addPanelsFromArray:tempArray];
    self.panelArray = tempArray;
}

-(void)handleTap: (UITapGestureRecognizer*) recognizer //coming from panel.imageView
{
    CGPoint tapPoint = [recognizer locationInView:self];
    NSLog(@"Location in self: %@", NSStringFromCGPoint(tapPoint));
    NSLog(@"self.subviews: %@", self.subviews);
    UIView *bottomView = [self hitTest:tapPoint withEvent:nil];
    NSLog(@"Bottom View: %@", bottomView);
}

bottomView の NSLog は常に panelThree (一番上のパネル) です。私が理解していることから、ヒットテストは「一番下」のサブビューを返す必要があります。

4

1 に答える 1

0

あなたは間違って理解しています。それ自体がタッチされたと認識し、指に最も近く、上部に近いビューを返します。
ビューが特定のポイントのタッチとして認識されない場合は、上書きする必要があります

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

そのビューのために。

Ole Begemann の Shapped Buttonは、その方法の良い例だと思います。

プロジェクトでは、このメソッドは、ポイントがパス内にあるかどうかを判断できます: CGPathContainsPoint.


次のpointInside:withEvent:ようになります。

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

@implementation CollagePanel
//
// ...
//
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    CGPoint p = [self convertPoint:point toView:[self superview]];
    if(self.layer.mask){
        if (CGPathContainsPoint([(CAShapeLayer *)self.layer.mask path], NULL, p, YES) )
            return YES;
    }else {
        if(CGRectContainsPoint(self.layer.frame, p))
            return YES;
    }
    return NO;
}

@end
于 2013-09-27T01:34:27.733 に答える