Swift 3:从 UIBezierPath 创建 UIImage [英] Swift 3: Create UIImage from UIBezierPath
问题描述
我有一个 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 中引入的.如果你需要支持早期的 iOS 版本,你可以使用 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
,只需定义一个带有 CAShapeLayer
的 UIView
子类:
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屋!