web-dev-qa-db-ja.com

UIView透明グラデーション

IOSで任意のUIViewが与えられた場合、Core Graphics(CAGradientLayerが思い浮かぶ)を使用して「前景透過」グラデーションを適用する方法はありますか

背景がUIColorより複雑なので、標準のCAGradientLayerを使用できません。サブビューが親の垂直スクロールビューに沿ってスクロールされると背景が変わるため、PNGをオーバーレイすることもできません(画像を参照)。

エレガントではないフォールバックがあります。Uiviewのサブビューをクリップし、親のスクロールビューがスクロールされるときに背景の事前レンダリングされたグラデーションpngを移動します。

transparent uiview gradient problem

34
jpsim

これは恥ずかしいほど簡単な修正でした。CAGradientLayerをサブビューのマスクとして適用します。

CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = _fileTypeScrollView.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[UIColor whiteColor].CGColor, (id)[UIColor clearColor].CGColor, nil];
gradientLayer.startPoint = CGPointMake(0.8f, 1.0f);
gradientLayer.endPoint = CGPointMake(1.0f, 1.0f);
_fileTypeScrollView.layer.mask = gradientLayer;

Cocoanetics が私を正しい方向に向けてくれてありがとう!

94
jpsim

これが私がやる方法です。

ステップ1カスタムグラデーションビューを定義します(Swift 4):

import UIKit

class GradientView: UIView {
    override open class var layerClass: AnyClass {
        return CAGradientLayer.classForCoder()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        let gradientLayer = self.layer as! CAGradientLayer
        gradientLayer.colors = [
            UIColor.white.cgColor,
            UIColor.init(white: 1, alpha: 0).cgColor
        ]
        backgroundColor = UIColor.clear
    }
}

ステップ2-ストーリーボードにUIViewをドラッグアンドドロップし、そのカスタムクラスをGradientViewに設定します

enter image description here

例として、これは上記のグラデーションビューがどのように見えるかです:


https://github.com/yzhong52/GradientViewDemo

7
Yuchen Zhong

Gradient Example

私はちょうど同じ問題にぶつかり、自分のクラスを書くことになりました。それは深刻なやり過ぎのように思えますが、透明度でグラデーションを行うことができる唯一の方法でした。あなたは私の ここに書き込みとコード例 を見ることができます

基本的には、2つの画像を作成するカスタムUIViewになります。 1つは単色で、もう1つは画像マスクとして使用されるグラデーションです。そこから、結果の画像をuiview.layer.contentに適用しました。

ジョーに役立つといいな

2
Joe Andolina

上記の受け入れられた(OPの)回答を使用し、 pvoted comment に記載されている同じ問題に遭遇しました-ビューがスクロールすると、画面外で開始されたすべてが透明になり、マスクで覆われます.

解決策は、グラデーションレイヤーをsuperviewのマスクではなく、superviewのマスクとして追加することでした。私の場合、contentViewというビュー内に含まれるテキストビューを使用しています。

3番目の色を追加し、locationsstartPointの代わりにendPointを使用したため、テキストビューの項目belowはまだ見える。

let gradientLayer = CAGradientLayer()
gradientLayer.frame = self.contentView!.bounds
gradientLayer.colors = [UIColor.white.cgColor, UIColor.clear.cgColor, UIColor.white.cgColor]

// choose position for gradient, aligned to bottom of text view
let bottomOffset = (self.textView!.frame.size.height + self.textView!.frame.Origin.y + 5)/self.contentView!.bounds.size.height
let topOffset = bottomOffset - 0.1
let bottomCoordinate = NSNumber(value: Double(bottomOffset))
let topCoordinate = NSNumber(value: Double(topOffset))
gradientLayer.locations = [topCoordinate, bottomCoordinate, bottomCoordinate]

self.contentView!.layer.mask = gradientLayer

以前は、オフスクリーンで始まるテキストは永久に見えませんでした。私の変更では、スクロールは期待どおりに機能し、「閉じる」ボタンはマスクで覆われていません。

screenshot

1
jab

私はそれを言うのが嫌いですが、私はあなたがカスタムUIViewの土地にいると思います。 drawRectルーチンをオーバーライドするカスタムUIViewでこれを実装しようと思うと思います。

これにより、そのビューを実際のスクロールビューの上に配置し、すべてのタッチイベントを「引き継ぐ」グラデーションビューを使用できます(つまり、最初のレスポンダーを放棄します)。

0
trumpetlicks