【问题标题】:Seems like saving graphics context doesn't work似乎保存图形上下文不起作用
【发布时间】:2018-01-16 03:54:59
【问题描述】:

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

正在处理结果:

我看不到我在哪里做错了,有什么想法吗?

【问题讨论】:

  • 我不确定你在这里问什么 - 你所包含的图像在文本上有阴影,但在其他地方没有,这不是你想要发生的吗?您能否包含“正确”和“错误”外观的图像?
  • @jrturton 第一张图片显示,当我在保存上下文后将逻辑迁移到单独的类时,它不会在标题“TOTAL”下方显示阴影,下方为橙色视图。在底部,我添加了无需将逻辑迁移到分离类即可工作的代码。第二张图片显示第二个选项是正确的,阴影只落在文本和橙色视图上。

标签: swift core-graphics


【解决方案1】:

您之前的代码不起作用(我在操场上运行它)- 阴影也不见了。

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

【讨论】:

  • 谢谢,我没看到这个错误。
猜你喜欢
  • 1970-01-01
  • 2018-04-17
  • 1970-01-01
  • 2013-01-31
  • 2011-05-22
  • 1970-01-01
  • 2016-04-25
  • 2011-10-08
  • 2011-10-19
相关资源
最近更新 更多