无法在 UIview 中绘制 - PaintCode

Unable to draw in UIview - PaintCode

我创建了一个折线图的 Paintcode 项目,并尝试在我的 Xcode 项目中实现。但不幸的是 UIView 没有绘制任何东西。 这是我的 StyleKit 文件:

import UIKit

public class LineGraphs : NSObject {

//// Drawing Methods

@objc dynamic public class func draw_7PointLine(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 375, height: 232), resizing: ResizingBehavior = .aspectFit, line: UIColor = UIColor(red: 0.284, green: 0.630, blue: 0.847, alpha: 1.000), horizontal: UIColor = UIColor(red: 0.901, green: 0.901, blue: 0.901, alpha: 1.000), height: CGFloat = 350, point0Value: CGFloat = 221, point1Value: CGFloat = 285, point2Value: CGFloat = 222, point3Value: CGFloat = 136, point4Value: CGFloat = 232, point5Value: CGFloat = 132, point6Value: CGFloat = 235, lineWidth: CGFloat = 3) {
    //// General Declarations
    let context = UIGraphicsGetCurrentContext()!

    //// Resize to Target Frame
    context.saveGState()
    let resizedFrame: CGRect = resizing.apply(rect: CGRect(x: 0, y: 0, width: 375, height: 232), target: targetFrame)
    context.translateBy(x: resizedFrame.minX, y: resizedFrame.minY)
    context.scaleBy(x: resizedFrame.width / 375, y: resizedFrame.height / 232)
    let resizedShadowScale: CGFloat = min(resizedFrame.width / 375, resizedFrame.height / 232)



    //// Shadow Declarations
    let shadow = NSShadow()
    shadow.shadowColor = line
    shadow.shadowOffset = CGSize(width: 2, height: 0)
    shadow.shadowBlurRadius = 5

    //// Variable Declarations
    let topValue = "\(Int(round(height)))"
    let middleValue = "\(Int(round(height / 2.0)))"
    let upperMiddleValue = "\(Int(round(height * 0.75)))"
    let lowerMiddleValue = "\(Int(round(height * 0.25)))"
    let yTop: CGFloat = 10
    let yBottom: CGFloat = 212
    let point0Calculation: CGFloat = yBottom - yTop + 5 - (yBottom - yTop) / height * point0Value
    let point1Calculation: CGFloat = yBottom - yTop + 5 - (yBottom - yTop) / height * point1Value
    let point2Calculation: CGFloat = yBottom - yTop + 5 - (yBottom - yTop) / height * point2Value
    let point3Calculation: CGFloat = yBottom - yTop + 5 - (yBottom - yTop) / height * point3Value
    let point4Calculation: CGFloat = yBottom - yTop + 5 - (yBottom - yTop) / height * point4Value
    let point5Calculation: CGFloat = yBottom - yTop + 5 - (yBottom - yTop) / height * point5Value
    let point6Calculation: CGFloat = yBottom - yTop + 5 - (yBottom - yTop) / height * point6Value

    //// Frames
    let frame0 = CGRect(x: 53, y: point0Calculation, width: 12, height: 12)
    let frame1 = CGRect(x: 101, y: point1Calculation, width: 12, height: 12)
    let frame2 = CGRect(x: 149, y: point2Calculation, width: 12, height: 12)
    let frame3 = CGRect(x: 197, y: point3Calculation, width: 12, height: 12)
    let frame4 = CGRect(x: 245, y: point4Calculation, width: 12, height: 12)
    let frame5 = CGRect(x: 293, y: point5Calculation, width: 12, height: 12)
    let frame6 = CGRect(x: 341, y: point6Calculation, width: 12, height: 12)


    //// topLine Drawing
    let topLinePath = UIBezierPath(rect: CGRect(x: 30, y: yTop, width: 345, height: 2))
    horizontal.setFill()
    topLinePath.fill()


    //// upperLine Drawing
    let upperLinePath = UIBezierPath(rect: CGRect(x: 30, y: 60.5, width: 345, height: 2))
    horizontal.setFill()
    upperLinePath.fill()


    //// middleLine Drawing
    let middleLinePath = UIBezierPath(rect: CGRect(x: 30, y: 111, width: 345, height: 2))
    horizontal.setFill()
    middleLinePath.fill()


    //// lowerLine Drawing
    let lowerLinePath = UIBezierPath(rect: CGRect(x: 30, y: 161.5, width: 345, height: 2))
    horizontal.setFill()
    lowerLinePath.fill()


    //// bottomLine Drawing
    let bottomLinePath = UIBezierPath(rect: CGRect(x: 30, y: yBottom, width: 345, height: 2))
    horizontal.setFill()
    bottomLinePath.fill()


    //// Bezier Drawing
    let bezierPath = UIBezierPath()
    bezierPath.move(to: CGPoint(x: frame0.minX + 6.5, y: frame0.minY + 6.05))
    bezierPath.addLine(to: CGPoint(x: frame1.minX + 5.5, y: frame1.minY + 5.99))
    bezierPath.addLine(to: CGPoint(x: frame2.minX + 5.5, y: frame2.minY + 6.63))
    bezierPath.addLine(to: CGPoint(x: frame3.minX + 5.5, y: frame3.minY + 6.99))
    bezierPath.addLine(to: CGPoint(x: frame4.minX + 5.5, y: frame4.minY + 5.4))
    bezierPath.addLine(to: CGPoint(x: frame5.minX + 5.5, y: frame5.minY + 6.68))
    bezierPath.addLine(to: CGPoint(x: frame6.minX + 4.5, y: frame6.minY + 7.13))
    context.saveGState()
    context.setShadow(offset: CGSize(width: shadow.shadowOffset.width * resizedShadowScale, height: shadow.shadowOffset.height * resizedShadowScale), blur: shadow.shadowBlurRadius * resizedShadowScale, color: (shadow.shadowColor as! UIColor).cgColor)
    line.setStroke()
    bezierPath.lineWidth = lineWidth
    bezierPath.lineJoinStyle = .round
    bezierPath.stroke()
    context.restoreGState()


    //// point0 Drawing
    let point0Path = UIBezierPath(ovalIn: CGRect(x: frame0.minX, y: frame0.minY + 0.55, width: 11, height: 11))
    context.saveGState()
    context.setShadow(offset: CGSize(width: shadow.shadowOffset.width * resizedShadowScale, height: shadow.shadowOffset.height * resizedShadowScale), blur: shadow.shadowBlurRadius * resizedShadowScale, color: (shadow.shadowColor as! UIColor).cgColor)
    line.setFill()
    point0Path.fill()
    context.restoreGState()

    line.setStroke()
    point0Path.lineWidth = 2
    point0Path.stroke()


    //// point1 Drawing
    let point1Path = UIBezierPath(ovalIn: CGRect(x: frame1.minX, y: frame1.minY + 0.49, width: 11, height: 11))
    context.saveGState()
    context.setShadow(offset: CGSize(width: shadow.shadowOffset.width * resizedShadowScale, height: shadow.shadowOffset.height * resizedShadowScale), blur: shadow.shadowBlurRadius * resizedShadowScale, color: (shadow.shadowColor as! UIColor).cgColor)
    line.setFill()
    point1Path.fill()
    context.restoreGState()

    line.setStroke()
    point1Path.lineWidth = 2
    point1Path.stroke()


    //// point2 Drawing
    let point2Path = UIBezierPath(ovalIn: CGRect(x: frame2.minX + 0.5, y: frame2.minY + 0.63, width: 11, height: 11))
    context.saveGState()
    context.setShadow(offset: CGSize(width: shadow.shadowOffset.width * resizedShadowScale, height: shadow.shadowOffset.height * resizedShadowScale), blur: shadow.shadowBlurRadius * resizedShadowScale, color: (shadow.shadowColor as! UIColor).cgColor)
    line.setFill()
    point2Path.fill()
    context.restoreGState()

    line.setStroke()
    point2Path.lineWidth = 1
    point2Path.stroke()


    //// point3 Drawing
    let point3Path = UIBezierPath(ovalIn: CGRect(x: frame3.minX, y: frame3.minY, width: 11, height: 11))
    context.saveGState()
    context.setShadow(offset: CGSize(width: shadow.shadowOffset.width * resizedShadowScale, height: shadow.shadowOffset.height * resizedShadowScale), blur: shadow.shadowBlurRadius * resizedShadowScale, color: (shadow.shadowColor as! UIColor).cgColor)
    line.setFill()
    point3Path.fill()
    context.restoreGState()

    line.setStroke()
    point3Path.lineWidth = 1
    point3Path.stroke()


    //// point4 Drawing
    let point4Path = UIBezierPath(ovalIn: CGRect(x: frame4.minX, y: frame4.minY + 0.58, width: 11, height: 11))
    context.saveGState()
    context.setShadow(offset: CGSize(width: shadow.shadowOffset.width * resizedShadowScale, height: shadow.shadowOffset.height * resizedShadowScale), blur: shadow.shadowBlurRadius * resizedShadowScale, color: (shadow.shadowColor as! UIColor).cgColor)
    line.setFill()
    point4Path.fill()
    context.restoreGState()

    line.setStroke()
    point4Path.lineWidth = 1
    point4Path.stroke()


    //// point5 Drawing
    let point5Path = UIBezierPath(ovalIn: CGRect(x: frame5.minX, y: frame5.minY, width: 11, height: 11))
    context.saveGState()
    context.setShadow(offset: CGSize(width: shadow.shadowOffset.width * resizedShadowScale, height: shadow.shadowOffset.height * resizedShadowScale), blur: shadow.shadowBlurRadius * resizedShadowScale, color: (shadow.shadowColor as! UIColor).cgColor)
    line.setFill()
    point5Path.fill()
    context.restoreGState()

    line.setStroke()
    point5Path.lineWidth = 1
    point5Path.stroke()


    //// point6 Drawing
    let point6Path = UIBezierPath(ovalIn: CGRect(x: frame6.minX, y: frame6.minY + 0.24, width: 11, height: 11))
    context.saveGState()
    context.setShadow(offset: CGSize(width: shadow.shadowOffset.width * resizedShadowScale, height: shadow.shadowOffset.height * resizedShadowScale), blur: shadow.shadowBlurRadius * resizedShadowScale, color: (shadow.shadowColor as! UIColor).cgColor)
    line.setFill()
    point6Path.fill()
    context.restoreGState()

    line.setStroke()
    point6Path.lineWidth = 1
    point6Path.stroke()


    //// Text Drawing
    let textRect = CGRect(x: 2, y: 0, width: 23, height: 21)
    let textStyle = NSMutableParagraphStyle()
    textStyle.alignment = .right
    let textFontAttributes = [
        .font: UIFont(name: "HelveticaNeue", size: 11)!,
        .foregroundColor: UIColor.black,
        .paragraphStyle: textStyle,
    ] as [NSAttributedStringKey: Any]

    let textTextHeight: CGFloat = topValue.boundingRect(with: CGSize(width: textRect.width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: textFontAttributes, context: nil).height
    context.saveGState()
    context.clip(to: textRect)
    topValue.draw(in: CGRect(x: textRect.minX, y: textRect.minY + (textRect.height - textTextHeight) / 2, width: textRect.width, height: textTextHeight), withAttributes: textFontAttributes)
    context.restoreGState()


    //// Text 2 Drawing
    let text2Rect = CGRect(x: 2, y: 51, width: 23, height: 21)
    let text2Style = NSMutableParagraphStyle()
    text2Style.alignment = .right
    let text2FontAttributes = [
        .font: UIFont(name: "HelveticaNeue", size: 11)!,
        .foregroundColor: UIColor.black,
        .paragraphStyle: text2Style,
    ] as [NSAttributedStringKey: Any]

    let text2TextHeight: CGFloat = upperMiddleValue.boundingRect(with: CGSize(width: text2Rect.width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: text2FontAttributes, context: nil).height
    context.saveGState()
    context.clip(to: text2Rect)
    upperMiddleValue.draw(in: CGRect(x: text2Rect.minX, y: text2Rect.minY + (text2Rect.height - text2TextHeight) / 2, width: text2Rect.width, height: text2TextHeight), withAttributes: text2FontAttributes)
    context.restoreGState()


    //// Text 3 Drawing
    let text3Rect = CGRect(x: 2, y: 101, width: 23, height: 21)
    let text3Style = NSMutableParagraphStyle()
    text3Style.alignment = .right
    let text3FontAttributes = [
        .font: UIFont(name: "HelveticaNeue", size: 11)!,
        .foregroundColor: UIColor.black,
        .paragraphStyle: text3Style,
    ] as [NSAttributedStringKey: Any]

    let text3TextHeight: CGFloat = middleValue.boundingRect(with: CGSize(width: text3Rect.width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: text3FontAttributes, context: nil).height
    context.saveGState()
    context.clip(to: text3Rect)
    middleValue.draw(in: CGRect(x: text3Rect.minX, y: text3Rect.minY + (text3Rect.height - text3TextHeight) / 2, width: text3Rect.width, height: text3TextHeight), withAttributes: text3FontAttributes)
    context.restoreGState()


    //// Text 4 Drawing
    let text4Rect = CGRect(x: 2, y: 152, width: 23, height: 21)
    let text4Style = NSMutableParagraphStyle()
    text4Style.alignment = .right
    let text4FontAttributes = [
        .font: UIFont(name: "HelveticaNeue", size: 11)!,
        .foregroundColor: UIColor.black,
        .paragraphStyle: text4Style,
    ] as [NSAttributedStringKey: Any]

    let text4TextHeight: CGFloat = lowerMiddleValue.boundingRect(with: CGSize(width: text4Rect.width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: text4FontAttributes, context: nil).height
    context.saveGState()
    context.clip(to: text4Rect)
    lowerMiddleValue.draw(in: CGRect(x: text4Rect.minX, y: text4Rect.minY + (text4Rect.height - text4TextHeight) / 2, width: text4Rect.width, height: text4TextHeight), withAttributes: text4FontAttributes)
    context.restoreGState()


    //// Text 5 Drawing
    let text5Rect = CGRect(x: 2, y: 202, width: 23, height: 21)
    let text5TextContent = "0"
    let text5Style = NSMutableParagraphStyle()
    text5Style.alignment = .right
    let text5FontAttributes = [
        .font: UIFont(name: "HelveticaNeue", size: 11)!,
        .foregroundColor: UIColor.black,
        .paragraphStyle: text5Style,
    ] as [NSAttributedStringKey: Any]

    let text5TextHeight: CGFloat = text5TextContent.boundingRect(with: CGSize(width: text5Rect.width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: text5FontAttributes, context: nil).height
    context.saveGState()
    context.clip(to: text5Rect)
    text5TextContent.draw(in: CGRect(x: text5Rect.minX, y: text5Rect.minY + (text5Rect.height - text5TextHeight) / 2, width: text5Rect.width, height: text5TextHeight), withAttributes: text5FontAttributes)
    context.restoreGState()

    context.restoreGState()

}




@objc(LineGraphsResizingBehavior)
public enum ResizingBehavior: Int {
    case aspectFit /// The content is proportionally resized to fit into the target rectangle.
    case aspectFill /// The content is proportionally resized to completely fill the target rectangle.
    case stretch /// The content is stretched to match the entire target rectangle.
    case center /// The content is centered in the target rectangle, but it is NOT resized.

    public func apply(rect: CGRect, target: CGRect) -> CGRect {
        if rect == target || target == CGRect.zero {
            return rect
        }

        var scales = CGSize.zero
        scales.width = abs(target.width / rect.width)
        scales.height = abs(target.height / rect.height)

        switch self {
            case .aspectFit:
                scales.width = min(scales.width, scales.height)
                scales.height = scales.width
            case .aspectFill:
                scales.width = max(scales.width, scales.height)
                scales.height = scales.width
            case .stretch:
                break
            case .center:
                scales.width = 1
                scales.height = 1
        }

        var result = rect.standardized
        result.size.width *= scales.width
        result.size.height *= scales.height
        result.origin.x = target.minX + (target.width - result.width) / 2
        result.origin.y = target.minY + (target.height - result.height) / 2
        return result
    }
  }
}

这是我的 Class 文件:

import UIKit

class LineView: UIView {


// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.

override func draw(_ rect: CGRect, for formatter: UIViewPrintFormatter) {
    LineGraphs.draw_7PointLine()
  }
}

另外,我创建了 UIView 并在 StoryBoard 中添加了 LineView class。难道我做错了什么?我还需要添加其他内容吗?

使用

draw(_ rect: CGRect)

而不是

draw(_ rect: CGRect, for formatter: UIViewPrintFormatter)

不管你是在StoryBoard还是Xib还是代码中使用。