web-dev-qa-db-ja.com

インターフェイスビルダーでグラデーションの背景色を作成する方法はありますか?

私のアプリケーションでは、TableViewを使用し、カスタマイズされたUITableViewCellsを使用しています。

プログラムではなく、インターフェイスビルダーを使用してセルをカスタマイズしました。インターフェイスビルダーでカスタマイズしたセルの背景色をグラデーションにする方法はありますか?

ありがとう。

39
Serdar Dogruyol

グラデーションを描画するには、プログラムでdrawRectをサブクラス化してオーバーライドする必要があります。

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSaveGState(context);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColorComponents
                             (colorSpace,
                              (const CGFloat[8]){1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f},
                              (const CGFloat[2]){0.0f,1.0f},
                              2);

    CGContextDrawLinearGradient(context,
                                gradient,
                                CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMinY(self.bounds)),
                                CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMaxY(self.bounds)),
                                0);

    CGColorSpaceRelease(colorSpace);
    CGContextRestoreGState(context);
}

セルをインターフェイスビルダーに保持するeasiestの方法は、おそらくUIViewをサブクラス化して、drawRectでグラデーションを描画し、他のサブビューの背後のセルに配置することです。

GradientView *gradientView = [[GradientView alloc] init];
gradientView.frame = cell.bounds;
[cell addSubview:gradientView];
[cell sendSubviewToBack:gradientView];

ただし、bestを実行する方法は、おそらくこれにインターフェイスビルダーを使用せず、UITableViewCellのサブクラスを作成することです。高度なカスタマイズの場合、インターフェースビルダーは私の経験上、より複雑なものにする傾向があります。しかし、それは個人的な好み次第です。

29
Aberrant

これはSwift 3.0で機能します:Swift 4.0で更新)

@IBDesignable
final class GradientView: UIView {
    @IBInspectable var startColor: UIColor = UIColor.clear
    @IBInspectable var endColor: UIColor = UIColor.clear

    override func draw(_ rect: CGRect) {
        let gradient: CAGradientLayer = CAGradientLayer()
        gradient.frame = CGRect(x: CGFloat(0),
                                y: CGFloat(0),
                                width: superview!.frame.size.width,
                                height: superview!.frame.size.height)
        gradient.colors = [startColor.cgColor, endColor.cgColor]
        gradient.zPosition = -1
        layer.addSublayer(gradient)
    }
}

enter image description here

enter image description here

55
etayluz
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = yourView.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor], (id)    [[UIColor whiteColor] CGColor], nil];
[yourView.layer insertSublayer:gradient atIndex:0];
13
Ali Raza

はい、これは可能です。1X Height pixでグラデーションの画像を作成します。これをセルのbackgroundColorに設定します。

cell.backgroundColor =  [UIColor colorWithPatternImage:[UIImage imageNamed:@"gradImage.png"]];

**コードでグラデーション色を設定できますが、処理に時間がかかります。あなたがよりよく満たすならば、それを捜してください。

7
Sudesh Kumar

etayluzによる回答 は正常に動作しますが、いくつかの変更を追加しました。

  1. スーパービューではなく、独自のレイヤー境界によって定義されるグラデーションサイズ。
  2. 描画のたびにグラデーションレイヤーを削除します。これにより、再描画が必要なときに描画や新しいレイヤーの追加が行われないようにします(たとえば、.setNeedsDisplay()を回転時に呼び出します)。

    @IBDesignable final class MFGradientView: UIView {
    
        @IBInspectable var startColor: UIColor = UIColor.clear
        @IBInspectable var endColor: UIColor = UIColor.clear
    
        override func draw(_ rect: CGRect) {
           layer.sublayers?.first?.removeFromSuperlayer()
    
           let gradient: CAGradientLayer = CAGradientLayer()
           gradient.frame = CGRect(Origin: CGPoint.zero, size: self.bounds.size)
           gradient.colors = [startColor.cgColor, endColor.cgColor]
           layer.insertSublayer(gradient, at: 0)
        }
    } 
    
4
alfhern

Etayluzの回答に基づいて、IViewlayerClassプロパティを考慮してコードを少し変更したため、サブレイヤーとして別のレイヤーは必要ありません。

私はそれがはるかにきれいであり、Interface Builderのライブアップデートでも動作すると思います。

@IBDesignable final class GradientView: UIView {

    @IBInspectable var startColor: UIColor = UIColor.red
    @IBInspectable var endColor: UIColor = UIColor.blue

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

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

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

    private func setupGradient() {
        let gradient = self.layer as! CAGradientLayer
        gradient.colors = [startColor.cgColor, endColor.cgColor]
    }

}
1
JulianM

@IBInspectableプロパティを使用して簡単なビュークラスを作成します。

  1. グラデーションレイヤーを1回作成する
  2. 各レイアウトサブビューのグラデーションレイヤーを再利用する

...

//
//  GradientView.Swift
//
//  Created by Maksim Vialykh on 23.08.2018.
//  Copyright © 2018 Vialyx. All rights reserved.
//

import UIKit

class GradientView: UIView {

    @IBInspectable
    var startColor: UIColor = .white

    @IBInspectable
    var endColor: UIColor = .black

    private let gradientLayerName = "Gradient"

    override func layoutSubviews() {
        super.layoutSubviews()

        setupGradient()
    }

    private func setupGradient() {
        var gradient: CAGradientLayer? = layer.sublayers?.first { $0.name == gradientLayerName } as? CAGradientLayer
        if gradient == nil {
            gradient = CAGradientLayer()
            gradient?.name = gradientLayerName
            layer.addSublayer(gradient!)
        }
        gradient?.frame = bounds
        gradient?.colors = [startColor.cgColor, endColor.cgColor]
        gradient?.zPosition = -1
    }

}
0
LLIAJLbHOu