2017-10-21 21 views
1

UILabelは、グラデーションイメージ(つまり、UIImageView)の上に描画されています。これは、みかんのようになります。Swiftのdraw(_ rect:CGRect)で異なるブレンドモードのUILabelを描画する方法

enter image description here

私はそれがラベルを描くようにUILabelさんdraw(_ rect: CGRect)機能にグラフィックスコンテキストのblendModeを変更しようとしているが、softLightブレンドモードと背景とブレンドしています。ここで

は、私はそれが見えるようにしたいものです。

override func draw(_ rect: CGRect) { 
    // Drawing code 
    if let context = UIGraphicsGetCurrentContext() { 
     context.setBlendMode(.softLight) 
     self.textColor.set() 
     self.drawText(in: rect) 
    } 
} 

このコードだけでトップ画像をレンダリングしていない:

enter image description here

ここで私はdraw(_ rect: CGRect)機能を持っているコードがありますブレンドされたバージョン。これは私が試みたすべてではない、私は他の多くのことを試みたが、私はちょうどCGContextdrawの機能を理解していない。

SOのほとんどの回答は、古い目的のいずれかであり、非推奨/壊れているか、迅速かつ複雑すぎます(たとえば、金属を使用)。私はちょうど私が持っているコンテキストでテキストを描画し、コンテキストのブレンドモードをソフトライトに設定したいと思います。簡単な方法があります!

これを修正する方法については、ご了承ください。ありがとう!

答えて

1

このようにビューをブレンドすることはできません。それらは独立して解決される個別のレイヤー階層を持っています。グラデーションとテキストをCALayerオブジェクト上に移動し、それらをブレンドします(または同じビュー内で手で描画します)。たとえば:

class MyView: UIView { 
    let gradientLayer: CAGradientLayer = { 
     let gradientLayer = CAGradientLayer() 
     gradientLayer.colors = [UIColor.red.cgColor, 
           UIColor.blue.cgColor] 
     gradientLayer.startPoint = CGPoint(x: 0, y: 0) 
     gradientLayer.endPoint = CGPoint(x: 1, y: 1) 
     return gradientLayer 
    }() 

    let textLayer: CATextLayer = { 
     let textLayer = CATextLayer() 
     let astring = NSAttributedString(string: "Text Example", 
             attributes: [.font: UIFont(name: "MarkerFelt-Wide", size: 60)!]) 
     textLayer.string = astring 
     textLayer.alignmentMode = kCAAlignmentCenter 
     textLayer.bounds = astring.boundingRect(with: CGSize(width: .max, height: .max), 
               options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil) 
     return textLayer 
    }() 

    override func draw(_ rect: CGRect) { 
     if let context = UIGraphicsGetCurrentContext() { 
      gradientLayer.bounds = bounds 
      gradientLayer.render(in: context) 

      context.saveGState() 
      context.setBlendMode(.softLight) 

      context.translateBy(x: center.x - textLayer.bounds.width/2, 
           y: center.y - textLayer.bounds.height/2) 

      textLayer.position = center 
      textLayer.render(in: context) 
      context.restoreGState() 
     } 
    } 
} 

enter image description here

+0

ありがとうございました!あなたは私が望んでいたものを理解し、私に与えることができた唯一の人のようです。残念ながら、私のラベルは動いているので、毎回のステップで「ブレンドカラー」を更新したいと思っています。そうする方法はありますか? – QuantumHoneybees

+0

これは単なるアニメーションです。テキストの場所を示すプロパティが必要です。そのプロパティを変更するには 'animate(withDuration:animations:)'を使い、変更されたときに 'setNeedsDisplay'を呼び出すためにそのプロパティのための' didSet'を追加してください。コアグラフィックスとコアアニメーションは、簡単な操作でもこのようなものを最適化するのに非常に優れています。ルート、そしてシステムに挑戦して悪化させようとするなら、最も単純な試みは最適です)。 –

+0

'CALayer'のカスタムプロパティをアニメーション化する代わりに、' UIView'ではなく 'CALayer'ですべてを行うことができます。それは聞こえるよりもややトリッキーです。それは難しいことではありませんが、それが必要な場合を除いて私は通常、人には勧めないほど微妙です。 –

0

テキストが本当にラベルの場合は、通常のラベルのように不透明度を変更して試すことができます。アルファをラベルに設定することに慣れていると思います。ラベルにアルファを設定するための一例の下に見つけてください:

label.textColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.25) 

それはラベルではない場合、私にヒントを与えてください - それはより複雑にする必要があります。

+0

それはラベルですが、私は不透明度を変更したくない、私は特に柔らかな光(または他のモード)へのブレンドモードを変更したいです。 – QuantumHoneybees

関連する問題