Есть ли способ сделать градиентный цвет фона в конструкторе интерфейса? - PullRequest
37 голосов
/ 17 ноября 2011

Для своего приложения я использую TableView и использую настроенные UITableViewCells.

Я настраивал свои ячейки через конструктор интерфейса, а не программно.Можно ли также сделать цвет фона моей настраиваемой ячейки градиентом в конструкторе интерфейсов?

Спасибо.

Ответы [ 9 ]

53 голосов
/ 04 декабря 2016

Это работает для 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

29 голосов
/ 17 ноября 2011

Чтобы нарисовать градиент, вам придется программно создать подкласс и переопределить 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);
}

Самый простой способ , который хранит ваши ячейки в конструкторе интерфейса, - это, вероятно,подкласс UIView, чтобы он нарисовал градиент в своем drawRect и поместил его в вашу ячейку позади других подпредставлений:

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

Однако, лучший способ сделать это - лучший , вероятно, неиспользуйте конструктор интерфейса для этого и создайте подкласс UITableViewCell.Для продвинутой настройки разработчики интерфейса, как правило, только усложняют мой опыт.Это зависит от личных предпочтений.

13 голосов
/ 02 мая 2014
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];
7 голосов
/ 17 ноября 2011

Да, это возможно: сделать изображение в градиенте с пикселем 1 X высоты. Установите это для backgroundColor для ячейки.

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

** Вы можете установить цвет градиента с помощью кода, но его время заняло процесс. Если вы заполняете лучше, ищите это.

4 голосов
/ 16 октября 2017

ответ от 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)
        }
    } 
    
1 голос
/ 15 декабря 2017

Основываясь на ответе etayluz, я немного изменил код, приняв во внимание свойство layerClass UIView , поэтому вам не нужен отдельный слой в качестве подслоя.

Я думаю, что он намного чище и работает с живыми обновлениями в Интерфейсном Разработчике.

@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 голосов
/ 23 августа 2018

Создайте класс простого представления со свойствами @IBInspectable.

  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 голосов
/ 17 ноября 2011

Нет, вы не можете.Вы можете использовать UISegmentedControl с одним сегментом в старых версиях SDK и xCode: http://chris -software.com / index.php / 2009/05/13 / creation-a-nice-glass-buttons / Но сейчасВы не можете сделать менее двух сегментов в одном UISegmentedControl.И даже таким образом, вы не можете изменить цвета кнопок по умолчанию без кодирования.

0 голосов
/ 17 ноября 2011

Я не знаю, есть ли опция градиента, но вы можете добавить UIImageView в пользовательскую ячейку и добавить изображение с градиентом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...