我为自定义视图编写了一个模型。该视图的标题有阴影,在我的示例中有4个条带。
我的问题是,每当我创建一个视图模型时,我保存上下文时都不会出现阴影 - 我希望显示阴影只显示在标题下方,而不是视图中的每个形状。
型号:
import UIKit
protocol StripeDrawable {
func drawCaption<T: CGContext>(in rect: CGRect, using ctx: T)
func drawSripes<T: CGContext>(in rect: CGRect, using ctx: T)
}
struct Stripe {
var numberOfStripes: Int
var stripPattern: [UIColor]
}
struct Caption {
var captionFontSize: CGFloat
var captionHeight: CGFloat
var captionTitle: String
var captionBackgroundColor: UIColor
var captionTextColor: UIColor
var isCaptionShadowEnabled: Bool
}
class StripeAxis {
var stripe: Stripe
var caption: Caption
init(stripe: Stripe, caption: Caption) {
self.stripe = stripe
self.caption = caption
}
}
extension StripeAxis: StripeDrawable {
func drawCaption<T>(in rect: CGRect, using ctx: T) where T : CGContext {
let captionRect = CGRect(x: 0, y: 0, width: rect.width, height: caption.captionHeight)
ctx.addRect(captionRect)
ctx.saveGState()
if caption.isCaptionShadowEnabled {
ctx.setShadow(offset: CGSize(width: 0, height: 0), blur: 3, color: UIColor.black.cgColor)
}
ctx.setFillColor(caption.captionBackgroundColor.cgColor)
ctx.fill(captionRect)
let font = UIFont.boldSystemFont(ofSize: caption.captionFontSize)
let attribs = [NSAttributedStringKey.foregroundColor : caption.captionTextColor,
NSAttributedStringKey.font : font] as [NSAttributedStringKey : Any]
caption.captionTitle.center(in: captionRect, attribs: attribs as! [NSAttributedStringKey : NSObject])
ctx.restoreGState()
}
func drawSripes<T>(in rect: CGRect, using ctx: T) where T : CGContext {
let stripHeight: CGFloat = (rect.height - caption.captionHeight) / CGFloat(stripe.numberOfStripes)
for i in 0...stripe.numberOfStripes - 1 {
var color: UIColor!
let stripRect = CGRect(x: 0, y: stripHeight * CGFloat(i) + caption.captionHeight, width: rect.width, height: stripHeight)
if i % 2 == 0 {
color = stripe.stripPattern[0]
} else {
color = stripe.stripPattern[1]
}
ctx.setFillColor(color.cgColor)
ctx.fill(stripRect)
}
}
}
自定义视图:
导入UIKit
final class TimersStripesView: UIView {
var selectedIndex: Int = 0
var statusRects: [CGRect] = []
var onSelection: (() -> ())!
private let pad = UIDevice.current.userInterfaceIdiom == .pad
var stripeAxis: StripeAxis!
override init(frame: CGRect) {
super.init(frame: frame)
stripeAxis = StripeAxis(stripe: Stripe(numberOfStripes: 4, stripPattern: [.red, .blue]),
caption: Caption(captionFontSize: pad ? 15 : 11, captionHeight: pad ? 40 : 25, captionTitle: "TOTAL", captionBackgroundColor: .orange, captionTextColor: .white, isCaptionShadowEnabled: true))
contentMode = .redraw
// addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onTouch(_:))))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let ctx = UIGraphicsGetCurrentContext() else { return }
stripeAxis.drawCaption(in: rect, using: ctx)
stripeAxis.drawSripes(in: rect, using: ctx)
}
}
正如我们所看到的,影子标题上的阴影已经下降,但它不会直接下降。
在我没有模特的变化之前,只是当我做同样的事情时:
平局:
override func draw(_ rect: CGRect) {
super.draw(rect)
guard let ctx = UIGraphicsGetCurrentContext() else { return }
let captionRect = CGRect(x: 0, y: 0, width: rect.width, height: pad ? 40.0 : 25.0)
drawCaption(in: captionRect, using: ctx)
drawStrips(using: ctx, in: rect, captionHeight: pad ? 40.0 : 25.0)
}
方法:
func drawCaption<T: CGContext>(in rect: CGRect, using ctx: T) {
ctx.addRect(rect)
ctx.saveGState()
ctx.setShadow(offset: CGSize(width: 0, height: 0), blur: 3, color: UIColor.black.cgColor)
ctx.setFillColor(UIColor.orange.cgColor)
ctx.fill(rect)
let statusText = "TOTAL"
let font = UIFont.boldSystemFont(ofSize: pad ? 15 : 11)
let attribs = [NSAttributedStringKey.foregroundColor : UIColor.white, NSAttributedStringKey.font: font]
statusText.center(in: rect, attribs: attribs)
ctx.restoreGState()
}
func drawStrips<T: CGContext>(using ctx: T, in rect: CGRect, captionHeight: CGFloat) {
let statusHeight: CGFloat = (rect.height - captionHeight) / 4
for i in 0...3 {
var color: UIColor!
let newRect = CGRect(x: 0, y: statusHeight * CGFloat(i) + captionHeight, width: rect.width, height: statusHeight)
if i % 2 == 0 {
color = .red
} else {
color = .blue
}
ctx.setFillColor(color.cgColor)
ctx.fill(newRect)
}
}
正在处理结果:
我看不出我做错了哪里,有什么想法?
答案 0 :(得分:1)
你以前的代码没有工作(我在操场上跑了) - 影子也丢失了。
保存和恢复图形状态没有问题。发生的事情很简单,当您绘制条纹时,它们会被绘制在橙色框的阴影顶部,因此您无法再看到它。只需更改绘图调用的顺序,以便在标题之前绘制条纹,一切正常。