我正在尝试为我成功的UI Image添加一个六边形面具.但是我无法绕六边形面具的两侧.我想加上cell.profilePic.layer.cornerRadius = 10;会做的伎俩,但它没有.

这是我的代码:

CGRect rect = cell.profilePic.frame;

CAShapeLayer *hexagonMask = [CAShapeLayer layer];
CAShapeLayer *hexagonBorder = [CAShapeLayer layer];
hexagonBorder.frame = cell.profilePic.layer.bounds;
UIBezierPath *hexagonPath = [UIBezierPath bezierPath];
CGFloat sideWidth = 2 * ( 0.5 * rect.size.width / 2 );
CGFloat lcolumn = ( rect.size.width - sideWidth ) / 2;
CGFloat rcolumn = rect.size.width - lcolumn;
CGFloat height = 0.866025 * rect.size.height;
CGFloat y = (rect.size.height - height) / 2;
CGFloat by = rect.size.height - y;
CGFloat midy = rect.size.height / 2;
CGFloat rightmost = rect.size.width;
[hexagonPath movetoPoint:CGPointMake(lcolumn,y)];
[hexagonPath addLinetoPoint:CGPointMake(rcolumn,y)];
[hexagonPath addLinetoPoint:CGPointMake(rightmost,midy)];
[hexagonPath addLinetoPoint:CGPointMake(rcolumn,by)];
[hexagonPath addLinetoPoint:CGPointMake(lcolumn,by)];
[hexagonPath addLinetoPoint:CGPointMake(0,midy)];
[hexagonPath addLinetoPoint:CGPointMake(lcolumn,y)];

hexagonMask.path = hexagonPath.CGPath;
hexagonBorder.path = hexagonPath.CGPath;
hexagonBorder.fillColor = [UIColor clearColor].CGColor;
hexagonBorder.strokeColor = [UIColor blackColor].CGColor;
hexagonBorder.linewidth = 5;
cell.profilePic.layer.mask = hexagonMask;
cell.profilePic.layer.cornerRadius = 10;
cell.profilePic.layer.masksToBounds = YES;
[cell.profilePic.layer addSublayer:hexagonBorder];

有任何想法吗?

谢谢

解决方法

您可以定义一个带圆角的六边形路径(手动定义该路径),然后将其应用为蒙版和边框子图层:
CGFloat linewidth    = 5.0;
UIBezierPath *path   = [UIBezierPath polygonInRect:self.imageView.bounds
                                             sides:6
                                         linewidth:linewidth
                                      cornerRadius:30];

// mask for the image view

CAShapeLayer *mask   = [CAShapeLayer layer];
mask.path            = path.CGPath;
mask.linewidth       = linewidth;
mask.strokeColor     = [UIColor clearColor].CGColor;
mask.fillColor       = [UIColor whiteColor].CGColor;
self.imageView.layer.mask = mask;

// if you also want a border,add that as a separate layer

CAShapeLayer *border = [CAShapeLayer layer];
border.path          = path.CGPath;
border.linewidth     = linewidth;
border.strokeColor   = [UIColor blackColor].CGColor;
border.fillColor     = [UIColor clearColor].CGColor;
[self.imageView.layer addSublayer:border];

具有圆角的正多边形的路径可能在类似的类别中实现:

@interface UIBezierPath (polygon)

/** Create UIBezierPath for regular polygon with rounded corners
 *
 * @param rect          The CGRect of the square in which the path should be created.
 * @param sides         How many sides to the polygon (e.g. 6=hexagon; 8=octagon,etc.).
 * @param linewidth     The width of the stroke around the polygon. The polygon will be inset such that the stroke stays within the above square.
 * @param cornerRadius  The radius to be applied when rounding the corners.
 *
 * @return              UIBezierPath of the resulting rounded polygon path.
 */

+ (instancetype)polygonInRect:(CGRect)rect sides:(NSInteger)sides linewidth:(CGFloat)linewidth cornerRadius:(CGFloat)cornerRadius;

@end

@implementation UIBezierPath (polygon)

+ (instancetype)polygonInRect:(CGRect)rect sides:(NSInteger)sides linewidth:(CGFloat)linewidth cornerRadius:(CGFloat)cornerRadius {
    UIBezierPath *path  = [UIBezierPath bezierPath];

    CGFloat theta       = 2.0 * M_PI / sides;                           // how much to turn at every corner
    CGFloat offset      = cornerRadius * tanf(theta / 2.0);             // offset from which to start rounding corners
    CGFloat squareWidth = MIN(rect.size.width,rect.size.height);   // width of the square

    // calculate the length of the sides of the polygon

    CGFloat length      = squareWidth - linewidth;
    if (sides % 4 != 0) {                                               // if not dealing with polygon which will be square with all sides ...
        length = length * cosf(theta / 2.0) + offset/2.0;               // ... offset it inside a circle inside the square
    }
    CGFloat sideLength = length * tanf(theta / 2.0);

    // start drawing at `point` in lower right corner

    CGPoint point = CGPointMake(rect.origin.x + rect.size.width / 2.0 + sideLength / 2.0 - offset,rect.origin.y + rect.size.height / 2.0 + length / 2.0);
    CGFloat angle = M_PI;
    [path movetoPoint:point];

    // draw the sides and rounded corners of the polygon

    for (NSInteger side = 0; side < sides; side++) {
        point = CGPointMake(point.x + (sideLength - offset * 2.0) * cosf(angle),point.y + (sideLength - offset * 2.0) * sinf(angle));
        [path addLinetoPoint:point];

        CGPoint center = CGPointMake(point.x + cornerRadius * cosf(angle + M_PI_2),point.y + cornerRadius * sinf(angle + M_PI_2));
        [path addArcWithCenter:center radius:cornerRadius startAngle:angle - M_PI_2 endAngle:angle + theta - M_PI_2 clockwise:YES];

        point = path.currentPoint; // we don't have to calculate where the arc ended ... UIBezierPath did that for us
        angle += theta;
    }

    [path closePath];

    path.linewidth = linewidth;           // in case we're going to use CoreGraphics to stroke path,rather than CAShapeLayer
    path.lineJoinStyle = kCGLineJoinRound;

    return path;
}

产生这样的结果:

或者在Swift 3中你可以这样做:

let linewidth: CGFloat = 5
let path = UIBezierPath(polygonIn: imageView.bounds,sides: 6,linewidth: linewidth,cornerRadius: 30)

let mask = CAShapeLayer()
mask.path            = path.cgPath
mask.linewidth       = linewidth
mask.strokeColor     = UIColor.clear.cgColor
mask.fillColor       = UIColor.white.cgColor
imageView.layer.mask = mask

let border = CAShapeLayer()
border.path          = path.cgPath
border.linewidth     = linewidth
border.strokeColor   = UIColor.black.cgColor
border.fillColor     = UIColor.clear.cgColor
imageView.layer.addSublayer(border)

extension UIBezierPath {

    /// Create UIBezierPath for regular polygon with rounded corners
    ///
    /// - parameter rect:            The CGRect of the square in which the path should be created.
    /// - parameter sides:           How many sides to the polygon (e.g. 6=hexagon; 8=octagon,etc.).
    /// - parameter linewidth:       The width of the stroke around the polygon. The polygon will be inset such that the stroke stays within the above square. Default value 1.
    /// - parameter cornerRadius:    The radius to be applied when rounding the corners. Default value 0.

    convenience init(polygonIn rect: CGRect,sides: Int,linewidth: CGFloat = 1,cornerRadius: CGFloat = 0) {
        self.init()

        let theta = 2 * CGFloat.pi / CGFloat(sides)                 // how much to turn at every corner
        let offset = cornerRadius * tan(theta / 2)                  // offset from which to start rounding corners
        let squareWidth = min(rect.size.width,rect.size.height)    // width of the square

        // calculate the length of the sides of the polygon

        var length = squareWidth - linewidth
        if sides % 4 != 0 {                                         // if not dealing with polygon which will be square with all sides ...
            length = length * cos(theta / 2) + offset / 2           // ... offset it inside a circle inside the square
        }
        let sideLength = length * tan(theta / 2)

        // if you'd like to start rotated 90 degrees,use these lines instead of the following two:
        //
        // var point = CGPoint(x: rect.midX - length / 2,y: rect.midY + sideLength / 2 - offset)
        // var angle = -CGFloat.pi / 2.0

        // if you'd like to start rotated 180 degrees,use these lines instead of the following two:
        //
        // var point = CGPoint(x: rect.midX - sideLength / 2 + offset,y: rect.midY - length / 2)
        // var angle = CGFloat(0)

        var point = CGPoint(x: rect.midX + sideLength / 2 - offset,y: rect.midY + length / 2)
        var angle = CGFloat.pi

        move(to: point)

        // draw the sides and rounded corners of the polygon

        for _ in 0 ..< sides {
            point = CGPoint(x: point.x + (sideLength - offset * 2) * cos(angle),y: point.y + (sideLength - offset * 2) * sin(angle))
            addLine(to: point)

            let center = CGPoint(x: point.x + cornerRadius * cos(angle + .pi / 2),y: point.y + cornerRadius * sin(angle + .pi / 2))
            addArc(withCenter: center,radius: cornerRadius,startAngle: angle - .pi / 2,endAngle: angle + theta - .pi / 2,clockwise: true)

            point = currentPoint
            angle += theta
        }

        close()

        self.linewidth = linewidth           // in case we're going to use CoreGraphics to stroke path,rather than CAShapeLayer
        lineJoinStyle = .round
    }

}

对于Swift 2的演绎,请参阅previous revision of this answer.

ios – 如何用Hexagon面具圆角UIImage的角落的更多相关文章

  1. 详解Canvas实用库Fabric.js使用手册

    这篇文章主要介绍了详解Canvas实用库Fabric.js使用手册的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. 【HTML5】3D模型--百行代码实现旋转立体魔方实例

    本篇文章主要介绍【HTML5】3D模型--百行代码实现旋转立体魔方实例,具有一定的参考价值,有需要的可以了解一下。

  3. H5 canvas实现贪吃蛇小游戏

    本篇文章主要介绍了H5 canvas实现贪吃蛇小游戏,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. ios – 如何更改UINavigationBar底部边框的颜色?

    我阅读了许多主题,但没有一个在最新版本的Swift的清晰,一致的答案中解决了这个问题.例如,thisquestion的最佳答案表明UINavigationBar.appearance().setShadowImage().但是,最新版本的swift中不存在这样的方法.我不想隐藏底部边框.我只是想改变颜色.另外,能够改变高度会很棒,但我知道我在一个问题上问得太多了.编辑:我创建了一个2×1像素图像并

  5. ios – sizeToFit削减了一些UILabel字体类型的高度和宽度但不是其他 – 是否有修复?

    我正在使用自定义字体,我有一点障碍.有些字体可以正常使用sizetoFit,如下所示:但是,其他自定义字体在左侧和底部被截断,因为这是:我可以“破解”它,只检查每种字体类型并添加几个像素,但我想知道是否有更清晰的解决方案,甚至解释为什么会发生这种情况.谢谢!

  6. ios – UILabel子类 – 尽管标签高度正确,文字在底部切断

    我有一个问题,UILabel子类切断底部的文本.标签的高度适合文本,底部留有一些空间,但文本仍然被剪掉.红色条纹是添加到标签图层的边框.我将标签子类化以添加边缘插入.但是,在这种特殊情况下,插入是零.解决方法事实证明问题在于改变它解决了这个问题

  7. ios – performBatchUpdates上的UICollectionView性能问题

    我们正在尝试使用自定义布局设置UICollectionView.每个CollectionViewCell的内容都是一个图像.总之,将会有数千张图像,并且在某个特定时间可以看到大约140-150张图像.在动作事件中,可能会在位置和大小上重新组织所有单元格.目标是使用performBatchUpdates方法为当前所有移动事件设置动画.在一切变得动画之前,这会导致很长的延迟时间.到目前为止,我们发现内

  8. ios – 当我缩放时,如何关闭所有图像处理以查看实际的未修改像素?

    我有一个应用程序需要放大到足够远的图像,我可以清楚地看到图像上的单个像素.我需要看到一种颜色的清晰正方形,没有抗锯齿或其他通常有用的技术,使图像在显示器上看起来很好.我如何扼杀所有这些帮助?

  9. 如何清除屏幕截图IOS

    我正在研究IOS应用程序,其中需要采取清晰的屏幕截图我已经尝试过了但是图像的质量并不好.请为我推荐一些东西.解决方法换线至

  10. ios – 如何只向UIImageView添加右边框

    我想为UIImageView添加白色边框.我尝试了以下,但它不起作用:解决方法我现在就这样做了

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部