我已经为我的自定义 View 编写了一个模型。该 View 有带阴影的标题,在我的示例中有 4 个 strip 。
我的问题是每当我为 View 创建模型时,当我保存上下文时阴影不会出现 - 我只想在标题下方显示阴影,而不是在 View 内的每个形状中。
型号:
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)
}
}
}
自定义 View :
导入 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)
}
}
正在处理结果:
我看不出哪里做错了,有什么想法吗?
最佳答案
您之前的代码无法正常工作(我在 Playground 上运行了它)- 阴影也不见了。
保存和恢复图形状态没有问题。发生的事情很简单,当你绘制条纹时,它们被绘制在橙色框的阴影之上,所以你再也看不到它了。只需更改绘图调用的顺序,以便在标题之前绘制条纹,一切正常。
关于swift - 似乎保存图形上下文不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48224962/