似乎保存图形上下文不起作用

时间:2018-01-12 11:05:43

标签: swift core-graphics

我为自定义视图编写了一个模型。该视图的标题有阴影,在我的示例中有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)
    }
}

正在处理结果:

enter image description here

我看不出我做错了哪里,有什么想法?

1 个答案:

答案 0 :(得分:1)

你以前的代码没有工作(我在操场上跑了) - 影子也丢失了。

保存和恢复图形状态没有问题。发生的事情很简单,当您绘制条纹时,它们会被绘制在橙色框的阴影顶部,因此您无法再看到它。只需更改绘图调用的顺序,以便在标题之前绘制条纹,一切正常。