我已经创建了一个Line Graph的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
}
}
}
这是我的班级文件:
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类。难道我做错了什么?我还需要添加其他内容吗?