2017-03-16 60 views
2

我有一个UIBezierPath,最终我需要一个UIImageView。现在我试图先创建一个UIImage,然后再创建一个UIImageView。Swift 3:从UIBezierPath创建UIImage

我在swift中工作,并且我查看了类似的问题,并且答案要么不工作要么产生形状而不是曲线。我的贝塞尔代表草图而不是实际的形状。我不想让bezier关闭,这是UIImage.shapeImageWithBezierPath()所做的。最后一个解决方案是唯一一个实际封装完整曲线的解决方案。所有其他解决方案要么产生碎片,要么完全不出现。

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

在此先感谢。

+1

有几个选择。可能是最好的一个涉及绘制CGContext(使用UIBezierPath.cgPath),然后将其转换为CGImage。从那里制作UIImage非常简单,但你可能不需要。 – dfd

回答

3

如果你想UIImage(你可以用UIImageView使用),你可以使用UIGraphicsGetImageFromCurrentImageContext得到UIImage然后你可以使用你的UImageView产生的图像。

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如果你想,只是定义UIView子类有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 
    } 

} 
+1

这工作,但我意识到我一直在做错了什么。贝塞尔路径是使用CGPoints手动计算的,并且从CGFrames到UIImage的转换是罪魁祸首。所以我有一些事情要解决 –