Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用PDF矢量图像作为内容时出现模糊的CALayer_Ios_Swift_Uikit_Core Graphics_Core Animation - Fatal编程技术网

Ios 使用PDF矢量图像作为内容时出现模糊的CALayer

Ios 使用PDF矢量图像作为内容时出现模糊的CALayer,ios,swift,uikit,core-graphics,core-animation,Ios,Swift,Uikit,Core Graphics,Core Animation,我试图使用PDF矢量图像作为CALayer的内容,但当它缩放到15x13的初始大小以上时,看起来非常模糊。我已在有关图像的资源目录中启用了“保留向量数据”。下面是我的视图的代码,它在一个图层上绘制一个外圆,如果isComplete属性设置为true,则使用第二个图层在视图中心显示复选标记的图像 @IBDesignable public class GoalCheckView: UIView { // MARK: - Public properties @IBInspectab

我试图使用PDF矢量图像作为
CALayer
的内容,但当它缩放到15x13的初始大小以上时,看起来非常模糊。我已在有关图像的资源目录中启用了“保留向量数据”。下面是我的视图的代码,它在一个图层上绘制一个外圆,如果
isComplete
属性设置为
true
,则使用第二个图层在视图中心显示复选标记的图像

@IBDesignable
public class GoalCheckView: UIView {

    // MARK: - Public properties

    @IBInspectable public var isComplete: Bool = false {
        didSet {
            setNeedsLayout()
        }
    }

    // MARK: - Private properties

    private lazy var checkImage: UIImage? = {
        let bundle = Bundle(for: type(of: self))
        return UIImage(named: "check_event_carblog_confirm", in: bundle, compatibleWith: nil)
    }()

    private var checkImageSize: CGSize {
        let widthRatio: CGFloat  = 15 / 24 // Size of image is 15x13 when circle is 24x24
        let heightRatio: CGFloat = 13 / 24
        return CGSize(width: bounds.width * widthRatio, height: bounds.height * heightRatio)
    }

    private let circleLayer = CAShapeLayer()
    private let checkLayer = CALayer()
    private let lineWidth: CGFloat = 1

    // MARK: - View lifecycle

    public override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

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

    public override func layoutSubviews() {
        super.layoutSubviews()

        // Layout circle
        let path = UIBezierPath(ovalIn: bounds.insetBy(dx: lineWidth / 2, dy: lineWidth / 2))
        circleLayer.path = path.cgPath

        // Layout check
        checkLayer.frame = CGRect(
            origin: CGPoint(x: bounds.midX - checkImageSize.width / 2, y: bounds.midY - checkImageSize.height / 2),
            size: checkImageSize
        )
        checkLayer.opacity = isComplete ? 1 : 0
    }

    // MARK: - Private methods

    private func setupView() {

        // Setup circle layer
        circleLayer.lineWidth = lineWidth
        circleLayer.fillColor = nil
        circleLayer.strokeColor = UIColor(named: "goal_empty", in: bundle, compatibleWith: nil)?.cgColor
        layer.addSublayer(circleLayer)

        // Setup check layer
        checkLayer.contentsScale = UIScreen.main.scale
        checkLayer.contentsGravity = .resizeAspect
        checkLayer.contents = checkImage?.cgImage
        layer.addSublayer(checkLayer)
    }
}
如果我将视图的大小设置为240x240,则此代码将导致以下显示:


我能够为此创建一个解决方案。我可以在
layoutSubviews
中检查图像的预期大小,如果它与
UIImage
的大小不匹配,我可以使用
UIGraphicsImageRenderer
创建缩放到正确大小的新图像。我创建了一个
UIImage
的扩展来实现这一点:

extension UIImage {

    internal func imageScaled(toSize scaledSize: CGSize) -> UIImage {
        let renderer = UIGraphicsImageRenderer(size: scaledSize)
        let newImage = renderer.image { [unowned self] _ in
            self.draw(in: CGRect(origin: .zero, size: scaledSize))
        }
        return newImage
    }
}
现在,我更新的
layoutSubviews
方法如下所示:

public override func layoutSubviews() {
    super.layoutSubviews()

    // Layout circle
    let path = UIBezierPath(ovalIn: bounds.insetBy(dx: lineWidth.mid, dy: lineWidth.mid))
    circleLayer.path = path.cgPath

    // Layout check
    if let checkImage = checkImage, checkImage.size != checkImageSize {
        checkLayer.contents = checkImage.imageScaled(toSize: checkImageSize).cgImage
    }
    let checkOrigin  = CGPoint(x: bounds.midX - checkImageSize.midW, y: bounds.midY - checkImageSize.midH)
    checkLayer.frame = CGRect(origin: checkOrigin, size: checkImageSize)
}
这将产生一个清晰的图像:


我尝试过设置
checkLayer.rasterizationScale=UIScreen.main.scale
checkLayer.shouldrasterizaze=true
,但这似乎没有任何区别。