Swift 3:从 UIBezierPath 创建 UIImage [英] Swift 3: Create UIImage from UIBezierPath

查看:24
本文介绍了Swift 3:从 UIBezierPath 创建 UIImage的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 UIBezierPath,我最终需要一个 UIImageView .现在我正在尝试首先创建一个 UIImage,然后从中创建一个 UIImageView.

I have a UIBezierPath, and I ultimately I need a UIImageView from it. Right now I'm trying to first create a UIImage, and then a UIImageView from that.

我正在快速工作,我看过类似的问题,答案要么不起作用,要么产生形状而不是曲线.我的贝塞尔曲线代表草图而不是实际形状.我不想关闭贝塞尔曲线,这就是 UIImage.shapeImageWithBezierPath() 所做的.最后一个解决方案是唯一一个实际封装了完整曲线的解决方案.所有其他解决方案要么产生碎片,要么根本不出现.

I'm working in swift, and I have looked at similar questions, and the answers either don't work or produce a shape rather than a curve. My beziers represent sketches as opposed to actual shapes. I don't want the bezier closed, which is what UIImage.shapeImageWithBezierPath() does. This last solution is the only one which has actually encapsulated the full curve. All the other solutions either produce fragments or don't show up at all.

最终目标是创建一个CollectionView,将这些曲线作为列表中的项目,这意味着我最终必须将UIBeziers 放入CollectionViewCells>.

The end goal is to create a CollectionView with these curves as items in the list, meaning that I ultimately have to put UIBeziers into CollectionViewCells.

提前致谢.

推荐答案

如果你想要 UIImage(你可以和 UIImageView 一起使用),你可以使用 UIGraphicsImageRenderer:

If you want UIImage (which you can use with UIImageView), you can use UIGraphicsImageRenderer:

private func image(with path: UIBezierPath, size: CGSize) -> UIImage {
    return UIGraphicsImageRenderer(size: size).image { _ in
        UIColor.blue.setStroke()
        path.lineWidth = 2
        path.stroke()
    }
}

这是在 iOS 10 中引入的.如果你需要支持早期的 iO​​S 版本,你可以使用 UIGraphicsGetImageFromCurrentImageContext:

That was introduced in iOS 10. If you need to support earlier iOS versions, you can use the UIGraphicsGetImageFromCurrentImageContext:

private func image(with path: UIBezierPath, size: CGSize) -> UIImage? {
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    UIColor.blue.setStroke()
    path.lineWidth = 2
    path.stroke()
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
}

<小时>

或者,如果需要,您可以绕过 UIImage,只需定义一个带有 CAShapeLayerUIView 子类:


Alternatively, you can bypass the UIImage if you want, and just define a UIView subclass with a CAShapeLayer:

@IBDesignable
class ShapeView: UIView {

    @IBInspectable var lineWidth:   CGFloat = 1   { didSet { shapeLayer.lineWidth   = lineWidth } }
    @IBInspectable var strokeColor: UIColor = #colorLiteral(red: 0, green: 0, blue: 1, alpha: 1)  { didSet { shapeLayer.strokeColor = strokeColor.cgColor } }
    @IBInspectable var fillColor:   UIColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 0)  { didSet { shapeLayer.fillColor   = fillColor.cgColor } }

    var path:  UIBezierPath? { didSet { shapeLayer.path = path?.cgPath } }

    private let shapeLayer = CAShapeLayer()

    override init(frame: CGRect) {
        super.init(frame: frame)

        configure()
    }

    convenience init() {
        self.init(frame: .zero)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        configure()
    }

    /// Add and configure the view.
    ///
    /// Add and configure shape.

    private func configure() {
        layer.addSublayer(shapeLayer)

        shapeLayer.strokeColor = self.strokeColor.cgColor
        shapeLayer.fillColor   = self.fillColor.cgColor
        shapeLayer.lineWidth   = self.lineWidth
    }

    // just add some path so if you used this in IB, you'll see something

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        shapeLayer.path = UIBezierPath(ovalIn: bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2)).cgPath
    }

}

这篇关于Swift 3:从 UIBezierPath 创建 UIImage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆