Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 当UIBezierPath超过阈值时,如何更改其笔划和路径颜色_Ios_Swift_Uibezierpath - Fatal编程技术网

Ios 当UIBezierPath超过阈值时,如何更改其笔划和路径颜色

Ios 当UIBezierPath超过阈值时,如何更改其笔划和路径颜色,ios,swift,uibezierpath,Ios,Swift,Uibezierpath,刚接触核心图形,有一个问题我不知道如何解决 我需要绘制一个图形,在路径穿过阈值线时更改笔划和填充颜色,如本例所示: 我可以毫无问题地把这张图画成全绿色。我不知道该怎么做的是高于或低于阈值线的部分。路径可能在点之间穿过阈值 我曾想过画两次图形,先是橙色,然后是绿色,然后在绿色路径上添加一个遮罩,阈值线形成一个矩形,使橙色版本的图形可以显示出来 我相信有更好的方法。任何指点都将不胜感激。我用的是Swift 4。你的思路是对的。对于每个色带: 保存图形状态 将上下文剪裁到当前色带覆盖的区域 用适当的

刚接触核心图形,有一个问题我不知道如何解决

我需要绘制一个图形,在路径穿过阈值线时更改笔划和填充颜色,如本例所示:

我可以毫无问题地把这张图画成全绿色。我不知道该怎么做的是高于或低于阈值线的部分。路径可能在点之间穿过阈值

我曾想过画两次图形,先是橙色,然后是绿色,然后在绿色路径上添加一个遮罩,阈值线形成一个矩形,使橙色版本的图形可以显示出来


我相信有更好的方法。任何指点都将不胜感激。我用的是Swift 4。

你的思路是对的。对于每个色带:

  • 保存图形状态
  • 将上下文剪裁到当前色带覆盖的区域
  • 用适当的颜色填充并划过整个路径
  • 恢复图形状态
  • 在代码中,它可能看起来像这样:

        for band in bands {
            let y0 = max(CGPoint(x: 0, y: band.min).applying(transform).y, 0)
            let y1 = min(CGPoint(x: 0, y: band.max).applying(transform).y, mySize.height)
            gc.saveGState(); do {
                gc.clip(to: CGRect(x: 0, y: y0, width: mySize.width, height: y1 - y0))
                band.fillColor.setFill()
                gc.addPath(pathForFilling)
                gc.fillPath()
                band.strokeColor.setStroke()
                gc.addPath(pathForStroking)
                gc.strokePath()
            }; gc.restoreGState()
        }
    
    结果:

    以下是我的完整操场代码:

    import UIKit
    
    class BandedGraphView: UIView {
    
        struct Band {
            var min: CGFloat // In data geometry
            var max: CGFloat // In data geometry
            var strokeColor: UIColor
            var fillColor: UIColor { return strokeColor.withAlphaComponent(0.2) }
        }
    
        var bands: [Band] = [] {
            didSet { setNeedsDisplay() }
        }
    
        /// The minimum visible data geometry coordinate
        var minVisiblePoint = CGPoint.zero {
            didSet { setNeedsDisplay() }
        }
    
        /// The maximum visible data geometry coordinate
        var maxVisiblePoint = CGPoint(x: 1, y: 1) {
            didSet { setNeedsDisplay() }
        }
    
        /// Data points, in data geometry.
        var data: [CGPoint] = [] {
            didSet { setNeedsDisplay() }
        }
    
        var lineWidth: CGFloat = 2 {
            didSet { setNeedsDisplay() }
        }
    
        override func draw(_ rect: CGRect) {
            guard
                minVisiblePoint.x != maxVisiblePoint.x,
                minVisiblePoint.y != maxVisiblePoint.y,
                !bands.isEmpty,
                !data.isEmpty,
                let gc = UIGraphicsGetCurrentContext()
                else { return }
    
            let mySize = bounds.size
    
            var transform = CGAffineTransform.identity
            transform = transform.scaledBy(x: mySize.width / (maxVisiblePoint.x - minVisiblePoint.x), y: mySize.height / (maxVisiblePoint.y - minVisiblePoint.y))
            transform = transform.translatedBy(x: -minVisiblePoint.x, y: -minVisiblePoint.y)
    
            let pathForStroking = CGMutablePath()
            pathForStroking.addLines(between: data, transform: transform)
    
            let pathForFilling = pathForStroking.mutableCopy(using: nil)!
            let firstPoint = data.first!.applying(transform)
            let lastPoint = data.last!.applying(transform)
            print(pathForFilling)
            pathForFilling.addLine(to: CGPoint(x: lastPoint.x, y: -CGFloat.greatestFiniteMagnitude))
            pathForFilling.addLine(to: CGPoint(x: firstPoint.x, y: -CGFloat.greatestFiniteMagnitude))
            pathForFilling.closeSubpath()
            print(pathForFilling)
    
            // Transform the context so the origin is at the lower left.
            gc.translateBy(x: 0, y: mySize.height)
            gc.scaleBy(x: 1, y: -1)
    
            for band in bands {
                let y0 = max(CGPoint(x: 0, y: band.min).applying(transform).y, 0)
                let y1 = min(CGPoint(x: 0, y: band.max).applying(transform).y, mySize.height)
                gc.saveGState(); do {
                    gc.clip(to: CGRect(x: 0, y: y0, width: mySize.width, height: y1 - y0))
                    band.fillColor.setFill()
                    gc.addPath(pathForFilling)
                    gc.fillPath()
                    band.strokeColor.setStroke()
                    gc.addPath(pathForStroking)
                    gc.strokePath()
                }; gc.restoreGState()
            }
        }
    
    }
    
    import PlaygroundSupport
    
    let view = BandedGraphView(frame: CGRect(x: 0, y: 0, width: 400, height: 300))
    view.backgroundColor = .white
    view.bands = [
        .init(min: -CGFloat.infinity, max: -0.8, strokeColor: .blue),
        .init(min: -0.8, max: 0.2, strokeColor: .red),
        .init(min: 0.2, max: CGFloat.infinity, strokeColor: .orange),
    ]
    view.minVisiblePoint = CGPoint(x: 0, y: -2)
    view.maxVisiblePoint = CGPoint(x: 10, y: 2)
    view.lineWidth = 2
    view.data = stride(from: CGFloat(0), through: CGFloat(10), by: CGFloat(0.01)).map { CGPoint(x: $0, y: cos($0)) }
    
    PlaygroundPage.current.liveView = view
    

    你在正确的轨道上。对于每个色带:

  • 保存图形状态
  • 将上下文剪裁到当前色带覆盖的区域
  • 用适当的颜色填充并划过整个路径
  • 恢复图形状态
  • 在代码中,它可能看起来像这样:

        for band in bands {
            let y0 = max(CGPoint(x: 0, y: band.min).applying(transform).y, 0)
            let y1 = min(CGPoint(x: 0, y: band.max).applying(transform).y, mySize.height)
            gc.saveGState(); do {
                gc.clip(to: CGRect(x: 0, y: y0, width: mySize.width, height: y1 - y0))
                band.fillColor.setFill()
                gc.addPath(pathForFilling)
                gc.fillPath()
                band.strokeColor.setStroke()
                gc.addPath(pathForStroking)
                gc.strokePath()
            }; gc.restoreGState()
        }
    
    结果:

    以下是我的完整操场代码:

    import UIKit
    
    class BandedGraphView: UIView {
    
        struct Band {
            var min: CGFloat // In data geometry
            var max: CGFloat // In data geometry
            var strokeColor: UIColor
            var fillColor: UIColor { return strokeColor.withAlphaComponent(0.2) }
        }
    
        var bands: [Band] = [] {
            didSet { setNeedsDisplay() }
        }
    
        /// The minimum visible data geometry coordinate
        var minVisiblePoint = CGPoint.zero {
            didSet { setNeedsDisplay() }
        }
    
        /// The maximum visible data geometry coordinate
        var maxVisiblePoint = CGPoint(x: 1, y: 1) {
            didSet { setNeedsDisplay() }
        }
    
        /// Data points, in data geometry.
        var data: [CGPoint] = [] {
            didSet { setNeedsDisplay() }
        }
    
        var lineWidth: CGFloat = 2 {
            didSet { setNeedsDisplay() }
        }
    
        override func draw(_ rect: CGRect) {
            guard
                minVisiblePoint.x != maxVisiblePoint.x,
                minVisiblePoint.y != maxVisiblePoint.y,
                !bands.isEmpty,
                !data.isEmpty,
                let gc = UIGraphicsGetCurrentContext()
                else { return }
    
            let mySize = bounds.size
    
            var transform = CGAffineTransform.identity
            transform = transform.scaledBy(x: mySize.width / (maxVisiblePoint.x - minVisiblePoint.x), y: mySize.height / (maxVisiblePoint.y - minVisiblePoint.y))
            transform = transform.translatedBy(x: -minVisiblePoint.x, y: -minVisiblePoint.y)
    
            let pathForStroking = CGMutablePath()
            pathForStroking.addLines(between: data, transform: transform)
    
            let pathForFilling = pathForStroking.mutableCopy(using: nil)!
            let firstPoint = data.first!.applying(transform)
            let lastPoint = data.last!.applying(transform)
            print(pathForFilling)
            pathForFilling.addLine(to: CGPoint(x: lastPoint.x, y: -CGFloat.greatestFiniteMagnitude))
            pathForFilling.addLine(to: CGPoint(x: firstPoint.x, y: -CGFloat.greatestFiniteMagnitude))
            pathForFilling.closeSubpath()
            print(pathForFilling)
    
            // Transform the context so the origin is at the lower left.
            gc.translateBy(x: 0, y: mySize.height)
            gc.scaleBy(x: 1, y: -1)
    
            for band in bands {
                let y0 = max(CGPoint(x: 0, y: band.min).applying(transform).y, 0)
                let y1 = min(CGPoint(x: 0, y: band.max).applying(transform).y, mySize.height)
                gc.saveGState(); do {
                    gc.clip(to: CGRect(x: 0, y: y0, width: mySize.width, height: y1 - y0))
                    band.fillColor.setFill()
                    gc.addPath(pathForFilling)
                    gc.fillPath()
                    band.strokeColor.setStroke()
                    gc.addPath(pathForStroking)
                    gc.strokePath()
                }; gc.restoreGState()
            }
        }
    
    }
    
    import PlaygroundSupport
    
    let view = BandedGraphView(frame: CGRect(x: 0, y: 0, width: 400, height: 300))
    view.backgroundColor = .white
    view.bands = [
        .init(min: -CGFloat.infinity, max: -0.8, strokeColor: .blue),
        .init(min: -0.8, max: 0.2, strokeColor: .red),
        .init(min: 0.2, max: CGFloat.infinity, strokeColor: .orange),
    ]
    view.minVisiblePoint = CGPoint(x: 0, y: -2)
    view.maxVisiblePoint = CGPoint(x: 10, y: 2)
    view.lineWidth = 2
    view.data = stride(from: CGFloat(0), through: CGFloat(10), by: CGFloat(0.01)).map { CGPoint(x: $0, y: cos($0)) }
    
    PlaygroundPage.current.liveView = view
    

    您可以检查颜色混合模式:。带有屏幕混合的红色层将在绿色上产生类似的结果。您可以检查颜色混合模式:。带有混合屏幕的红色图层将在你的green.Rob上产生类似的效果。这是一个很大的帮助。谢谢我必须分别画出三个带,而不是画成一个圈,才能让它填充到正确的方向,否则我会竖起大拇指。这是一个很大的帮助。谢谢我必须分别画出三个带,而不是画成一个圈,才能让它填充到正确的方向,否则我会竖起大拇指。