首先,从 SO 的其他地方查看这个非常方便的CALayer扩展。它可以帮助您确定图层内容分配的CGImageRef中的点是否中的某个点是否透明。
注意:不能保证图层contents
可以表示或响应,就好像它是CGImageRef 一样。(这可能对更广泛地使用上面提到的扩展产生影响,授予。)但是,在我的情况下,我知道我正在测试的层contents
被分配了一个CGImageRef。(希望这不会在我分配后改变!另外我注意到它contents
被保留了。)
好的,回到手头的问题。这是我使用扩展的方式。对于初学者,我已将选择器从更改containsPoint:
为containsNonTransparentPoint:
(我需要保留原始方法。)
现在,我有一个使用七个CALayer对象的UIImageView子类。这些用于基于不透明度的动画(脉冲/发光效果和开/关状态)。这七层中的每一层都有一个已知的CGImageRef,它有效地“覆盖”(空中引号)整个视图的一部分,并带有自己的颜色。其各自图层中的每个图像的其余部分都是透明的。contents
在子类中,我注册了单击手势。当一个到达时,我遍历我的层以查看哪个被有效地点击(也就是说,哪个有一个我点击的不透明点,第一个找到获胜)然后我可以做任何需要做的事情。
这是我处理手势的方式:
- (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 模拟器上完美运行。(FWIW,我在 Lion 上运行 Xcode 4.1。)
然而,在我的 iPhone 4(使用 iOS 4.3.3)上,它甚至没有接近!我的水龙头似乎都没有与我期望它们匹配的任何层相匹配。
即使我尝试使用CGContextSetBlendMode的建议在绘制 1x1 像素上下文时
我希望这是飞行员的错误,但我还没有弄清楚差异是什么。水龙头确实有图案,但不是可辨别的。
也许存在数据边界问题。也许除了将 y 坐标翻转到图像的左下角之外,我还需要做一些事情。只是还不确定。
如果有人可以请阐明可能有什么问题,我将不胜感激!
2011 年 9 月 22 日更新:获得第一个啊哈时刻!问题不在于 Simulator-vs-iPhone。这是视网膜与非视网膜!使用 Retina 版本时,模拟器中也会出现相同的症状。也许解决方案以某种方式/形状/形式围绕缩放(CTM?)。Quartz 2D Programming Guide 还建议“iOS 应用程序应该使用UIGraphicsBeginImageContextWithOptions ”。我觉得我非常接近这里的解决方案!