Is there a way to make gradient background color in the interface builder?

前端 未结 9 1148
终归单人心
终归单人心 2021-01-30 13:08

For my application I\'m using a TableView and using customized UITableViewCells.

I customized my cells via interface builder, not programmatically. Is there a way to als

相关标签:
9条回答
  • 2021-01-30 13:47

    answer by etayluz works fine but I added a couple changes:

    1. Gradient size defined by own layer bounds, not the superview.
    2. Remove Gradient layer on every draw, so that it does not keep drawing and adding a new layer when redraw is necessary (for instance by calling .setNeedsDisplay() on rotation).

      @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)
          }
      } 
      
    0 讨论(0)
  • 2021-01-30 13:49

    To draw a gradient, you will have to subclass and override the drawRect programmatically:

    - (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);
    }
    

    The easiest way, which keeps your cells in the interface builder, is probably to subclass a UIView to have it draw a gradient in its drawRect and place it in your cell behind the other subviews:

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

    However, the best way to do it is probably not to use the interface builder for this and make a subclass of UITableViewCell. For advanced customization, interface builders tend to only make things more complicated in my experience. That's up to personal preference though.

    0 讨论(0)
  • 2021-01-30 13:55

    Based on etayluz answer I changed the code a little bit by taking the layerClass property of a UIView into account, so you do not need a separate layer as a sublayer.

    I think it is much cleaner and it also works with live updates in the 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]
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题