130 lines
4.8 KiB
Swift
130 lines
4.8 KiB
Swift
import UIKit
|
||
|
||
class PlateView: UIView {
|
||
// Some driver plate parameters from "ГОСТ Р 50577-93"
|
||
// http://docs.cntd.ru/document/gost-r-50577-93
|
||
private static let aspectRatio: CGFloat = 112.0/520.0
|
||
private static let fontHeightCoeff: CGFloat = 58.0/76.0
|
||
|
||
private var bgLayer = CALayer()
|
||
private var mainBgLayer = CALayer()
|
||
private var regionBgLayer = CALayer()
|
||
private var numberLayer = CenterTextLayer(coeff: fontHeightCoeff)
|
||
private var regionLayer = CenterTextLayer(coeff: fontHeightCoeff)
|
||
private var countryLayer = CenterTextLayer()
|
||
private var flagLayer = FlagLayer()
|
||
|
||
var number: PlateNumber? {
|
||
didSet {
|
||
self.layoutSubviews()
|
||
}
|
||
}
|
||
|
||
var foreground: UIColor? {
|
||
didSet {
|
||
self.layoutSubviews()
|
||
}
|
||
}
|
||
|
||
required init?(coder: NSCoder) {
|
||
super.init(coder: coder)
|
||
|
||
self.layer.backgroundColor = UIColor.clear.cgColor
|
||
|
||
self.bgLayer.cornerRadius = 6 //self.bounds.height/8
|
||
self.layer.addSublayer(self.bgLayer)
|
||
|
||
self.mainBgLayer.cornerRadius = 4
|
||
self.layer.addSublayer(self.mainBgLayer)
|
||
|
||
self.regionBgLayer.cornerRadius = 4
|
||
self.layer.addSublayer(self.regionBgLayer)
|
||
|
||
self.numberLayer.alignmentMode = .center
|
||
self.numberLayer.contentsScale = UIScreen.main.scale
|
||
self.layer.addSublayer(self.numberLayer)
|
||
|
||
self.regionLayer.alignmentMode = .center
|
||
self.regionLayer.contentsScale = UIScreen.main.scale
|
||
self.layer.addSublayer(self.regionLayer)
|
||
|
||
self.countryLayer.contentsScale = UIScreen.main.scale
|
||
self.countryLayer.string = "RUS"
|
||
self.countryLayer.alignmentMode = .center
|
||
self.layer.addSublayer(self.countryLayer)
|
||
|
||
self.flagLayer.contentsScale = UIScreen.main.scale
|
||
self.layer.addSublayer(self.flagLayer)
|
||
}
|
||
|
||
private func pathForFlag(in rect: CGRect) -> CGPath {
|
||
let path = CGMutablePath()
|
||
let rect = CGPath(rect: rect, transform: nil)
|
||
path.addPath(rect)
|
||
return path
|
||
}
|
||
|
||
override func layoutSubviews() {
|
||
super.layoutSubviews()
|
||
guard let number = self.number else { return }
|
||
guard let fgColorMain = UIColor(named: "PlateForeground")?.cgColor else { return }
|
||
guard let bgColor = UIColor(named: "PlateBackground")?.cgColor else { return }
|
||
|
||
let fgColor = self.foreground?.cgColor ?? fgColorMain
|
||
|
||
self.bgLayer.backgroundColor = fgColor
|
||
self.bgLayer.frame = self.bounds
|
||
|
||
self.mainBgLayer.backgroundColor = bgColor
|
||
self.regionBgLayer.backgroundColor = bgColor
|
||
self.mainBgLayer.frame = self.bounds.inset(by: UIEdgeInsets(top: 2, left: 2, bottom: 2, right: self.bounds.width*0.27 + 1))
|
||
self.regionBgLayer.frame = self.bounds.inset(by: UIEdgeInsets(top: 2, left: self.bounds.width*0.73 + 1, bottom: 2, right: 2))
|
||
|
||
self.numberLayer.frame = self.mainBgLayer.frame.insetBy(dx: 4, dy: 0)
|
||
let font = UIFont(name: "RoadNumbers", size: self.mainBgLayer.frame.height*1.1) ?? UIFont.boldSystemFont(ofSize: 24)
|
||
let attributes: [NSAttributedString.Key: Any] = [
|
||
.kern: 3,
|
||
.font: font,
|
||
.foregroundColor: fgColor
|
||
]
|
||
let attributed = NSAttributedString(string: number.mainPart(), attributes: attributes)
|
||
self.numberLayer.string = attributed
|
||
|
||
let rbgSize = self.regionBgLayer.frame.size
|
||
|
||
self.regionLayer.frame = self.regionBgLayer.frame.inset(by: UIEdgeInsets(top: 2, left: 2, bottom: rbgSize.height*0.35, right: 2))
|
||
let regionFont = UIFont(name: "RoadNumbers", size: rbgSize.height*0.8) ?? UIFont.boldSystemFont(ofSize: 24)
|
||
let regionAttrs: [NSAttributedString.Key: Any] = [
|
||
.kern: 1,
|
||
.font: regionFont,
|
||
.foregroundColor: fgColor
|
||
]
|
||
let attributedRegion = NSAttributedString(string: number.region(), attributes: regionAttrs)
|
||
self.regionLayer.string = attributedRegion
|
||
|
||
self.countryLayer.foregroundColor = fgColor
|
||
self.countryLayer.frame = self.regionBgLayer.frame.inset(by: UIEdgeInsets(top: rbgSize.height*0.64, left: rbgSize.width*0.08, bottom: rbgSize.height*0.07, right: rbgSize.width*0.42))
|
||
self.countryLayer.fontSize = self.countryLayer.frame.size.height
|
||
|
||
let top = (self.regionBgLayer.frame.origin.y + rbgSize.height*0.68).rounded(.toNearestOrAwayFromZero)
|
||
let left = (self.regionBgLayer.frame.origin.x + rbgSize.width*0.62).rounded(.toNearestOrAwayFromZero)
|
||
let w = (rbgSize.width*0.34).rounded(.toNearestOrAwayFromZero)
|
||
let h = (rbgSize.height*0.28).rounded(.toNearestOrAwayFromZero)
|
||
self.flagLayer.frame = CGRect(x: left, y: top, width: w, height: h)
|
||
self.flagLayer.setNeedsDisplay()
|
||
}
|
||
|
||
override var intrinsicContentSize: CGSize {
|
||
guard self.bounds.width != 0 || self.bounds.height != 0 else {
|
||
return CGSize.zero
|
||
}
|
||
|
||
let curAspectRatio = self.bounds.height/self.bounds.width
|
||
if curAspectRatio >= PlateView.aspectRatio {
|
||
return CGSize(width: self.bounds.width, height: self.bounds.width*PlateView.aspectRatio)
|
||
} else {
|
||
return CGSize(width: self.bounds.height/PlateView.aspectRatio, height: self.bounds.height)
|
||
}
|
||
}
|
||
}
|