- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { //Using code from http://stackoverflow.com/questions/1042830/retrieving-a-pixel-alpha-value-for-a-uiimage unsigned char pixel[1] = {0}; CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 1, NULL, kCGImageAlphaOnly); UIGraphicsPushContext(context); [self.image drawAtPoint:CGPointMake(-point.x, -point.y)]; UIGraphicsPopContext(); CGContextRelease(context); CGFloat alpha = pixel[0]/255.0f; BOOL transparent = alpha < 0.01f; return !transparent; }
一般在iOS的控件中,要不就是完全允许用户点击,要不就是禁止用户交互,这是可以通过设置控件的userInteractionEnabled属性来修改。如果添加的图片不是不规则形状的,而是矩形,这问题就简单多了,只需要将矩形图片对应的UIImageView的userInteractionEnabled设为YES,对半透明背景View(或者直接设置为一个按钮)设置点击事件处理,就可以点击实现半透明背景退出弹出界面。
现在的情况是这个矩形图片一分为二,一部分为实体的不规则形状图片,一部分为不规则形状的透明区域。很显然,问题的解决思路是:让手指能“穿透”这个不规则透明区域去点击背后的半透明背景,而不透明部分就不“穿透”。
前面说的userInteractionEnabled属性只是简单地一刀切设置控件是否允许用户操作(即可以响应手指触摸事件),更加灵活的设置方法是使用UIView的hitTest:withEvent:与pointInside:withEvent:。简单介绍下,iOS中的pointInside:withEvent:方法是用来判断当前的点击或者触摸事件的点是否在当前的view中,它被hitTest:withEvent:调用,通过对每个子视图调用pointInside:withEvent:决定最终哪个视图来响应此事件。如果一个子视图的pointInside:withEvent:返回NO,说明这个子视图不会响应点击事件,然后就去寻找更深层的子视图来找到最终响应触摸事件;返回YES就说明子视图能响应点击事件(但不一定是子视图本身响应,若子视图还有子视图的话,还会继续循环去找最终响应事件的子子视图)。
于是,本文的问题就可以这样转化:创建一个UIImageView的子类,重写pointInside:withEvent:方法,让矩形图片的透明区域的pointInside:withEvent:返回NO,而非透明区域的pointInside:withEvent:返回YES,如果能达到这个要求,透明区域点击事件穿透就能够实现。
现在的关键问题是怎么识别出这个透明区域。
iOS中通常用的图片是PNG图片,这种图片有alpha通道,如果能获取PNG图片每个像素的alpha值,就不难判断出手指点击的图片区域是不是透明的。
http://blog.csdn.net/ralbatr/article/details/38388801
http://www.cocoachina.com/ios/20160208/15238.html
总结
如果你一步一步做到了这里,我想一定会有不少收益。不过,学而不思则罔,思而不学则殆。动手实践后还是应该总结提炼,优化滑动性能主要涉及三个方面:
避免图层混合
-
确保控件的opaque属性设置为true,确保backgroundColor和父视图颜色一致且不透明。
-
如无特殊需要,不要设置低于1的alpha值。
-
确保UIImage没有alpha通道。
避免临时转换
-
确保图片大小和frame一致,不要在滑动时缩放图片。
-
确保图片颜色格式被GPU支持,避免劳烦CPU转换。
慎用离屏渲染
-
绝大多数时候离屏渲染会影响性能。
-
重写drawRect方法,设置圆角、阴影、模糊效果,光栅化都会导致离屏渲染。
-
设置阴影效果是加上阴影路径。
-
滑动时若需要圆角效果,开启光栅化。http://blog.csdn.net/pucker/article/details/41843511
http://www.cocoachina.com/ios/20160205/15233.html
http://blog.csdn.net/freedom2028/article/details/8040918