背景:
开发中的时候,美工姐姐让我做一条虚线包住一个WebView,但是,她给我的虚线只有两个小节那么长。我就很纳闷,给我这么短的虚线,我怎么显示啊?当时,我就想到拼接图片的做法。图片拼接是解决了长度问题,但是方向问题还没解决啊。我想到就是图片旋转。往下看,你就知道怎么回事了。果然,这样是可以的。如果你懒,那你叫美工姐姐给你重新切一个完全符合你的图咯。
实际情况
美工姐姐给我的图是这样的:
然而,她让我做出来的效果是这样的:
给我的图片只有水平的两个小结那么长,要我做出一个包裹住UIWebView
的框框。水平方向,直接拼接图片就能解决。竖直方向嘛,先让图片旋转90度,然后再拼接旋转之后的图片就好啦~~~
解决办法
拼接图片核心代码:
UIGraphicsBeginImageContextWithOptions(useImage.size ,NO, 0.0);
//这里才是主要,看你要拼接的位置
[maskImage drawInRect:CGRectMake(X, Y, W, H)];
//这里的图片就是拼接完成的图片
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
旋转图片核心代码:
+(UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation
{
long double rotate = 0.0;
CGRect rect;
float translateX = 0;
float translateY = 0;
float scaleX = 1.0;
float scaleY = 1.0;
switch (orientation) {
case UIImageOrientationLeft:
rotate = M_PI_2;
rect = CGRectMake(0, 0, image.size.height, image.size.width);
translateX = 0;
translateY = -rect.size.width;
scaleY = rect.size.width/rect.size.height;
scaleX = rect.size.height/rect.size.width;
break;
case UIImageOrientationRight:
rotate = 3 * M_PI_2;
rect = CGRectMake(0, 0, image.size.height, image.size.width);
translateX = -rect.size.height;
translateY = 0;
scaleY = rect.size.width/rect.size.height;
scaleX = rect.size.height/rect.size.width;
break;
case UIImageOrientationDown:
rotate = M_PI;
rect = CGRectMake(0, 0, image.size.width, image.size.height);
translateX = -rect.size.width;
translateY = -rect.size.height;
break;
default:
rotate = 0.0;
rect = CGRectMake(0, 0, image.size.width, image.size.height);
translateX = 0;
translateY = 0;
break;
}
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
//做CTM变换
CGContextTranslateCTM(context, 0.0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextRotateCTM(context, rotate);
CGContextTranslateCTM(context, translateX, translateY);
CGContextScaleCTM(context, scaleX, scaleY);
//绘制图片
CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);
UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
return newPic;
}
完整例子
//
// ViewController.m
// pinjie
//
// Created by HZhenF on 2017/9/8.
// Copyright © 2017年 GZHYTechnology. All rights reserved.
//
#import "ViewController.h"
#import "UIImage+Extension.h"
#define ScreenW [UIScreen mainScreen].bounds.size.width
#define ScreenH [UIScreen mainScreen].bounds.size.height
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//原始的图片
UIImage *originImage = [UIImage imageNamed:@"组-221"];
CGFloat padding = 5;
CGFloat lineWOrH = 2;
CGFloat W = ScreenW - 2*lineWOrH - 2*padding;
CGFloat H = 200;
CGFloat X = (ScreenW - W) * 0.5;
CGFloat Y = ScreenH - H;
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(X, Y, W, H)];
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[webView loadRequest:request];
[self.view addSubview:webView];
CGFloat topImageViewX = 0;
CGFloat topImageViewW = ScreenW;
CGFloat topImageViewH = lineWOrH;
CGFloat topImageViewY = CGRectGetMinY(webView.frame) - padding - lineWOrH;
UIImageView *topImageView = [[UIImageView alloc] initWithFrame:CGRectMake(topImageViewX, topImageViewY, topImageViewW, topImageViewH)];
topImageView.image = [UIImage imageAddLocalImage:originImage addMsakImage:originImage loopTimes:7 rotation:UIImageOrientationUp];
[self.view addSubview:topImageView];
CGFloat leftImageViewX = 0;
CGFloat leftImageViewY = ScreenH - H - padding;
CGFloat leftImageViewW = lineWOrH;
CGFloat leftImageViewH = ScreenH - leftImageViewY;
UIImageView *leftImageView = [[UIImageView alloc] initWithFrame:CGRectMake(leftImageViewX, leftImageViewY, leftImageViewW, leftImageViewH)];
//旋转后的图片
UIImage *leftOrientImg = [UIImage image:originImage rotation:UIImageOrientationRight];
leftImageView.image = [UIImage imageAddLocalImage:leftOrientImg addMsakImage:leftOrientImg loopTimes:4 rotation:UIImageOrientationLeft];
[self.view addSubview:leftImageView];
CGFloat rightImageViewX = ScreenW - 2;
CGFloat rightImageViewY = CGRectGetMinY(leftImageView.frame);
CGFloat rightImageViewW = CGRectGetWidth(leftImageView.frame);
CGFloat rightImageViewH = CGRectGetHeight(leftImageView.frame);
UIImageView *rightImageView = [[UIImageView alloc] initWithFrame:CGRectMake(rightImageViewX, rightImageViewY, rightImageViewW, rightImageViewH)];
//旋转后的图片
UIImage *rightOrientImg = [UIImage image:originImage rotation:UIImageOrientationLeft];
rightImageView.image = [UIImage imageAddLocalImage:rightOrientImg addMsakImage:rightOrientImg loopTimes:4 rotation:UIImageOrientationRight];
[self.view addSubview:rightImageView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
//
// UIImage+Extension.h
// pinjie
//
// Created by HZhenF on 2017/9/8.
// Copyright © 2017年 GZHYTechnology. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIImage (Extension)
/**
将图片旋转
@param image 要旋转的图片
@param orientation 图片旋转方向
@return 旋转之后的图片
*/
+(UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation;
/**
把图片合成
@param useImage 当前图片
@param maskImage 要合成的图片
@param loopTimes 要合成的次数
@param orientation 当前的方向
@return 合成完成的图片
*/
+(UIImage *)imageAddLocalImage:(UIImage *)useImage addMsakImage:(UIImage *)maskImage loopTimes:(NSInteger)loopTimes rotation:(UIImageOrientation)orientation;
@end
//
// UIImage+Extension.m
// pinjie
//
// Created by HZhenF on 2017/9/8.
// Copyright © 2017年 GZHYTechnology. All rights reserved.
//
#import "UIImage+Extension.h"
@implementation UIImage (Extension)
+(UIImage *)image:(UIImage *)image rotation:(UIImageOrientation)orientation
{
long double rotate = 0.0;
CGRect rect;
float translateX = 0;
float translateY = 0;
float scaleX = 1.0;
float scaleY = 1.0;
switch (orientation) {
case UIImageOrientationLeft:
rotate = M_PI_2;
rect = CGRectMake(0, 0, image.size.height, image.size.width);
translateX = 0;
translateY = -rect.size.width;
scaleY = rect.size.width/rect.size.height;
scaleX = rect.size.height/rect.size.width;
break;
case UIImageOrientationRight:
rotate = 3 * M_PI_2;
rect = CGRectMake(0, 0, image.size.height, image.size.width);
translateX = -rect.size.height;
translateY = 0;
scaleY = rect.size.width/rect.size.height;
scaleX = rect.size.height/rect.size.width;
break;
case UIImageOrientationDown:
rotate = M_PI;
rect = CGRectMake(0, 0, image.size.width, image.size.height);
translateX = -rect.size.width;
translateY = -rect.size.height;
break;
default:
rotate = 0.0;
rect = CGRectMake(0, 0, image.size.width, image.size.height);
translateX = 0;
translateY = 0;
break;
}
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
//做CTM变换
CGContextTranslateCTM(context, 0.0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextRotateCTM(context, rotate);
CGContextTranslateCTM(context, translateX, translateY);
CGContextScaleCTM(context, scaleX, scaleY);
//绘制图片
CGContextDrawImage(context, CGRectMake(0, 0, rect.size.width, rect.size.height), image.CGImage);
UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
return newPic;
}
+(UIImage *)imageAddLocalImage:(UIImage *)useImage addMsakImage:(UIImage *)maskImage loopTimes:(NSInteger)loopTimes rotation:(UIImageOrientation)orientation
{
UIGraphicsBeginImageContextWithOptions(useImage.size ,NO, 0.0);
//四个参数为水印图片的位置
//如果要多个位置显示,继续drawInRect就行
switch (orientation) {
case UIImageOrientationUp:
for (int i = 0; i < loopTimes; i ++)
{
CGFloat X = useImage.size.width/loopTimes*i;
CGFloat W = useImage.size.width/loopTimes;
CGFloat H = useImage.size.height;
CGFloat Y = 0;
[maskImage drawInRect:CGRectMake(X, Y, W, H)];
}
break;
case UIImageOrientationLeft :
for (int i = 0; i < loopTimes; i ++)
{
CGFloat X = 0;
CGFloat W = useImage.size.width;
CGFloat H = useImage.size.height / loopTimes;
CGFloat Y = useImage.size.height / loopTimes * i;
[maskImage drawInRect:CGRectMake(X, Y, W, H)];
}
break;
case UIImageOrientationRight:
for (int i = 0; i < loopTimes; i ++)
{
CGFloat X = 0;
CGFloat W = useImage.size.width;
CGFloat H = useImage.size.height / loopTimes;
CGFloat Y = useImage.size.height / loopTimes * i;
[maskImage drawInRect:CGRectMake(X, Y, W, H)];
}
break;
default:
break;
}
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return resultingImage;
}
@end
效果图:
额外提示
细心的小伙伴,你可能会发现,包裹住WebView的虚线,两个拐角是有点圆的。之前呢,我想着是改变线条的layer实现圆角的做法,实际上不太理想。但是,这个肯定是能做的,至于要实现拐角处像图片那么圆,layer的半径慢慢去调试吧,反正我是放弃了。
另一种做法呢,就是用一个UIView包裹住里面的线条和WebView。然后直接取改变这个大的UIView的layer。这个也是我比较喜欢的一种做法。