//
// IrregularBorderView.h
// IrregularBorderView
//
// Created by Fan HouCheng on 15/8/28.
// Copyright (c) 2015年 Fan HouCheng. All rights reserved.
//
#define BORDER_WIDTH 2
#define LINE_VIEW_TAG 9999
#import <UIKit/UIKit.h>
@interface IrregularBorderView : UIView
@property (nonatomic, assign) UIColor *borderColor;
/**
* 生成IrregularBorderView
*
* @param unitSize 单位宽高
* @param borderColor 边框颜色
* @param frames 组成IrregularBorderView的子view的Frame
*
* @return <#return value description#>
*/
+ (id)createViewWithUnit:(CGSize)unitSize borderColor:(CGFloat [3])borderColor frames:(NSValue *)frames, ...;
/**
* 给View的子view添加边框
*
* @param mView 父view
* @param unitSize 单位宽高
* @param borderColor 边框颜色
*/
+ (void)borderViewsInView:(UIView *)mView unitSize:(CGSize)unitSize borderColor:(CGFloat [3])borderColor;
/**
* 组成IrregularBorderView的子view的Tap事件
*
* @param tap tap事件
*/
- (void)addTapBlock:(void(^)(UIView *))tap;
@end
#import "IrregularBorderView.h"
@interface IrregularBorderView ()<UIGestureRecognizerDelegate>
{
void (^tapBlock)( UIView * );
}
@property (nonatomic, assign) CGSize unitSize;//ListView的显示状态
@end
@implementation IrregularBorderView
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
for (UIView *view1 in self.subviews){
if (![view1 isKindOfClass:[UIImageView class]]) {
BOOL contains = CGRectContainsPoint(view1.frame, point);
if (contains) {
return YES;
}
}
}
return NO;
}
-(void)handleTapFrom:(UITapGestureRecognizer*)recognizer
{
if (tapBlock) {
tapBlock(recognizer.view);
}
}
- (void)addTapBlock:(void(^)(UIView *))tap{
tapBlock = tap;
}
+(id)createViewWithUnit:(CGSize)unitSize borderColor:(CGFloat [3])borderColor frames:(NSValue *)frames, ...{
if(unitSize.height <= 0 || unitSize.width <= 0){
return nil;
}
IrregularBorderView *viewSelf = [[IrregularBorderView alloc] init];
viewSelf.unitSize = unitSize;
CGSize sizeMax = CGSizeMake(0, 0);//所有frame占据的区域的最大宽度和高度
CGPoint pointMin = CGPointMake([frames CGRectValue].origin.x, [frames CGRectValue].origin.y);//所有frame占据的区域的最原点
NSMutableArray *arrArgs = [[NSMutableArray alloc] initWithCapacity:0];
va_list args;
va_start(args, frames);
if (frames){
//将第一个参数添加到array
NSValue * prev = frames;
[arrArgs addObject:prev];
NSValue * frameVal;
while ((frameVal = va_arg(args, NSValue *))){
[arrArgs addObject:frameVal];
}
}
va_end(args);
//所有frame占据的区域的最原点
for (NSValue *frameVal in arrArgs){
CGRect frame = [frameVal CGRectValue];
//计算最原点
if (frame.origin.x < pointMin.x) {
pointMin.x = frame.origin.x;
}
if (frame.origin.y < pointMin.y) {
pointMin.y = frame.origin.y;
}
UIView *view = [[UIView alloc] initWithFrame:frame];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:viewSelf action:@selector(handleTapFrom:)];
[view addGestureRecognizer:tapRecognizer];
tapRecognizer.numberOfTapsRequired = 1;
tapRecognizer.delegate = viewSelf;
[viewSelf addSubview:view];
[view setBackgroundColor:[self randomColor]];
}
//所有frame占据的区域的最大宽度和高度
for (NSValue *frameVal in arrArgs){
//依次取得所有参数
CGRect frame = [frameVal CGRectValue];
CGFloat right = frame.origin.x - pointMin.x + frame.size.width;
CGFloat bottom = frame.origin.y - pointMin.y + frame.size.height;
if (right > sizeMax.width) {
sizeMax.width = right;
}
if (bottom > sizeMax.height) {
sizeMax.height = bottom;
}
}
CGRect frame = CGRectMake(0, 0, sizeMax.width+ BORDER_WIDTH, sizeMax.height+ BORDER_WIDTH) ;
[viewSelf setBackgroundColor:[UIColor clearColor]];
viewSelf.frame = frame;
for (UIView *view1 in viewSelf.subviews){
CGRect frame1 = view1.frame;
frame1.origin.x = frame1.origin.x - pointMin.x + BORDER_WIDTH/2;
frame1.origin.y = frame1.origin.y - pointMin.y + BORDER_WIDTH/2;
view1.frame = frame1;
}
[IrregularBorderView drawBorder:viewSelf unitSize:unitSize borderColor:borderColor];
return viewSelf;
}
+(void)borderViewsInView:(UIView *)mView unitSize:(CGSize)unitSize borderColor:(CGFloat [3])borderColor{
if(unitSize.height <= 0 || unitSize.width <= 0){
return ;
}
CGRect frame = mView.frame;
CGRect tempFrame = mView.frame;
tempFrame.origin.x = 0;
tempFrame.origin.y = 0;
mView.frame = tempFrame;
[IrregularBorderView drawBorder:mView unitSize:unitSize borderColor:borderColor];
mView.frame = frame;
}
+(UIColor *) randomColor
{
CGFloat hue = ( arc4random() % 256 / 256.0 ); //0.0 to 1.0
CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0,away from white
CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; //0.5 to 1.0,away from black
return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:0.3];
}
/**
* 以unitSize把整条线打散,以方便移除重复的线(重复的线就是不用画的线)
*
* @param unitSize 最小宽高单位
* @param fromP 起始点
* @param toP 结束点
* @param direction 方向(暂时无用)
*
* @return 打散的最小unitSize的线
*/
+(NSMutableArray *)toUnitLine:(CGSize) unitSize fromP:(CGPoint)fromP toP:(CGPoint)toP direction:(int)direction{
NSMutableArray *arr = [[NSMutableArray alloc]initWithCapacity:0];
BOOL hasRemain = YES;
while(hasRemain){
NSValue *fromVal = [NSValue valueWithCGPoint:fromP];
CGPoint toPoint = fromP;
if (fromP.y == toP.y) {
toPoint.x = toPoint.x + unitSize.width;
if (toPoint.x >= toP.x) {
toPoint.x = toP.x;
hasRemain = NO;
}else{
fromP.x = toPoint.x;
}
}else{
toPoint.y = toPoint.y + unitSize.height;
if (toPoint.y >= toP.y) {
toPoint.y = toP.y;
hasRemain = NO;
}else{
fromP.y = toPoint.y;
}
}
NSValue *toVal = [NSValue valueWithCGPoint:toPoint];
[arr addObject:[[NSMutableArray alloc]initWithObjects:fromVal, toVal, [NSNumber numberWithBool:NO] , [NSNumber numberWithFloat:direction],nil]];
}
return arr;
}
/**
* 描绘边框
*
* @param view 需要描绘边框的父view
* @param unitSize 最小宽高单位
* @param borderColor 边框颜色
*/
+ (void)drawBorder:(UIView *)view unitSize:(CGSize) unitSize borderColor:(CGFloat [3])borderColor
{
//先以unitSize把整条线打散,以方便移除重复的线(重复的线就是不用画的线)
NSMutableArray *arrVLinePoint = [[NSMutableArray alloc]initWithCapacity:0];
NSMutableArray *arrHLinePoint = [[NSMutableArray alloc]initWithCapacity:0];
for (UIView *view1 in view.subviews){
CGRect frame1 = view1.frame;
//把所有起始点,结束点统计出来
//left
CGPoint fromPoint = frame1.origin;
fromPoint.x = fromPoint.x;
CGPoint toPoint = fromPoint;
toPoint.y = frame1.origin.y + frame1.size.height;
[arrVLinePoint addObjectsFromArray:[IrregularBorderView toUnitLine:unitSize fromP:fromPoint toP:toPoint direction:0]];
//right
fromPoint = frame1.origin;
fromPoint.x = fromPoint.x + frame1.size.width;
toPoint = fromPoint;
toPoint.y = frame1.origin.y + frame1.size.height;
[arrVLinePoint addObjectsFromArray:[IrregularBorderView toUnitLine:unitSize fromP:fromPoint toP:toPoint direction:1]];
//top
fromPoint = frame1.origin;
fromPoint.y = fromPoint.y ;
toPoint = fromPoint;
toPoint.x = frame1.origin.x + frame1.size.width;
[arrHLinePoint addObjectsFromArray:[IrregularBorderView toUnitLine:unitSize fromP:fromPoint toP:toPoint direction:2]];
//bottom
fromPoint = frame1.origin;
fromPoint.y = fromPoint.y + frame1.size.height;
toPoint = fromPoint;
toPoint.x = frame1.origin.x + frame1.size.width;
[arrHLinePoint addObjectsFromArray:[IrregularBorderView toUnitLine:unitSize fromP:fromPoint toP:toPoint direction:3]];
}
//把水平线是重复的线表示出来
for(int i = 0; i < [arrHLinePoint count]; i++){
NSMutableArray *line1 = [arrHLinePoint objectAtIndex:i];
NSNumber *repeatVal = line1[2];
BOOL hasRepeat = [repeatVal boolValue];
if (!hasRepeat) {
NSValue *fromVal1 = line1[0];
CGPoint fromPoint1 = [fromVal1 CGPointValue];
for(int j = i + 1; j < [arrHLinePoint count]; j++){
NSMutableArray *line2 = [arrHLinePoint objectAtIndex:j];
NSValue *fromVal2 = line2[0];
CGPoint fromPoint2 = [fromVal2 CGPointValue];
if(fromPoint1.y == fromPoint2.y){
if(fromPoint1.x == fromPoint2.x){
line1[2] = [NSNumber numberWithBool:YES];
line2[2] = [NSNumber numberWithBool:YES];
[arrHLinePoint replaceObjectAtIndex:i withObject:line1];
[arrHLinePoint replaceObjectAtIndex:j withObject:line2];
}
}
}
}
}
//移除水平线重复的线
for(int i = 0; i < [arrHLinePoint count]; i++){
NSMutableArray *line1 = [arrHLinePoint objectAtIndex:i];
NSNumber *repeatVal = line1[2];
BOOL hasRepeat = [repeatVal boolValue];
if (hasRepeat) {
[arrHLinePoint removeObjectAtIndex:i];
i--;
}
}
//连接分散但是实际在之前被打散的水平线(可以不连接,也许划线的时候耗费资源)
for(int i = 0; i < [arrHLinePoint count]; i++){
NSMutableArray *line1 = [arrHLinePoint objectAtIndex:i];
if (line1.count == 0) {
continue;
}
NSValue *toVal1 = line1[1];
CGPoint toPoint1 = [toVal1 CGPointValue];
for(int j = i + 1; j < [arrHLinePoint count]; j++){
NSMutableArray *line2 = [arrHLinePoint objectAtIndex:j];
if (line2.count == 0) {
continue;
}
NSValue *fromVal2 = line2[0];
CGPoint fromPoint2 = [fromVal2 CGPointValue];
NSValue *toVal2 = line2[1];
CGPoint toPoint2 = [toVal2 CGPointValue];
if(fromPoint2.x == toPoint1.x && fromPoint2.y == toPoint1.y){
toVal1 = toVal2;
toPoint1 = toPoint2;
[line1 replaceObjectAtIndex:1 withObject:toVal2];
[arrHLinePoint replaceObjectAtIndex:j withObject:[[NSMutableArray alloc] initWithCapacity:0]];
}
}
}
//画水平线
for(int i = 0 ; i < arrHLinePoint.count; i ++){
NSMutableArray *line1 = arrHLinePoint[i];
if (line1.count == 0) {
continue;
}
NSValue *fromVal1 = line1[0];
CGPoint fromPoint1 = [fromVal1 CGPointValue];
NSValue *toVal1 = line1[1];
CGPoint toPoint1 = [toVal1 CGPointValue];
NSNumber *direction = line1[3];
[IrregularBorderView drawLineInView:view fromPoint:fromPoint1 toPoint:toPoint1 direction:[direction intValue] borderColor:borderColor];
}
//以下为垂直线
for(int i = 0; i < [arrVLinePoint count]; i++){
NSMutableArray *line1 = [arrVLinePoint objectAtIndex:i];
NSNumber *repeatVal = line1[2];
BOOL hasRepeat = [repeatVal boolValue];
if (!hasRepeat) {
NSValue *fromVal1 = line1[0];
CGPoint fromPoint1 = [fromVal1 CGPointValue];
for(int j = i + 1; j < [arrVLinePoint count]; j++){
NSMutableArray *line2 = [arrVLinePoint objectAtIndex:j];
NSValue *fromVal2 = line2[0];
CGPoint fromPoint2 = [fromVal2 CGPointValue];
if(fromPoint1.x == fromPoint2.x){
if(fromPoint1.y == fromPoint2.y){
line1[2] = [NSNumber numberWithBool:YES];
line2[2] = [NSNumber numberWithBool:YES];
[arrVLinePoint replaceObjectAtIndex:i withObject:line1];
[arrVLinePoint replaceObjectAtIndex:j withObject:line2];
}
}
}
}
}
for(int i = 0; i < [arrVLinePoint count]; i++){
NSMutableArray *line1 = [arrVLinePoint objectAtIndex:i];
NSNumber *repeatVal = line1[2];
BOOL hasRepeat = [repeatVal boolValue];
if (hasRepeat) {
[arrVLinePoint removeObjectAtIndex:i];
i--;
}
}
for(int i = 0; i < [arrVLinePoint count]; i++){
NSMutableArray *line1 = [arrVLinePoint objectAtIndex:i];
if (line1.count == 0) {
continue;
}
NSValue *toVal1 = line1[1];
CGPoint toPoint1 = [toVal1 CGPointValue];
for(int j = i + 1; j < [arrVLinePoint count]; j++){
NSMutableArray *line2 = [arrVLinePoint objectAtIndex:j];
if (line2.count == 0) {
continue;
}
NSValue *fromVal2 = line2[0];
CGPoint fromPoint2 = [fromVal2 CGPointValue];
NSValue *toVal2 = line2[1];
CGPoint toPoint2 = [toVal2 CGPointValue];
if(fromPoint2.x == toPoint1.x && fromPoint2.y == toPoint1.y){
toVal1 = toVal2;
toPoint1 = toPoint2;
[line1 replaceObjectAtIndex:1 withObject:toVal2];
[arrVLinePoint replaceObjectAtIndex:j withObject:[[NSMutableArray alloc] initWithCapacity:0]];
}
}
}
for(int i = 0 ; i < arrVLinePoint.count; i ++){
NSArray *line1 = arrVLinePoint[i];
if (line1.count == 0) {
continue;
}
NSValue *fromVal1 = line1[0];
CGPoint fromPoint1 = [fromVal1 CGPointValue];
NSValue *toVal1 = line1[1];
CGPoint toPoint1 = [toVal1 CGPointValue];
NSNumber *direction = line1[3];
[IrregularBorderView drawLineInView:view fromPoint:fromPoint1 toPoint:toPoint1 direction:[direction intValue] borderColor:borderColor];
}
}
+ (void)drawLineInView:(UIView *)view fromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint direction:(int)direction borderColor:(CGFloat [3])borderColor
{
if(fromPoint.x == toPoint.x && fromPoint.y == toPoint.y ){
return;
}
UIImageView *imageView = (UIImageView *)[view viewWithTag:LINE_VIEW_TAG];
if (imageView == nil) {
imageView=[[UIImageView alloc] initWithFrame:view.frame];
imageView.tag = LINE_VIEW_TAG;
[view addSubview:imageView];
}
UIGraphicsBeginImageContext(imageView.frame.size);
[imageView.image drawInRect:CGRectMake(0, 0, imageView.frame.size.width, imageView.frame.size.height)];
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapSquare); //边缘样式
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), BORDER_WIDTH); //线宽
CGContextSetAllowsAntialiasing(UIGraphicsGetCurrentContext(), YES);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), borderColor[0], borderColor[1], borderColor[2], borderColor[3]); //颜色
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), fromPoint.x, fromPoint.y); //起点坐标
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), toPoint.x, toPoint.y); //终点坐标
CGContextStrokePath(UIGraphicsGetCurrentContext());
imageView.image=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
@end