iOS 不规则View

//
//  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
时间: 2024-08-05 20:56:55

iOS 不规则View的相关文章

iOS 判断View 是否是第一次显示

在实现某些需求的时候会有这样的情况,页面第一次加载显示的时候需要某些操作,而以后就不需要重复执行了, 一般这种处理都放在- (void)viewDidLoad或- (id)init因为一般这两个函数除了在第一次显示或初始化以后就不会走了. 如果反过来呢页面第一次加载显示的时候不需要某些操作,但是如果是非第一次就需要做些判断,这个时候就需要做一些处理. 我选择了用计数来控制通过-(void)viewDidAppear:(BOOL)animated来控制 做法就是全局一个int isfirst 在-

一句话搞定IOS中View的Frame和Bound

就一句话,Frame是父View上看到子View的窗户,Bound是子View上可以被父View看见的内容. 稍微解释下.Frame 指子View在父View中的位置以及大小.由两部分构成,第一部分是Origin,规定了子View在父类的位置.第二部分是Size,指View在父类中的可视范围(这里能说是View的大小).这感觉像是在父View中在Frame.Origin位置打开一个窗户,窗户的大小是Frame.Size,从窗户中可以看到子View的内容. Bound 指子View自身显示那些内容

iOS Programming View Controllers 视图控制器

iOS Programming View Controllers? 视图控制器? 1.1? A view controller is an instance of a subclass of UIViewController. 一个view controller 是一个UIViewController的子类. A view controller manages a view hierarchy. 一个view controller 管理一个视图树. It is responsible for c

iOS show view above keyboard

Access the main window or view: http://stackoverflow.com/questions/6820017/ios-access-main-window-or-view http://www.cnblogs.com/ihojin/p/view-cover-keyboard.html http://stackoverflow.com/questions/6544042/show-a-view-over-the-keyboard iOS show view

iOS 制作view渐变的效果CAGradientLayer

有时候我们需要在view中加入渐变的效果来让它看起来有玻璃质感,可以使用Core Animation框架中提供的CAGradientLayer来实现. 代码如下:首先添加QuartzCore.framework然后加入如下代码: #import <QuartzCore/QuartzCore.h> - (CAGradientLayer *)shadowAsInverse { CAGradientLayer *newShadow = [[[CAGradientLayer alloc] init] 

iOS xib View宽高不能改变

IOS - xib(Interface Builder,view) - can't change view size(view不能改变大小问题) 今天在试着swift语言写个demo,,当中遇到了这个问题,分享一下 当我们自己定义tableview.collectionview的cell,也有时候我们要自己定义窗体xib,但创建xib后,其height.width不可改动. 这时问题就来了.怎么才干使我们的自己定义xib宽高可改动: 项目中创建xib,单独的view时, 方法: 默认Simula

【转】iOS应用view之间数据传递的方式

数据在view之间传递分为两大类:直接传递与间接传递.其中间接传递里面还可以定义一个singleton,用来共享数据. [iOS5之前的旧解决方法] 1)采用代理模式 子viewcontroller设计 代理协议,定义协议接口,父viewcontroller 实现协议接口,实现子viewcontroller 退出时将相关数据更新到父视图.2)采用ios的消息机制 父viewcontroller注册消息 子viewcontroller 发送消息,触发父viewcontroller的消息处理.3)采

ios应用view之间数据传递的方式

对于不同的viewcontroller之间数据的共享和处理 采用代理的方式,子viewcontroller设计代理协议,并定义协议接口,父viewcontroller实现协议接口,实现子视图控制器退出时将相关数据更新到父视图中 采用ios的消息机制,父viewcontroller注册消息,子viewcontroller发送消息,触发父viewcontroller的消息处理 采用database作为数据中间的存储媒介,子viewcontroller将状态数据存入DB,父viewcontrller从

iOS 不规则的ImageView

我们在做iOS开发的时候,往往需要实现不规则形状的头像,如: 那如何去实现? 通常图片都是矩形的,如果想在客户端去实现不规则的头像,需要自己去实现. 1.使用layer去实现, 见http://blog.csdn.net/johnzhjfly/article/details/39993345 2.使用CAShapeLayer, CALayer如何去实现 我们来看看如何使用CAShapeLayer去实现, 定义一个ShapedImageView,继承于UIView, 代码如下: #import "