Skip to content

Instantly share code, notes, and snippets.

@ourui
Created May 22, 2016 10:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ourui/3d97497ca413cd37bab4fa1197d31ebe to your computer and use it in GitHub Desktop.
Save ourui/3d97497ca413cd37bab4fa1197d31ebe to your computer and use it in GitHub Desktop.
//
// UIImage+RoundedCorner.h
// SelectTags
//
// Created by jm on 16/2/22.
// Copyright © 2016年 Jim. All rights reserved.
//
//生成带圆角的图片
#import <UIKit/UIKit.h>
struct JMRadius {
CGFloat topLeftRadius;
CGFloat topRightRadius;
CGFloat bottomLeftRadius;
CGFloat bottomRightRadius;
};
typedef struct JMRadius JMRadius;
static inline JMRadius JMRadiusMake(CGFloat topLeftRadius, CGFloat topRightRadius, CGFloat bottomLeftRadius, CGFloat bottomRightRadius) {
JMRadius radius;
radius.topLeftRadius = topLeftRadius;
radius.topRightRadius = topRightRadius;
radius.bottomLeftRadius = bottomLeftRadius;
radius.bottomRightRadius = bottomRightRadius;
return radius;
}
@interface UIImage (RoundedCorner)
- (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit andCornerRadius:(CGFloat)radius;
- (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit andCornerRadius:(CGFloat)radius withContentMode:(UIViewContentMode)contentMode;
+ (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit CornerRadius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth;
+ (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit andCornerRadius:(CGFloat)radius andColor:(UIColor *)color;
+ (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit CornerRadius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage withContentMode:(UIViewContentMode)contentMode;
+ (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit JMRadius:(JMRadius)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage withContentMode:(UIViewContentMode)contentMode;
@end
//
// UIImage+RoundedCorner.m
// SelectTags
//
// Created by jm on 16/2/22.
// Copyright © 2016年 Jim. All rights reserved.
//
#import "UIImage+RoundedCorner.h"
@implementation UIImage (RoundedCorner)
- (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit andCornerRadius:(CGFloat)radius {
return [UIImage jm_imageWithRoundedCornersAndSize:sizeToFit CornerRadius:radius borderColor:nil borderWidth:0 backgroundColor:nil backgroundImage:self withContentMode:UIViewContentModeScaleAspectFill];
}
- (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit andCornerRadius:(CGFloat)radius withContentMode:(UIViewContentMode)contentMode {
return [UIImage jm_imageWithRoundedCornersAndSize:sizeToFit CornerRadius:radius borderColor:nil borderWidth:0 backgroundColor:nil backgroundImage:self withContentMode:contentMode];
}
+ (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit CornerRadius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
return [UIImage jm_imageWithRoundedCornersAndSize:sizeToFit CornerRadius:radius borderColor:borderColor borderWidth:borderWidth backgroundColor:nil backgroundImage:nil withContentMode:UIViewContentModeScaleToFill];
}
+ (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit andCornerRadius:(CGFloat)radius andColor:(UIColor *)color {
return [UIImage jm_imageWithRoundedCornersAndSize:sizeToFit CornerRadius:radius borderColor:nil borderWidth:0 backgroundColor:color backgroundImage:nil withContentMode:UIViewContentModeScaleToFill];
}
+ (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit CornerRadius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage withContentMode:(UIViewContentMode)contentMode {
return [UIImage jm_imageWithRoundedCornersAndSize:sizeToFit JMRadius:JMRadiusMake(radius, radius, radius, radius) borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor backgroundImage:backgroundImage withContentMode:contentMode];
}
+ (UIImage *)jm_imageWithRoundedCornersAndSize:(CGSize)sizeToFit JMRadius:(JMRadius)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage withContentMode:(UIViewContentMode)contentMode {
if (backgroundImage) {
backgroundImage = [backgroundImage scaleToSize:CGSizeMake(sizeToFit.width, sizeToFit.height) withContentMode:contentMode backgroundColor:backgroundColor];
backgroundColor = [UIColor colorWithPatternImage:backgroundImage];
} else if (!backgroundColor){
backgroundColor = [UIColor whiteColor];
}
UIGraphicsBeginImageContextWithOptions(sizeToFit, NO, UIScreen.mainScreen.scale);
CGFloat halfBorderWidth = borderWidth / 2;
//设置上下文
CGContextRef context = UIGraphicsGetCurrentContext();
//边框大小
CGContextSetLineWidth(context, borderWidth);
//边框颜色
CGContextSetStrokeColorWithColor(context, borderColor.CGColor);
//矩形填充颜色
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
CGFloat height = sizeToFit.height;
CGFloat width = sizeToFit.width;
radius = [UIImage transformationJMRadius:radius size:sizeToFit borderWidth:borderWidth];
CGFloat startPointY;
if (radius.topRightRadius >= height - borderWidth) {
startPointY = height;
} else if (radius.topRightRadius > 0){
startPointY = halfBorderWidth + radius.topRightRadius;
} else {
startPointY = 0;
}
CGContextMoveToPoint(context, width - halfBorderWidth, startPointY); // 开始坐标右边开始
CGContextAddArcToPoint(context, width - halfBorderWidth, height - halfBorderWidth, width / 2, height - halfBorderWidth, radius.bottomRightRadius); // 右下角角度
CGContextAddArcToPoint(context, halfBorderWidth, height - halfBorderWidth, halfBorderWidth, height / 2, radius.bottomLeftRadius); // 左下角角度
CGContextAddArcToPoint(context, halfBorderWidth, halfBorderWidth, width / 2, halfBorderWidth, radius.topLeftRadius); // 左上角
CGContextAddArcToPoint(context, width - halfBorderWidth, halfBorderWidth, width - halfBorderWidth, height / 2, radius.topRightRadius); // 右上角
CGContextDrawPath(context, kCGPathFillStroke); //根据坐标绘制路径
UIImage *outImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outImage;
}
+ (JMRadius)transformationJMRadius:(JMRadius)radius size:(CGSize)size borderWidth:(CGFloat)borderWidth {
radius.topLeftRadius = minimum(size.width - borderWidth, size.height - borderWidth, radius.topLeftRadius - borderWidth / 2);
radius.topRightRadius = minimum(size.width - borderWidth - radius.topLeftRadius, size.height - borderWidth, radius.topRightRadius - borderWidth / 2);
radius.bottomLeftRadius = minimum(size.width - borderWidth, size.height - borderWidth - radius.topLeftRadius, radius.bottomLeftRadius - borderWidth / 2);
radius.bottomRightRadius = minimum(size.width - borderWidth - radius.bottomLeftRadius, size.height - borderWidth - radius.topRightRadius, radius.bottomRightRadius - borderWidth / 2);
return radius;
}
static inline CGFloat minimum(CGFloat a, CGFloat b, CGFloat c) {
CGFloat minimum = MIN(MIN(a, b), c);
return MAX(minimum, 0);
}
- (UIImage *)scaleToSize:(CGSize)size withContentMode:(UIViewContentMode)contentMode backgroundColor:(UIColor *)backgroundColor {
CGRect rect = CGRectMake(0, 0, size.width, size.height);
UIGraphicsBeginImageContextWithOptions(size, NO, UIScreen.mainScreen.scale);
if (backgroundColor) {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
CGContextAddRect(context, rect);
CGContextDrawPath(context, kCGPathFillStroke); //根据坐标绘制路径
}
[self drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height) withContentMode:contentMode];
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
- (void)drawInRect:(CGRect)rect withContentMode:(UIViewContentMode)contentMode {
[self drawInRect:[self convertRect:rect withContentMode:contentMode]];
}
- (CGRect)convertRect:(CGRect)rect withContentMode:(UIViewContentMode)contentMode {
CGSize size = self.size;
rect = CGRectStandardize(rect);
size.width = size.width < 0 ? -size.width : size.width;
size.height = size.height < 0 ? -size.height : size.height;
CGPoint center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
switch (contentMode) {
case UIViewContentModeRedraw:
case UIViewContentModeScaleAspectFit:
case UIViewContentModeScaleAspectFill: {
if (rect.size.width < 0.01 || rect.size.height < 0.01 ||
size.width < 0.01 || size.height < 0.01) {
rect.origin = center;
rect.size = CGSizeZero;
} else {
CGFloat scale;
if (contentMode == UIViewContentModeScaleAspectFill) {
if (size.width / size.height < rect.size.width / rect.size.height) {
scale = rect.size.width / size.width;
} else {
scale = rect.size.height / size.height;
}
} else {
if (size.width / size.height < rect.size.width / rect.size.height) {
scale = rect.size.height / size.height;
} else {
scale = rect.size.width / size.width;
}
}
size.width *= scale;
size.height *= scale;
rect.size = size;
rect.origin = CGPointMake(center.x - size.width * 0.5, center.y - size.height * 0.5);
}
} break;
case UIViewContentModeCenter: {
rect.size = size;
rect.origin = CGPointMake(center.x - size.width * 0.5, center.y - size.height * 0.5);
} break;
case UIViewContentModeTop: {
rect.origin.x = center.x - size.width * 0.5;
rect.size = size;
} break;
case UIViewContentModeBottom: {
rect.origin.x = center.x - size.width * 0.5;
rect.origin.y += rect.size.height - size.height;
rect.size = size;
} break;
case UIViewContentModeLeft: {
rect.origin.y = center.y - size.height * 0.5;
rect.size = size;
} break;
case UIViewContentModeRight: {
rect.origin.y = center.y - size.height * 0.5;
rect.origin.x += rect.size.width - size.width;
rect.size = size;
} break;
case UIViewContentModeTopLeft: {
rect.size = size;
} break;
case UIViewContentModeTopRight: {
rect.origin.x += rect.size.width - size.width;
rect.size = size;
} break;
case UIViewContentModeBottomLeft: {
rect.origin.y += rect.size.height - size.height;
rect.size = size;
} break;
case UIViewContentModeBottomRight: {
rect.origin.x += rect.size.width - size.width;
rect.origin.y += rect.size.height - size.height;
rect.size = size;
} break;
case UIViewContentModeScaleToFill:
default: {
rect = rect;
}
}
return rect;
}
@end
//
// UIView+RoundedCorner.h
// UIImageRoundedCornerDemo
//
// Created by jm on 16/2/25.
// Copyright © 2016年 Jim. All rights reserved.
//
//使用这个类就可以了
#import <UIKit/UIKit.h>
#import "UIImage+RoundedCorner.h"
@interface UIView (RoundedCorner)
/**给view设置一个圆角边框*/
- (void)jm_setCornerRadius:(CGFloat)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth;
/**给view设置一个圆角边框,四个圆角弧度可以不同*/
- (void)jm_setJMRadius:(JMRadius)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth;
/**给view设置一个圆角背景颜色*/
- (void)jm_setCornerRadius:(CGFloat)radius withBackgroundColor:(UIColor *)backgroundColor;
/**给view设置一个圆角背景颜色,四个圆角弧度可以不同*/
- (void)jm_setJMRadius:(JMRadius)radius withBackgroundColor:(UIColor *)backgroundColor;
/**给view设置一个圆角背景图*/
- (void)jm_setCornerRadius:(CGFloat)radius withImage:(UIImage *)image;
///**给view设置一个圆角背景图,四个圆角弧度可以不同*/
- (void)jm_setJMRadius:(JMRadius)radius withImage:(UIImage *)image;
/**给view设置一个contentMode模式的圆角背景图*/
- (void)jm_setCornerRadius:(CGFloat)radius withImage:(UIImage *)image contentMode:(UIViewContentMode)contentMode;
///**给view设置一个contentMode模式的圆角背景图,四个圆角弧度可以不同*/
- (void)jm_setJMRadius:(JMRadius)radius withImage:(UIImage *)image contentMode:(UIViewContentMode)contentMode;
/**设置所有属性配置出一个圆角背景图*/
- (void)jm_setCornerRadius:(CGFloat)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage contentMode:(UIViewContentMode)contentMode;
/**设置所有属性配置出一个圆角背景图,四个圆角弧度可以不同*/
- (void)jm_setJMRadius:(JMRadius)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage contentMode:(UIViewContentMode)contentMode;
/**设置所有属性配置出一个圆角背景图,并多传递了一个size参数,如果JMRoundedCorner没有拿到view的size,可以调用这个方法*/
- (void)jm_setJMRadius:(JMRadius)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage contentMode:(UIViewContentMode)contentMode size:(CGSize)size;
@end
//
// UIView+RoundedCorner.m
// UIImageRoundedCornerDemo
//
// Created by jm on 16/2/25.
// Copyright © 2016年 Jim. All rights reserved.
//
#import "UIView+RoundedCorner.h"
#import <objc/runtime.h>
static NSOperationQueue *jm_operationQueue;
static char jm_operationKey;
@implementation UIView (RoundedCorner)
+ (void)load {
jm_operationQueue = [[NSOperationQueue alloc] init];
}
- (NSOperation *)jm_getOperation {
id operation = objc_getAssociatedObject(self, &jm_operationKey);
return operation;
}
- (void)jm_setOperation:(NSOperation *)operation {
objc_setAssociatedObject(self, &jm_operationKey, operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)jm_cancelOperation {
NSOperation *operation = [self jm_getOperation];
[operation cancel];
[self jm_setOperation:nil];
}
- (void)jm_setCornerRadius:(CGFloat)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
[self jm_setCornerRadius:radius withBorderColor:borderColor borderWidth:borderWidth backgroundColor:nil backgroundImage:nil contentMode:UIViewContentModeScaleAspectFill];
}
- (void)jm_setJMRadius:(JMRadius)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
[self jm_setJMRadius:radius withBorderColor:borderColor borderWidth:borderWidth backgroundColor:nil backgroundImage:nil contentMode:UIViewContentModeScaleAspectFill];
}
- (void)jm_setCornerRadius:(CGFloat)radius withBackgroundColor:(UIColor *)backgroundColor {
[self jm_setCornerRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:backgroundColor backgroundImage:nil contentMode:UIViewContentModeScaleAspectFill];
}
- (void)jm_setJMRadius:(JMRadius)radius withBackgroundColor:(UIColor *)backgroundColor {
[self jm_setJMRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:backgroundColor backgroundImage:nil contentMode:UIViewContentModeScaleAspectFill];
}
- (void)jm_setCornerRadius:(CGFloat)radius withImage:(UIImage *)image {
[self jm_setCornerRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:nil backgroundImage:image contentMode:UIViewContentModeScaleAspectFill];
}
- (void)jm_setJMRadius:(JMRadius)radius withImage:(UIImage *)image {
[self jm_setJMRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:nil backgroundImage:image contentMode:UIViewContentModeScaleAspectFill];
}
- (void)jm_setCornerRadius:(CGFloat)radius withImage:(UIImage *)image contentMode:(UIViewContentMode)contentMode {
[self jm_setCornerRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:nil backgroundImage:image contentMode:contentMode];
}
- (void)jm_setJMRadius:(JMRadius)radius withImage:(UIImage *)image contentMode:(UIViewContentMode)contentMode {
[self jm_setJMRadius:radius withBorderColor:nil borderWidth:0 backgroundColor:nil backgroundImage:image contentMode:contentMode];
}
- (void)jm_setCornerRadius:(CGFloat)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage contentMode:(UIViewContentMode)contentMode {
[self jm_setJMRadius:JMRadiusMake(radius, radius, radius, radius) withBorderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor backgroundImage:backgroundImage contentMode:contentMode];
}
- (void)jm_setJMRadius:(JMRadius)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage contentMode:(UIViewContentMode)contentMode {
[self jm_cancelOperation];
[self jm_setJMRadius:radius withBorderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor backgroundImage:backgroundImage contentMode:contentMode size:CGSizeZero];
}
- (void)jm_setJMRadius:(JMRadius)radius withBorderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth backgroundColor:(UIColor *)backgroundColor backgroundImage:(UIImage *)backgroundImage contentMode:(UIViewContentMode)contentMode size:(CGSize)size {
__block CGSize _size = size;
__weak typeof(self) wself = self;
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
if ([[wself jm_getOperation] isCancelled]) return;
if (CGSizeEqualToSize(_size, CGSizeZero)) {
dispatch_sync(dispatch_get_main_queue(), ^{
_size = wself.bounds.size;
});
}
CGSize size2 = CGSizeMake(pixel(_size.width), pixel(_size.height));
UIImage *image = [UIImage jm_imageWithRoundedCornersAndSize:size2 JMRadius:radius borderColor:borderColor borderWidth:borderWidth backgroundColor:backgroundColor backgroundImage:backgroundImage withContentMode:contentMode];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
__strong typeof(wself) self = wself;
if ([[self jm_getOperation] isCancelled]) return;
self.frame = CGRectMake(pixel(self.frame.origin.x), pixel(self.frame.origin.y), size2.width, size2.height);
if ([self isKindOfClass:[UIImageView class]]) {
((UIImageView *)self).image = image;
} else if ([self isKindOfClass:[UIButton class]] && backgroundImage) {
[((UIButton *)self) setBackgroundImage:image forState:UIControlStateNormal];
} else if ([self isKindOfClass:[UILabel class]]) {
self.layer.backgroundColor = [UIColor colorWithPatternImage:image].CGColor;
} else {
self.layer.contents = (__bridge id _Nullable)(image.CGImage);
}
}];
}];
[self jm_setOperation:blockOperation];
[jm_operationQueue addOperation:blockOperation];
}
static inline float pixel(float num) {
float unit = 1.0 / [UIScreen mainScreen].scale;
double remain = fmod(num, unit);
return num - remain + (remain >= unit / 2.0? unit: 0);
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment