2

먼저, SO의 다른 곳에서 this very handy extension to CALayer을 확인하십시오. 레이어 내용의 한 점 (CGImageRef)이 투명한지 여부를 결정하는 데 도움이됩니다.iPhone에서가 아닌 시뮬레이터의 레이어 OK에서 알파벳 감지

n.b .: 레이어 contents이 표현 가능하거나 응답하는 것처럼 그것이 CGImageRef 인 것처럼 보장 할 수 없습니다. (위에서 언급 한 확장 기능의 광범위한 사용에 영향을 미칠 수 있습니다.) 그러나 제 경우 테스트 할 레이어가 contents이고 CGImageRef이 할당 된 것을 알고 있습니다. (희망에 따라이 일이 임무를 마치고 나 밑에서 바뀔 수는 없으며, contents이 유지된다는 사실을 알고 있습니다.)

OK. 확장 기능을 사용하는 방법은 다음과 같습니다. 우선, 내가 containsPoint:containsNonTransparentPoint:에에서 선택을 변경했습니다 (I 주위에 원래의 방법을 계속해야합니다.)

지금, 나는 일곱 개 의 CALayer 객체를 사용하는 있는 UIImageView 서브 클래스가 있습니다. 불투명도 기반 애니메이션 (펄싱/글로우 효과 및 켜기/끄기 상태)에 사용됩니다. 이 7 개의 레이어는 각각 contentsCGImageRef으로 알려져 있으며, 전체보기의 한 부분을 고유 한 색상으로 효과적으로 덮고 있습니다 (공기 인용 부호). 해당 레이어의 각 이미지의 나머지 부분은 투명합니다.

하위 클래스에서 I는 단일 탭 제스처를 등록합니다. 하나가 도착하면, 어떤 레이어가 효과적으로 도청되었는지 (즉, 어느 탭이 비어있는 지, 처음에는 하나를 찾음) 레이어를 통과 한 다음 필요한 작업을 수행 할 수 있습니다.

- (IBAction)handleSingleTap:(UIGestureRecognizer *)sender { 
    CGPoint tapPoint = [sender locationInView:sender.view]; 

    // Flip y so 0,0 is at lower left. (Required by layer method below.) 
    tapPoint.y = sender.view.bounds.size.height - tapPoint.y; 

    // Figure out which layer was effectively tapped. First match wins. 
    for (CALayer *layer in myLayers) { 
     if ([layer containsNonTransparentPoint:tapPoint]) { 
      NSLog(@"%@ tapped at (%.0f, %.0f)", layer.name, tapPoint.x, tapPoint.y); 

      // We got our layer! Do something useful with it. 
      return; 
     } 
    } 
} 

좋은 소식 : 여기

내가 제스처를 처리하는 방법은? 이 모든 기능은 iOS 4.3.2가 적용된 iPhone Simulator에서 아름답게 작동합니다. (FWIW, Xcode 4.1을 실행중인 라이온입니다.)

그러나 iPhone 4 (iOS 4.3.3)에서는 가까이 오지 않습니다! 없음 내 도청 장치의과 일치하는 것으로 보이며, 나는 그들이 기대하는 레이어 중 어느 것인가도입니다.

1x1 픽셀 컨텍스트에 드로잉 할 때 suggestion to use CGContextSetBlendMode을 사용해도 주사위가 없습니다.

필자는 파일럿 오류라고 기대하지만, 아직 불일치가 무엇인지 파악하지 못했습니다. 탭에는 패턴이 있지만 식별 할 수는 없습니다.

아마도 데이터 경계 문제가 있습니다. 아마도 y 좌표를 이미지의 왼쪽 하단으로 뒤집는 것 이외의 다른 작업을해야 할 것입니다. 아직 확실하지 않습니다.

누구나 저주받을 수있는 부분을 밝힐 수 있다면, 나는 가장 감사하게 생각합니다.

업데이트 : 2011 년 9 월 22 일 : 처음으로 아하! 문제는 Simulator-vs-iPhone이 아닙니다. 그것은 망막 대 비 망막입니다! Retina 버전을 사용할 때 시뮬레이터에서 동일한 증상이 발생합니다. 아마도 솔루션은 스케일링 (CTM?)을 중심으로/모양/형태를 중심으로 전개 될 것입니다.Quartz 2D Programming Guide는 또한 "iOS 응용 프로그램은 UIGraphicsBeginImageContextWithOptions을 사용해야한다"고 조언한다. 나는 내가 여기있는 해결책에 매우 가깝다고 느낀다!

답변

1

OK! 첫째, 문제는 Simulator-vs-iPhone이 아니 었습니다. 오히려 그것은 망막 대 비 망막이었다. Retina 버전을 사용할 때 시뮬레이터에서 동일한 증상이 발생합니다. 바로 솔루션이 스케일링과 관련이 있다고 생각하기 시작합니다.

Apple Dev Quartz 2D 포럼 (유사한 "스케일링에주의를 기울이십시오")에 대한 매우 유용한 포스트를 통해 나를 해결책으로 이끌 수있었습니다. 이제 저는 처음으로이 해결책이 좋지는 않지만 망막과 비 망막의 경우에 효과가 있다는 것을 처음으로 인정합니다. 우리는 규모에 대해 알아야 할 요컨대

// 
// Checks image at a point (and at a particular scale factor) for transparency. 
// Point must be with origin at lower-left. 
// 
BOOL ImagePointIsTransparent(CGImageRef image, CGFloat scale, CGPoint point) { 
    unsigned char pixel[1] = {0}; 

    CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 1, 
     NULL, kCGImageAlphaOnly); 
    CGContextSetBlendMode(context, kCGBlendModeCopy); 
    CGContextDrawImage(context, CGRectMake(-point.x, -point.y, 
     CGImageGetWidth(image)/scale, CGImageGetHeight(image)/scale), image); 

    CGContextRelease(context); 
    CGFloat alpha = pixel[0]/255.0; 
    return (alpha < 0.01); 
} 

@implementation CALayer (Extensions) 

- (BOOL)containsNonTransparentPoint:(CGPoint)point scale:(CGFloat)scale { 
    if (CGRectContainsPoint(self.bounds, point)) { 
     if (!ImagePointIsTransparent((CGImageRef)self.contents, scale, point)) 
      return YES; 
    } 
    return NO; 
} 

@end 

, : 그와

, 여기에 개정 된 상기 CALayer extension에 대한 코드입니다. 이미지의 너비와 높이를 해당 눈금으로 나누면 타격 테스트가 이제 망막 및 비 망막 장치에서 작동합니다!

내가 싫어하는 것은 불량 선별기에 대한 불만이며, 현재는 containsNonTransparentPoint : Scale :입니다. 이 질문에서 언급했듯이, 레이어의 내용물이 무엇을 담고 있는지 보장 할 수는 없습니다. 제 경우에는 CGImageRef가있는 레이어에서만 이것을 사용하도록주의를 기울이고 있습니다 만, 좀 더 일반적인/재사용 가능한 경우는 그렇지 않습니다.

이 모든 것이 궁극적으로 CALayer가 적어도이 새로운 구현에서이 특정 확장에 가장 적합한 장소가 아닌지 궁금합니다. 어쩌면 CGImage가 일부 레이어를 던져 버리면 더 깨끗해질 것입니다. CGImage에서 히트 테스트를하고 그 시점에서 불투명 한 내용을 가진 첫 번째 레이어의 이름을 반환한다고 상상해보십시오. 어떤 레이어에 CGImageRef가 있는지 알지 못하는 문제가 있으므로 몇 가지 힌팅이 필요할 수 있습니다. (진정으로 당신을위한 운동과 독자로 왼쪽!)

UPDATE :를 애플 개발자와 논의 후에 이런 식으로 레이어와 장난 경솔한 사실이다. 이전에 배운 것과는 달리 (잘못?), UIView 내에 캡슐화 된 여러 개의 UIImageView가 여기에있는 방법입니다. (나는 항상 당신이 당신의 견해를 최소한으로 유지하기를 원한다는 것을 기억한다. 아마도이 경우에는 큰 문제가 아니다.) 그럼에도 불구하고 나는이 답을 지금 당장 여기에서 지키지 만, 그것을 옳은 것으로 표시하지는 않을 것이다. 일단 나가서 다른 기술을 검증하면, 나는 그것을 여기에서 공유 할 것입니다!

관련 문제