如何绘制其背层是CAGradientLayer的视图?

时间:2019-01-10 17:57:38

标签: ios12 swift4.2

请查看以下简单应用程序。它为ViewController提供了一个View,其View的底层是CAGradientLayer。如图所示(即MyView.draw = false),应用程序按预期工作:该视图显示白色->黑色渐变。但是,如果doDraw设置为true,则视图在黑色背景上显示红色的日食;没有渐变。

有人可以帮我了解发生了什么吗?我认为可以通过在渐变视图中添加子视图,绘制子视图并允许渐变视图在清晰的背景下显示(关于子层的类似想法)来获得所需的内容。尽管如此,我想了解为什么我目前在做什么不起作用。

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        window = UIWindow(frame: UIScreen.main.bounds)
        window?.makeKeyAndVisible()
        window!.rootViewController = MyViewController()

        return true
    }
}

class MyViewController : UIViewController {
    override func loadView() {
        view = MyView()
    }
}

class MyView : UIView {

    private static let draw = false

    override class var layerClass: AnyClass { return CAGradientLayer.self }

    init() {
        super.init(frame: CGRect.zero)
        (layer as! CAGradientLayer).colors = [UIColor.white.cgColor, UIColor.black.cgColor]
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func draw(_ rect: CGRect) {
        super.draw(rect)

        if MyView.draw {
            guard let context = UIGraphicsGetCurrentContext() else { return }

            context.addEllipse(in: rect.insetBy(dx: 50, dy: 50))

            context.setStrokeColor(UIColor.red.cgColor)
            context.setLineWidth(2)
            context.strokePath()
        }
    }
}

更新1:

我有一个令我满意的解决方案(请参阅下文)。尽管如此,我仍然想知道我最初的尝试是怎么回事。

// Rather than using a CAGradientLayer, directly draw the gradient.
override func draw(_ rect: CGRect) {
    super.draw(rect)

    guard let context = UIGraphicsGetCurrentContext() else { return }

    let colors = [UIColor.white.cgColor, UIColor.black.cgColor] as CFArray
    let gradient = CGGradient(colorsSpace: nil, colors: colors, locations: nil)!
    context.drawLinearGradient(gradient, start: CGPoint(x: bounds.midX, y: 0), end: CGPoint(x: bounds.midX, y: bounds.maxY), options: [])

    context.addEllipse(in: rect.insetBy(dx: 50, dy: 50))
    context.setStrokeColor(UIColor.red.cgColor)
    context.setLineWidth(2)
    context.strokePath()
}

0 个答案:

没有答案