我有一个UIBezierPath
,最终我需要从中得到一个UIImageView
。现在我正在尝试首先创建一个UIImage
,然后从中UIImageView
。
正在快速工作,我看过类似的问题,答案要么不起作用,要么产生形状而不是曲线。我的贝济尔代表草图而不是实际形状。我不希望贝塞尔关闭,这就是UIImage.shapeImageWithBezierPath()
所做的。最后一个解决方案是唯一一个实际封装完整曲线的解决方案。所有其他解决方案要么产生片段,要么根本不显示。
最终目标是创建一个CollectionView
,将这些曲线作为列表中的项目,这意味着我最终必须UIBeziers
放入CollectionViewCells
。
提前谢谢。
如果你想要UIImage
(你可以与UIImageView
一起使用(,你可以使用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中引入的。如果您需要支持早期的iOS版本,可以使用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
,只需定义一个带有CAShapeLayer
的UIView
子类:
@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
}
}