如何在下面的ios中设置像六边形的图像视图

时间:2016-01-14 11:30:52

标签: ios objective-c uiimageview

我需要像六角形一样给出imageView的界限。我在Stack Overflow中搜索并获取代码,但它并不完全满足需要。

Please click here.this is my example imageview

2 个答案:

答案 0 :(得分:2)

好的,这是一个如何做的例子。

首先,在UIBezierPath上创建一个类别:

<强>目标C

.h文件:

@import UIKit.UIBezierPath;

@interface UIBezierPath (Additions)

+ (UIBezierPath * _Nullable)bezierPathWithSquare:(CGRect)square numberOfSides:(NSUInteger)numberOfSides cornerRadius:(CGFloat)cornerRadius;

@end

.m文件:

#import "UIBezierPath+Additions.h"

@implementation UIBezierPath (Additions)

+ (UIBezierPath *)bezierPathWithSquare:(CGRect)square numberOfSides:(NSUInteger)numberOfSides cornerRadius:(CGFloat)cornerRadius
{
    if ( CGRectGetWidth(square) != CGRectGetHeight(square) )
    {
        return nil;
    }

    CGFloat squareWidth = CGRectGetWidth(square);

    if ( numberOfSides == 0 || cornerRadius < 0.0 || 2.0 * cornerRadius > squareWidth || CGRectIsInfinite(square) || CGRectIsEmpty(square) || CGRectIsNull(square) )
    {
        return nil;
    }

    UIBezierPath *path = [UIBezierPath new];

    CGFloat theta = 2.0 * M_PI / numberOfSides;
    CGFloat offset = cornerRadius * tan(0.5 * theta);

    CGFloat length = squareWidth - path.lineWidth;
    if ( numberOfSides % 4 != 0 )
    {
        length = length * cos(0.5 * theta);
    }

    CGFloat sideLength = length * tan(0.5 * theta);

    CGFloat p1 = squareWidth / 2.0 + sideLength / 2.0 - offset;
    CGFloat p2 = squareWidth - (squareWidth - length) / 2.0;
    CGPoint point = CGPointMake(p1, p2);
    CGFloat angle = M_PI;
    [path moveToPoint:point];

    for ( NSUInteger i = 0; i < numberOfSides; i++ )
    {
        CGFloat x1 = point.x + ( sideLength - offset * 2.0 ) * cos(angle);
        CGFloat y1 = point.y + ( sideLength - offset * 2.0 ) * sin(angle);

        point = CGPointMake(x1, y1);
        [path addLineToPoint:point];

        CGFloat centerX = point.x + cornerRadius * cos(angle + M_PI_2);
        CGFloat centerY = point.y + cornerRadius * sin(angle + M_PI_2);
        CGPoint center = CGPointMake(centerX, centerY);
        CGFloat radius = cornerRadius;
        CGFloat startAngle = angle - M_PI_2;
        CGFloat endAngle = angle + theta - M_PI_2;

        [path addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
        point = path.currentPoint;
        angle += theta;
    }

    [path closePath];

    return path;
}

@end

然后,您的视图控制器的实现将如下所示:

#import "ViewController.h"
#import "UIBezierPath+Additions.h"

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIImageView *imageView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self setupImageViewHexagonMask];
}

- (void)setupImageViewHexagonMask
{
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithSquare:self.imageView.bounds numberOfSides:6 cornerRadius:20.0];
    CAShapeLayer *maskingLayer = [CAShapeLayer layer];
    maskingLayer.path = maskPath.CGPath;

    self.imageView.layer.mask = maskingLayer;
}

@end

Swift 2

UIBezierPath

上创建扩展程序
import UIKit

/** Additions Extends UIBezierPath

*/
extension UIBezierPath {

    convenience init?(square: CGRect, numberOfSides: UInt, cornerRadius: CGFloat) {

        guard CGRectGetWidth(square) == CGRectGetHeight(square) else {

            return nil
        }

        let squareWidth = CGRectGetWidth(square)

        guard numberOfSides > 0 && cornerRadius >= 0.0 && 2.0 * cornerRadius < squareWidth && !CGRectIsInfinite(square) && !CGRectIsEmpty(square) && !CGRectIsNull(square) else {

            return nil
        }

        self.init()

        // how much to turn at every corner
        let theta =  CGFloat(2.0 * M_PI) / CGFloat(numberOfSides)

        // offset from which to start rounding corners
        let offset: CGFloat = cornerRadius * CGFloat(tan( theta / 2.0 ))

        var length = squareWidth - lineWidth
        if( numberOfSides % 4 != 0){
            length = length * cos(theta / 2.0)
        }

        let sideLength = length * CGFloat(tan(theta / 2.0))

        // start drawing ap 'point' in lower right corner
        let p1 = squareWidth / 2.0 + sideLength / 2.0 - offset
        let p2 = squareWidth - ((squareWidth - length) / 2.0)
        var point = CGPointMake(CGFloat(p1), CGFloat(p2))
        var angle = CGFloat(M_PI)
        moveToPoint(point)

        // draw the sides around rounded corners of the polygon
        for ( var i: UInt = 0; i < numberOfSides; i++){
            let x1 = CGFloat(point.x) + ((sideLength - offset * 2.0) * CGFloat(cos(angle)))
            let y1 = CGFloat(point.y) + ((sideLength - offset * 2.0) * CGFloat(sin(angle)))

            point = CGPointMake(CGFloat(x1), CGFloat(y1))
            addLineToPoint(point)

            let centerX = point.x + cornerRadius * CGFloat(cos(angle + CGFloat(M_PI_2)))
            let centerY = point.y + cornerRadius * CGFloat(sin(angle + CGFloat(M_PI_2)))
            let center = CGPointMake(CGFloat(centerX), CGFloat(centerY))
            let radius:CGFloat = CGFloat(cornerRadius)
            let startAngle = CGFloat(angle) - CGFloat(M_PI_2)
            let endAngle = CGFloat(angle) + CGFloat(theta) - CGFloat(M_PI_2)

            addArcWithCenter(center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
            point = currentPoint
            angle += theta

        }

        closePath()
    }
}

示例视图控制器的实现:

import UIKit

class ViewController: UIViewController {

    @IBOutlet private weak var imageView: UIImageView!

    override func viewWillAppear(animated: Bool) {

        super.viewWillAppear(animated)
        applyHexagonMask()
    }

    private func applyHexagonMask() {

        let maskPath = UIBezierPath(square: imageView.bounds, numberOfSides: 6, cornerRadius: 10.0)

        let maskingLayer = CAShapeLayer()
        maskingLayer.path = maskPath?.CGPath

        imageView.layer.mask = maskingLayer
    }
}

Swift 4

import UIKit

extension UIBezierPath {

    convenience init?(square: CGRect, numberOfSides: UInt, cornerRadius: CGFloat) {

        guard square.width == square.height else { return nil }

        let squareWidth = square.width

        guard numberOfSides > 0 && cornerRadius >= 0.0 && 2.0 * cornerRadius < squareWidth && !square.isInfinite && !square.isEmpty && !square.isNull else {

            return nil
        }

        self.init()

        // how much to turn at every corner
        let theta =  2.0 * .pi / CGFloat(numberOfSides)
        let halfTheta = 0.5 * theta

        // offset from which to start rounding corners
        let offset: CGFloat = cornerRadius * CGFloat(tan(halfTheta))

        var length = squareWidth - self.lineWidth
        if numberOfSides % 4 > 0 {

            length = length * cos(halfTheta)
        }

        let sideLength = length * CGFloat(tan(halfTheta))

        // start drawing at 'point' in lower right corner
        let p1 = 0.5 * (squareWidth + sideLength) - offset
        let p2 = squareWidth - 0.5 * (squareWidth - length)
        var point = CGPoint(x: p1, y: p2)
        var angle = CGFloat.pi

        self.move(to: point)

        // draw the sides around rounded corners of the polygon
        for _ in 0..<numberOfSides {

            let x1 = CGFloat(point.x) + ((sideLength - offset * 2.0) * CGFloat(cos(angle)))
            let y1 = CGFloat(point.y) + ((sideLength - offset * 2.0) * CGFloat(sin(angle)))

            point = CGPoint(x: x1, y: y1)
            self.addLine(to: point)

            let centerX = point.x + cornerRadius * CGFloat(cos(angle + 0.5 * .pi))
            let centerY = point.y + cornerRadius * CGFloat(sin(angle + 0.5 * .pi))
            let center = CGPoint(x: centerX, y: centerY)
            let startAngle = CGFloat(angle) - 0.5 * .pi
            let endAngle = CGFloat(angle) + CGFloat(theta) - 0.5 * .pi

            self.addArc(withCenter: center, radius: cornerRadius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
            point = self.currentPoint
            angle += theta

        }

        self.close()
    }
}

示例视图控制器的实现:

class ViewController: UIViewController {

    @IBOutlet private weak var imageView: UIImageView!

    override func viewWillAppear(_ animated: Bool) {

        super.viewWillAppear(animated)
        applyHexagonMask()
    }

    private func applyHexagonMask() {

        let maskPath = UIBezierPath(square: imageView.bounds, numberOfSides: 6, cornerRadius: 10.0)

        let maskingLayer = CAShapeLayer()
        maskingLayer.path = maskPath?.cgPath

        imageView.layer.mask = maskingLayer
    }
}

游乐场的结果:

Result

享受。

答案 1 :(得分:0)

以下代码适用于我:

super()