有没有办法在界面构建器中制作渐变背景颜色?

Ser*_*yol 40 interface-builder uitableview ios

对于我的应用程序,我使用的是TableView并使用自定义的UITableViewCells.

我通过界面构建​​器而不是以编程方式自定义我的单元格 有没有办法在界面构建器中使我的自定义单元格的背景颜色成为渐变?

谢谢.

eta*_*luz 55

这适用于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)
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在此输入图像描述

  • 这会将渐变图层放在您的子视图之上,这显然是不可取的,请使用`gradient.zposition = -1`来修复它. (4认同)
  • 正确的属性名称是`gradient.zPosition`. (3认同)
  • 可能是用例的问题,但使用superview的框架并不是我需要的.将它改为`gradient.frame = bounds`给了我预期的行为. (2认同)

Abe*_*ant 29

要绘制渐变,您必须以编程方式子类化并覆盖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);
}
Run Code Online (Sandbox Code Playgroud)

将单元格保留在界面构建器中的最简单方法可能是将UIView子类化为使其在drawRect中绘制渐变并将其放置在其他子视图后面的单元格中:

GradientView *gradientView = [[GradientView alloc] init];
gradientView.frame = cell.bounds;
[cell addSubview:gradientView];
[cell sendSubviewToBack:gradientView];
Run Code Online (Sandbox Code Playgroud)

但是,最好的方法是不要使用接口构建器,并创建UITableViewCell的子类.对于高级自定义,界面构建器往往只会让我的体验变得更复杂.这取决于个人偏好.


Ali*_*aza 13

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];
Run Code Online (Sandbox Code Playgroud)


Sud*_*mar 7

是的,这是可能的:使用1 X高度像素制作渐变图像.将其设置为backgroundColor for cell.

cell.backgroundColor =  [UIColor colorWithPatternImage:[UIImage imageNamed:@"gradImage.png"]];
Run Code Online (Sandbox Code Playgroud)

**您可以使用代码设置渐变颜色,但需要花费时间.如果你填写得更好,那么搜索它.


alf*_*ern 5

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)
        }
    } 
    
    Run Code Online (Sandbox Code Playgroud)


Jul*_*anM 5

基于etayluz的回答,我通过考虑UIViewlayerClass属性对代码进行了一些更改,因此您不需要单独的层作为子层。

我认为它更干净,并且还可以与 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]
    }

}
Run Code Online (Sandbox Code Playgroud)