简体   繁体   English

如何在 Swift 中向 UIImageView 添加自定义形状?

[英]How to add a custom shape to an UIImageView in Swift?

I'm trying to add a custom shape to an imageView .我正在尝试向imageView添加自定义形状。 Please check the below images.请检查以下图片。

This is the required one:这是必需的:

所需的图像形状

This is what I have done so far:这是我到目前为止所做的:

当前图像形状

I'm new to Core Graphics and I have done this so far:我是Core Graphics新手,到目前为止我已经做到了:

    private func customImageClipper(imageV: UIImageView){

    let path = UIBezierPath()

    let size = imageV.frame.size

    print(size)

    path.move(to: CGPoint(x: 0.0, y: size.height))

    path.addLine(to: CGPoint(x: 0.8, y: size.height/2))

    path.close()

    let shape = CAShapeLayer()

    shape.path = path.cgPath

    imageV.layer.sublayers = [shape]

}

I'm creating a function to achieve a shape like this, but whenever I pass the imageView into this function, I can not see any change at all.我正在创建一个函数来实现这样的形状,但是每当我将imageView传递给这个函数时,我根本看不到任何变化。 I know that I have to move from points to another point to achieve this shape, but I have never done this.我知道我必须从一个点移动到另一个点才能达到这个形状,但我从来没有这样做过。 Any help would be appreciated.任何帮助,将不胜感激。 This is how I'm calling this function:这就是我调用这个函数的方式:

imageV.layoutIfNeeded()

customImageClipper(imageV: imageV)

PS: I'm not using Storyboard , I have created this programmatically. PS:我没有使用Storyboard ,我以编程方式创建了它。

There are many ways to create shapes using UIBezierPaths.有很多方法可以使用 UIBezierPaths 创建形状。 This post here discusses the use of the draw function to create a shape.此处的这篇文章讨论了使用draw函数创建形状。

Here is an example using your clip function within the cell.这是在单元格中使用clip功能的示例。

func clip(imageView: UIView, withOffset offset: CGFloat) {
    let path = UIBezierPath()

    //Move to Top Left
    path.move(to: .init(x: imageView.bounds.size.width * offset, y: 0))

    //Draw line from Top Left to Top Right
    path.addLine(to: .init(x: imageView.bounds.size.width, y: 0))

    //Draw Line from Top Right to Bottom Right
    path.addLine(to: .init(x: imageView.bounds.size.width * (1 - offset), y: imageView.bounds.size.height))

    //Draw Line from Bottom Right to Bottom Left
    path.addLine(to: .init(x: 0, y: imageView.bounds.size.height))

    //Close Path
    path.close()

    //Create the Shape Mask for the ImageView
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = path.cgPath
    shapeLayer.fillColor = UIColor.black.cgColor
    imageView.layer.mask = shapeLayer
}

In this function, the offset is the amount of angle you would like on the shape, ranging from 0 to 1. (0.4) seems to work for your requirements.在这个函数中,偏移量是你想要的形状的角度量,范围从 0 到 1。(0.4) 似乎适合你的要求。

This shares a lot of similarities with Apseri's answer, except I chose the route of percentages, rather than exact size.这与 Apseri 的答案有很多相似之处,除了我选择了百分比路线,而不是确切大小。 Nothing wrong with either approach, I just found it easier to understand with percentages.这两种方法都没有错,我只是发现百分比更容易理解。 :) :)

One last note to point out, I used this function in the layoutSubviews function.最后要指出的是,我在layoutSubviews函数中使用了这个函数。

override func layoutSubviews() {
    super.layoutSubviews()
    imageView.layoutIfNeeded()
    clip(imageView: self.imageView, withOffset: 0.4)
}

This output the following image:这输出以下图像:

显示自定义形状的单元格图像

Hope this helps.希望这可以帮助。

Here is example of some path clipping.这是一些路径剪辑的示例。 Of course path can be also put via parameters, and this can be applied to any view, as shown.当然路径也可以通过参数放置,这可以应用于任何视图,如图所示。

Before:前:

在此处输入图片说明

After (grey background is below ScrollView background):之后(灰色背景在 ScrollView 背景下方):

在此处输入图片说明

func customImageClipper(imageV: UIView){

    let path = UIBezierPath()
    let size = imageV.frame.size

    path.move(to: CGPoint(x: size.width/3.0, y: 0))
    path.addLine(to: CGPoint(x: size.width/3.0 + 50, y: 0))
    path.addLine(to: CGPoint(x: size.width/3.0, y: size.height))
    path.addLine(to: CGPoint(x: size.width/3.0 - 50, y: size.height))
    path.addLine(to: CGPoint(x: size.width/3.0, y: 0))
    path.close()

    let shape = CAShapeLayer()
    shape.path = path.cgPath
    shape.fillColor = UIColor.black.cgColor

    imageV.layer.mask = shape
}

1- Subclassing your UIImageView 1-子类化你的 UIImageView

2- implement your custom drawings inside setNeedsLayout using UIBezierPath 2- 使用 UIBezierPath 在 setNeedsLayout 中实现您的自定义绘图

class MyCustomImageView: UIImageView {  



    override func setNeedsLayout() {
        let path = UIBezierPath()
        path.moveToPoint(CGPoint(x: self.frame.size.width/2, y: self.frame.size.height))
        path.addLineToPoint(CGPoint(x: self.frame.size.width, y: self.frame.size.height/2))
        path.addLineToPoint(CGPoint(x: self.frame.size.width/2, y: 0))
        path.addArcWithCenter(CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2), radius: self.frame.size.width/2, startAngle:-CGFloat(M_PI_2), endAngle: CGFloat(M_PI_2), clockwise: false)

        path.moveToPoint(CGPoint(x: self.frame.size.width/2, y: self.frame.size.height))
        path.closePath()
        UIColor.redColor().setFill()
        path.stroke()
        path.bezierPathByReversingPath()
        let shapeLayer = CAShapeLayer()
        shapeLayer.frame = self.bounds
        shapeLayer.path = path.CGPath
        shapeLayer.fillColor = UIColor.redColor().CGColor
        self.layer.mask = shapeLayer;
        self.layer.masksToBounds = true;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM