2017-03-24 7 views
0

私のシーンには2つのビューがあります:最初にCALayerインスタンス(小節)を保持し、もう1つはCAGradientLayerを保持し、最初のものを配置します。下の図は、現在の状態を示しています。CAGradientLayer over CALayers

Image

しかし、私は、この勾配は最初のビューのバー(CALayerの)に適用する必要があります。

enter image description here

私は私の問題に関連するすべての情報を見つけていません。どんな助けもありがたい。

答えて

4

グラデーションにマスクを適用する必要があります。この問題に近づくにはさまざまな方法があります。

あなたは、CAShapeLayerを作成シェイプレイヤーのpathバーの形状に設定し、勾配層のmaskそのシェイプレイヤーに設定することができます。

または、バーレイヤーを削除し、代わりに2つのグラデーションレイヤーを使用できます.1つはオレンジバー用、もう1つはグレーバー用です。両方のグラデーションレイヤをサブビューに並べて並べて、スーパービューのレイヤーマスクをシェイプレイヤーに設定します。これを行う方法は次のとおりです。

次の2つのグラデーションレイヤーとシェイプレイヤー必要があります:グラデーションを設定し、すべてを追加し、初期化時に

private let barWidth = CGFloat(9) 

:あなたがバーの幅をも必要となります

@IBDesignable 
class BarGraphView : UIView { 

    private let orangeGradientLayer = CAGradientLayer() 
    private let grayGradientLayer = CAGradientLayer() 
    private let maskLayer = CAShapeLayer() 

をサブレイヤ:

override init(frame: CGRect) { 
     super.init(frame: frame) 
     commonInit() 
    } 

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

    private func commonInit() { 
     backgroundColor = .black 

     initGradientLayer(orangeGradientLayer, with: .orange) 
     initGradientLayer(grayGradientLayer, with: .gray) 

     maskLayer.strokeColor = nil 
     maskLayer.fillColor = UIColor.white.cgColor 
     layer.mask = maskLayer 
    } 

    private func initGradientLayer(_ gradientLayer: CAGradientLayer, with color: UIColor) { 
     gradientLayer.colors = [ color, color, color.withAlphaComponent(0.6), color ].map({ $0.cgColor }) 
     gradientLayer.locations = [ 0.0, 0.5, 0.5, 1.0 ] 
     layer.addSublayer(gradientLayer) 
    } 

レイアウト時に、グラデーションレイヤーのフレームを設定し、マスクレイを設定しますエルのパス。これは、あなたがバーを半分オレンジと半グレーにしたくないので、少しの作業が必要です。

override func layoutSubviews() { 
     super.layoutSubviews() 

     let barCount = ceil(bounds.size.width/barWidth) 
     let orangeBarCount = floor(barCount/2) 
     let grayBarCount = barCount - orangeBarCount 

     var grayFrame = bounds 
     grayFrame.size.width = grayBarCount * barWidth 
     grayFrame.origin.x = frame.maxX - grayFrame.size.width 
     grayGradientLayer.frame = grayFrame 

     var orangeFrame = bounds 
     orangeFrame.size.width -= grayFrame.size.width 
     orangeGradientLayer.frame = orangeFrame 

     maskLayer.frame = bounds 
     maskLayer.path = barPath() 
    } 

    private func barPath() -> CGPath { 
     var columnBounds = self.bounds 
     columnBounds.origin.x = columnBounds.maxX 
     columnBounds.size.width = barWidth 
     let path = CGMutablePath() 
     for datum in barData.reversed() { 
      columnBounds.origin.x -= barWidth 
      let barHeight = CGFloat(datum) * columnBounds.size.height 
      let barRect = columnBounds.insetBy(dx: 1, dy: (columnBounds.size.height - barHeight)/2) 
      path.addRoundedRect(in: barRect, cornerWidth: 2, cornerHeight: 2) 
     } 
     return path 
    } 

    let barData: [Double] = { 
     let count = 100 
     return (0 ..< count).map({ 0.5 + (1 + sin(8.0 * .pi * Double($0)/Double(count)))/4 }) 
    }() 

} 

結果:なしバーが存在しないどこ

gradient bars

BarGraphViewが透明です。あなたは暗い背景の上にそれをしたい場合は、その背後にある暗いビューを置くか、または暗いビューのサブビューます

gradient bars on dark blue

+0

はこの素晴らしいたとえばどうもありがとうございました – WINSergey

関連する問題