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

标签 swift core-graphics

我已经为我的自定义 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)
    }
}

正在处理结果:

enter image description here

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

最佳答案

您之前的代码无法正常工作(我在 Playground 上运行了它)- 阴影也不见了。

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

关于swift - 似乎保存图形上下文不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48224962/

相关文章:

ios - NSFetchedResultsController 在更新关系后从 UITableView 中删除行

ios - 当设备笔直且不倾斜时,如何让我的加速度计不移动我的节点?

iphone - 设置需要显示矩形 : paints a white rectangle only

ios - UIBezierPath下绘制渐变

ios - swift 中的协议(protocol)与多态性

swift - 错误 : "cannot invoke initializer" for function to be executed on Watch OS only

ios - 如何使用 Swift 滚动 TextView 时重复动画?

objective-c - 没有隐藏项目的 Core Graphics 屏幕截图

ios - 如何平滑绘制图像的边缘?

iphone - 从核心图形中的路径中删除形状