【iOS开发】根据图片透明度自定义UIButton实现
2014-10-20 11:32
495 查看
日常开发过程中,经常会碰到自定义按钮的需求,例如:微信中的图片部分的尖角。本身就是根据聊天的气泡进行“塑形”的,如下图就是微信中图片“气泡化”显示。
要达成目标,我们需要解决的问题有下面几个:
1、点击没有图片的部分,不响应点击操作
2、根据指定的mask图片,进行图片合成&剪切
问题1:根据图片,设定响应区域
我们建立一个UIButton的子类,变量imageMask用来记录图片的形状,UIButton每次点击的时候,都会调用:
- (BOOL)pointInside:(CGPoint)point
withEvent:(UIEvent *)event;
来判断当前点击的按钮是否需要响应,所以,我们在UIButton的子类(KMAutoShapeButton)中响应该函数:
在-(BOOL)pointInside:withEvent: 中,先判断父类的结果并返回。
再次判断 当前点击位置是否等于上次的点击位置,如果是,返回上次的结果。在响应过程中一次点击可能会多次调用-(BOOL)pointInside:withEvent:
否则返回当前次判断返回结果。
问题2:根据制定的mask图片,进行图片合成&剪切
解决了问题1,我们只是能根据提供的mask图片检测响应区域,下面讨论怎么在:
- (void)setImage:(UIImage *)image forState:(UIControlState)state;
- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state;
的函数里面对要设置的图片进行剪切。
在图片绘制CGContext系列函数里面,CGContextClipToMask
是根据指定mask图片的alpha值进行剪切,由此,我们可以通过mask图片&CGContextClipToMask 函数,将设置的Image进行剪切然后设置到UIButton中。
UIImage+shape.m剪切部分:
KMAutoShapeButton.m重载图片设置部分:
按钮点击检测、图片剪切 等步骤,可以得到我们最终需要的图片效果,并且在需要变换形状的时候,仅仅将mask图片替换掉即可。
代码下载:http://download.csdn.net/detail/u013494674/8046173
要达成目标,我们需要解决的问题有下面几个:
1、点击没有图片的部分,不响应点击操作
2、根据指定的mask图片,进行图片合成&剪切
问题1:根据图片,设定响应区域
我们建立一个UIButton的子类,变量imageMask用来记录图片的形状,UIButton每次点击的时候,都会调用:
- (BOOL)pointInside:(CGPoint)point
withEvent:(UIEvent *)event;
来判断当前点击的按钮是否需要响应,所以,我们在UIButton的子类(KMAutoShapeButton)中响应该函数:
// 判断当前point对应的alpha是否在0.1以内,设置的阀值是0.1 - (BOOL)isAlphaVisibleAtPoint:(CGPoint)point forImage:(UIImage *)image { CGSize iSize = image.size; CGSize bSize = self.bounds.size; point.x *= (bSize.width != 0) ? (iSize.width / bSize.width) : 1; point.y *= (bSize.height != 0) ? (iSize.height / bSize.height) : 1; CGColorRef pixelColor = [[self.imageMask colorAtPixel:point] CGColor]; CGFloat alpha = CGColorGetAlpha(pixelColor); return alpha >= kAlphaVisibleThreshold; } - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { // Return NO if even super returns NO (i.e., if point lies outside our bounds) BOOL superResult = [super pointInside:point withEvent:event]; if (!superResult) { return superResult; } if (CGPointEqualToPoint(self.previousTouchPoint, point)) { return self.previousTouchHitTestResponse; } self.previousTouchPoint = point; self.previousTouchHitTestResponse = [self isAlphaVisibleAtPoint:point forImage:self.imageMask]; return self.previousTouchHitTestResponse; }
在-(BOOL)pointInside:withEvent: 中,先判断父类的结果并返回。
再次判断 当前点击位置是否等于上次的点击位置,如果是,返回上次的结果。在响应过程中一次点击可能会多次调用-(BOOL)pointInside:withEvent:
否则返回当前次判断返回结果。
问题2:根据制定的mask图片,进行图片合成&剪切
解决了问题1,我们只是能根据提供的mask图片检测响应区域,下面讨论怎么在:
- (void)setImage:(UIImage *)image forState:(UIControlState)state;
- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state;
的函数里面对要设置的图片进行剪切。
在图片绘制CGContext系列函数里面,CGContextClipToMask
是根据指定mask图片的alpha值进行剪切,由此,我们可以通过mask图片&CGContextClipToMask 函数,将设置的Image进行剪切然后设置到UIButton中。
UIImage+shape.m剪切部分:
- (UIImage *)imageWithMask:(UIImage*)imageMask { // 转换坐标 imageMask = [imageMask flipVertical]; UIGraphicsBeginImageContext(CGSizeMake(self.size.width, self.size.height)); CGContextRef context = UIGraphicsGetCurrentContext(); CGImageRef maskRef = [imageMask fitSize:self.size].CGImage; CGContextClipToMask(context, CGRectMake(0, 0, self.size.width, self.size.height), maskRef); [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)]; UIImage *reSizeImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return reSizeImage; } - (UIImage*)flipVertical { UIImage *image = nil; switch (self.imageOrientation) { case UIImageOrientationUp: { image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationDownMirrored]; break; } case UIImageOrientationDown: { image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationUpMirrored]; break; } case UIImageOrientationLeft: { image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationLeftMirrored]; break; } case UIImageOrientationRight: { image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationRightMirrored]; break; } case UIImageOrientationUpMirrored: { image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationDown]; break; } case UIImageOrientationDownMirrored: { image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationUp]; break; } case UIImageOrientationLeftMirrored: { image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationLeft]; break; } case UIImageOrientationRightMirrored: { image = [UIImage imageWithCGImage:self.CGImage scale:1 orientation:UIImageOrientationRight]; break; } default: break; } return image; }
KMAutoShapeButton.m重载图片设置部分:
// Reset the Hit Test Cache when a new image is assigned to the button - (void)setImage:(UIImage *)image forState:(UIControlState)state { [super setImage:self.imageMask ? [image imageWithMask:self.imageMask] : image forState:state]; [self resetHitTestCache]; } - (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state { [super setBackgroundImage:self.imageMask ? [image imageWithMask:self.imageMask] : image forState:state]; [self resetHitTestCache]; } - (void)resetHitTestCache { self.previousTouchPoint = CGPointMake(CGFLOAT_MIN, CGFLOAT_MIN); self.previousTouchHitTestResponse = NO; }通过
按钮点击检测、图片剪切 等步骤,可以得到我们最终需要的图片效果,并且在需要变换形状的时候,仅仅将mask图片替换掉即可。
代码下载:http://download.csdn.net/detail/u013494674/8046173
相关文章推荐
- iOS开发:自定义库实现广告图片轮播
- iOS View自定义窍门——UIButton实现上显示图片,下显示文字
- iOS View自定义窍门——UIButton实现上显示图片,下显示文字
- IOS 开发之自定义按钮实现文字图片位置随意定制
- SWT开发--自定义图片按钮的实现
- iOS开发——图片转PDF的实现方法
- Objective-C ,ios,iphone开发基础:快速实现一个简单的图片查看器
- iOS开发-自定义后台显示图片(iOS7-Background Fetch的应用)
- Objective-C ,ios,iphone开发基础:快速实现一个简单的图片查看器
- IOS开发入门基本知识——实现小猫招呼UIView UILabel UIButton NSTimer层级关系
- 【ios开发】自定义Actionsheet实现时间选择器和省市区选择器
- 【iOS开发】---- 如何将图片保存至自定义分组
- iOS开发-自定义后台显示图片(iOS7-Background Fetch的应用)
- iOS开发那些事--自定义单元格实现
- IOS开发实现二张图片合并http://ios.662p.com/thread-1350-1-1.html
- ((ios开发学习笔记 十))代码实现自定义TableView
- iOS开发点击UIButton实现UIView的旋转
- ((ios开发学习笔记 十二))Nib加载的方式实现自定义TableView
- iOS开发——图片转PDF的实现方法
- IOS开发之UIButton同时设置图片文字以及触发按钮时文字图片的切换