Я пытаюсь создать представление с градиентным цветным фоном (сплошной цвет до прозрачного) во время выполнения. Есть ли способ сделать это?
Программно создайте UIView с градиентом цвета
Ответ 1
Objective-C:
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = view.bounds;
gradient.colors = @[(id)[UIColor whiteColor].CGColor, (id)[UIColor blackColor].CGColor];
[view.layer insertSublayer:gradient atIndex:0];
Swift:
let view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 50))
let gradient = CAGradientLayer()
gradient.frame = view.bounds
gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
view.layer.insertSublayer(gradient, at: 0)
Информация: используйте startPoint и endPoint для изменить направление градиента.
Если в этот UIView (например, UILabel) добавлены другие представления (например, UILabel), вы можете захотеть установить цвет фона этих UIView s на [UIColor clearColor], чтобы вместо этого было представлено представление градиента цвета фона для подменю. Использование clearColor имеет небольшое повышение производительности.
Ответ 2
Вы можете создать собственный класс GradientView:
Swift 5
class GradientView: UIView {
    override open class var layerClass: AnyClass {
       return CAGradientLayer.classForCoder()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        let gradientLayer = layer as! CAGradientLayer
        gradientLayer.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
    }
}
В раскадровке установите тип класса для любого представления, для которого вы хотите иметь градиентный фон:
Это лучше следующими способами:
- Нет необходимости устанавливать кадр из CLayer
- Используйте NSConstraintкак обычно наUIView
- Не нужно создавать подслои (меньше использования памяти)
Ответ 3
Это мой рекомендуемый подход.
Чтобы способствовать повторному использованию, я бы сказал, создав категорию CAGradientLayer и добавив нужные градиенты в качестве методов класса. Укажите их в файле header следующим образом:
#import <QuartzCore/QuartzCore.h>
@interface CAGradientLayer (SJSGradients)
+ (CAGradientLayer *)redGradientLayer;
+ (CAGradientLayer *)blueGradientLayer;
+ (CAGradientLayer *)turquoiseGradientLayer;
+ (CAGradientLayer *)flavescentGradientLayer;
+ (CAGradientLayer *)whiteGradientLayer;
+ (CAGradientLayer *)chocolateGradientLayer;
+ (CAGradientLayer *)tangerineGradientLayer;
+ (CAGradientLayer *)pastelBlueGradientLayer;
+ (CAGradientLayer *)yellowGradientLayer;
+ (CAGradientLayer *)purpleGradientLayer;
+ (CAGradientLayer *)greenGradientLayer;
@end
Затем в вашем файле реализации укажите каждый градиент с помощью этого синтаксиса:
+ (CAGradientLayer *)flavescentGradientLayer
{
    UIColor *topColor = [UIColor colorWithRed:1 green:0.92 blue:0.56 alpha:1];
    UIColor *bottomColor = [UIColor colorWithRed:0.18 green:0.18 blue:0.18 alpha:1];
    NSArray *gradientColors = [NSArray arrayWithObjects:(id)topColor.CGColor, (id)bottomColor.CGColor, nil];
    NSArray *gradientLocations = [NSArray arrayWithObjects:[NSNumber numberWithInt:0.0],[NSNumber numberWithInt:1.0], nil];
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.colors = gradientColors;
    gradientLayer.locations = gradientLocations;
    return gradientLayer;
}
Затем просто импортируйте эту категорию в свой ViewController или любой другой требуемый subclass и используйте его следующим образом:
CAGradientLayer *backgroundLayer = [CAGradientLayer purpleGradientLayer];
backgroundLayer.frame = self.view.frame;
[self.view.layer insertSublayer:backgroundLayer atIndex:0];
Ответ 4
Попробуй это, это сработало как талисман для меня,
Цель С
Я установил цвет градиента RGB для UIview
   UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,35)];
   CAGradientLayer *gradient = [CAGradientLayer layer];
   gradient.frame = view.bounds;
   gradient.startPoint = CGPointZero;
   gradient.endPoint = CGPointMake(1, 1);
   gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithRed:34.0/255.0 green:211/255.0 blue:198/255.0 alpha:1.0] CGColor],(id)[[UIColor colorWithRed:145/255.0 green:72.0/255.0 blue:203/255.0 alpha:1.0] CGColor], nil];
   [view.layer addSublayer:gradient];
ОБНОВЛЕНО: - Swift3 +
Код: -
 var gradientView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 35))
 let gradientLayer:CAGradientLayer = CAGradientLayer()
 gradientLayer.frame.size = self.gradientView.frame.size
 gradientLayer.colors = 
 [UIColor.white.cgColor,UIColor.red.withAlphaComponent(1).cgColor] 
//Use diffrent colors
 gradientView.layer.addSublayer(gradientLayer)
Вы можете добавить начальную и конечную точку цвета градиента.
  gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
  gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
Для более подробной информации см. CAGradientLayer Doc
Надеюсь, что это помощь для кого-то.
Ответ 5
Поскольку мне нужен только один тип градиента в моем приложении, я создал подкласс UIView и предварительно сконфигурировал слой градиента при инициализации с помощью фиксированных цветов. Инициализаторы UIView вызывают метод configureGradientLayer, который настраивает CAGradientLayer:
DDGradientView.h:
#import <UIKit/UIKit.h>
@interface DDGradientView : UIView {
}
@end
DDGradientView.m:
#import "DDGradientView.h"
@implementation DDGradientView
// Change the views layer class to CAGradientLayer class
+ (Class)layerClass
{
    return [CAGradientLayer class];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if(self) {
        [self configureGradientLayer];
    }
    return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if(self) {
        [self configureGradientLayer];
    }
    return self;
}
// Make custom configuration of your gradient here   
- (void)configureGradientLayer {
    CAGradientLayer *gLayer = (CAGradientLayer *)self.layer;
    gLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor], (id)[[UIColor lightGrayColor] CGColor], nil];
}
@end
Ответ 6
Быстрая реализация:
var gradientLayerView: UIView = UIView(frame: CGRectMake(0, 0, view.bounds.width, 50))
var gradient: CAGradientLayer = CAGradientLayer()
gradient.frame = gradientLayerView.bounds
gradient.colors = [UIColor.grayColor().CGColor, UIColor.clearColor().CGColor]
gradientLayerView.layer.insertSublayer(gradient, atIndex: 0)
self.view.layer.insertSublayer(gradientLayerView.layer, atIndex: 0)
Ответ 7
Я реализовал это быстро и с расширением:
Swift 3
extension UIView {
    func addGradientWithColor(color: UIColor) {
        let gradient = CAGradientLayer()
        gradient.frame = self.bounds
        gradient.colors = [UIColor.clear.cgColor, color.cgColor]
        self.layer.insertSublayer(gradient, at: 0)
    }
}
Swift 2.2
extension UIView {
    func addGradientWithColor(color: UIColor) {
        let gradient = CAGradientLayer()
        gradient.frame = self.bounds
        gradient.colors = [UIColor.clearColor().CGColor, color.CGColor]
        self.layer.insertSublayer(gradient, atIndex: 0)
    }
}
Нет. Я могу задать градиент для каждого вида, например:
myImageView.addGradientWithColor(UIColor.blue)
Ответ 8
Я немного расширил принятый ответ, используя функциональность расширения Swift, а также перечисление.
О, и если вы используете раскадровку, как я, не забудьте позвонить gradientBackground(from:to:direction:) в viewDidLayoutSubviews() или позже.
Swift 3
enum GradientDirection {
    case leftToRight
    case rightToLeft
    case topToBottom
    case bottomToTop
}
extension UIView {
    func gradientBackground(from color1: UIColor, to color2: UIColor, direction: GradientDirection) {
        let gradient = CAGradientLayer()
        gradient.frame = self.bounds
        gradient.colors = [color1.cgColor, color2.cgColor]
        switch direction {
        case .leftToRight:
            gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
            gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
        case .rightToLeft:
            gradient.startPoint = CGPoint(x: 1.0, y: 0.5)
            gradient.endPoint = CGPoint(x: 0.0, y: 0.5)
        case .bottomToTop:
            gradient.startPoint = CGPoint(x: 0.5, y: 1.0)
            gradient.endPoint = CGPoint(x: 0.5, y: 0.0)
        default:
            break
        }
        self.layer.insertSublayer(gradient, at: 0)
    }
}
Ответ 9
Быстрый подход
Этот ответ основывается на ответах выше и обеспечивает реализацию для решения проблемы градиента, который не применяется должным образом во время вращения. Он удовлетворяет этой задаче, изменяя слой градиента на квадрат так, чтобы вращение во всех направлениях приводило к правильному градиенту. Функциональная подпись включает переменный аргумент Swift, который позволяет передавать как можно больше CGColorRef (CGColor) (см. Пример использования образца). Также представлен пример расширения Swift, так что можно применить градиент к любому UIView.
   func configureGradientBackground(colors:CGColorRef...){
        let gradient: CAGradientLayer = CAGradientLayer()
        let maxWidth = max(self.view.bounds.size.height,self.view.bounds.size.width)
        let squareFrame = CGRect(origin: self.view.bounds.origin, size: CGSizeMake(maxWidth, maxWidth))
        gradient.frame = squareFrame
        gradient.colors = colors
        view.layer.insertSublayer(gradient, atIndex: 0)
    }
Использовать:
in viewDidLoad...
  override func viewDidLoad() {
        super.viewDidLoad()
        configureGradientBackground(UIColor.redColor().CGColor, UIColor.whiteColor().CGColor)
  }
Расширение
extension CALayer {
    func configureGradientBackground(colors:CGColorRef...){
        let gradient = CAGradientLayer()
        let maxWidth = max(self.bounds.size.height,self.bounds.size.width)
        let squareFrame = CGRect(origin: self.bounds.origin, size: CGSizeMake(maxWidth, maxWidth))
        gradient.frame = squareFrame
        gradient.colors = colors
        self.insertSublayer(gradient, atIndex: 0)
    }
}
Пример использования префикса расширения:
 override func viewDidLoad() {
        super.viewDidLoad()
        self.view.layer.configureGradientBackground(UIColor.purpleColor().CGColor, UIColor.blueColor().CGColor, UIColor.whiteColor().CGColor)
 }
Это означает, что теперь фон градиента может применяться к любому UIControl, поскольку все элементы управления представляют собой UIViews (или подкласс), а все UIViews имеют CALayers.
Swift 4
Расширение
extension CALayer {
    public func configureGradientBackground(_ colors:CGColor...){
        let gradient = CAGradientLayer()
        let maxWidth = max(self.bounds.size.height,self.bounds.size.width)
        let squareFrame = CGRect(origin: self.bounds.origin, size: CGSize(width: maxWidth, height: maxWidth))
        gradient.frame = squareFrame
        gradient.colors = colors
        self.insertSublayer(gradient, at: 0)
    }    
}
Пример использования префикса расширения:
override func viewDidLoad() {
    super.viewDidLoad()
    self.view.layer.configureGradientBackground(UIColor.purple.cgColor, UIColor.blue.cgColor, UIColor.white.cgColor)
}
Ответ 10
То, что вы ищете, это CAGradientLayer. Каждый UIView имеет слой - в этот слой вы можете добавить подслои, так же, как вы можете добавить subviews. Один конкретный тип - это CAGradientLayer, где вы даете ему массив цветов для градиента.
Одним из примеров является эта простая оболочка для представления градиента:
http://oleb.net/blog/2010/04/obgradientview-a-simple-uiview-wrapper-for-cagradientlayer/
Обратите внимание, что вам необходимо включить среду QuartZCore для доступа ко всем части слоя UIView.
Ответ 11
Простой быстрый просмотр, основанный на версии Yuchen
class GradientView: UIView {
    override class func layerClass() -> AnyClass { return CAGradientLayer.self }
    lazy var gradientLayer: CAGradientLayer = {
        return self.layer as! CAGradientLayer
    }()
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}
Затем вы можете использовать gradientLayer после инициализации, как это...
someView.gradientLayer.colors = [UIColor.whiteColor().CGColor, UIColor.blackColor().CGColor]
Ответ 12
Моим решением является создание подкласса UIView с CAGradientLayer, доступным как свойство readonly. Это позволит вам настроить свой градиент, как вы хотите, и вам не нужно самостоятельно обрабатывать изменения компоновки. Реализация подкласса:
@interface GradientView : UIView
@property (nonatomic, readonly) CAGradientLayer *gradientLayer;
@end
@implementation GradientView
+ (Class)layerClass
{
    return [CAGradientLayer class];
}
- (CAGradientLayer *)gradientLayer
{
    return (CAGradientLayer *)self.layer;
}
@end
Использование:
self.iconBackground = [GradientView new];
[self.background addSubview:self.iconBackground];
self.iconBackground.gradientLayer.colors = @[(id)[UIColor blackColor].CGColor, (id)[UIColor whiteColor].CGColor];
self.iconBackground.gradientLayer.startPoint = CGPointMake(1.0f, 1.0f);
self.iconBackground.gradientLayer.endPoint = CGPointMake(0.0f, 0.0f);
Ответ 13
Хорошей идеей вызывать решения выше, чтобы обновить слой на
viewDidLayoutSubviews 
чтобы получить представление обновлено правильно
Ответ 14
Swift 4:
Правильно показывает градиент в IB:
@IBDesignable public class GradientView: UIView {
    override open class var layerClass: AnyClass {
        return CAGradientLayer.classForCoder()
    }
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configureGradientLayer()
    }
    public override init(frame: CGRect) {
        super.init(frame: frame)
        configureGradientLayer()
    }
    func configureGradientLayer() {
        let gradientLayer = layer as! CAGradientLayer
        gradientLayer.colors = [UIColor(hex: 0x003399).cgColor, UIColor(hex: 0x00297b).cgColor]
    }
}
Ответ 15
SWIFT 3
Чтобы добавить слой градиента на ваш взгляд
-  Привязать свою точку зрения @IBOutlet var YOURVIEW : UIView!
-  Определите CAGradientLayer() var gradient = CAGradientLayer()
-  Вот код, который вы должны написать в вашем viewDidLoad YOURVIEW.layoutIfNeeded()gradient.startPoint = CGPoint(x: CGFloat(0), y: CGFloat(1)) gradient.endPoint = CGPoint(x: CGFloat(1), y: CGFloat(0)) gradient.frame = YOURVIEW.bounds gradient.colors = [UIColor.red.cgColor, UIColor.green.cgColor] gradient.colors = [ UIColor(red: 255.0/255.0, green: 56.0/255.0, blue: 224.0/255.0, alpha: 1.0).cgColor,UIColor(red: 86.0/255.0, green: 13.0/255.0, blue: 232.0/255.0, alpha: 1.0).cgColor,UIColor(red: 16.0/255.0, green: 173.0/255.0, blue: 245.0/255.0, alpha: 1.0).cgColor] gradient.locations = [0.0 ,0.6 ,1.0] YOURVIEW.layer.insertSublayer(gradient, at: 0)
Ответ 16
extension UIView {
    func applyGradient(isVertical: Bool, colorArray: [UIColor]) {
        if let sublayers = layer.sublayers {
            sublayers.filter({ $0 is CAGradientLayer }).forEach({ $0.removeFromSuperlayer() })
        }
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = colorArray.map({ $0.cgColor })
        if isVertical {
            //top to bottom
            gradientLayer.locations = [0.0, 1.0]
        } else {
            //left to right
            gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
            gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
        }
        backgroundColor = .clear
        gradientLayer.frame = bounds
        layer.insertSublayer(gradientLayer, at: 0)
    }
}
ИСПОЛЬЗОВАНИЕ
someView.applyGradient(isVertical: true, colorArray: [.green, .blue])
Ответ 17
В Swift 3.1 Я добавил это расширение в UIView
import Foundation
import UIKit
import CoreGraphics
extension UIView {
    func gradientOfView(withColours: UIColor...) {
        var cgColours = [CGColor]()
        for colour in withColours {
            cgColours.append(colour.cgColor)
        }
        let grad = CAGradientLayer()
        grad.frame = self.bounds
        grad.colors = cgColours
        self.layer.insertSublayer(grad, at: 0)
    }
}
который я затем вызываю с помощью
    class OverviewVC: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            self.view.gradientOfView(withColours: UIColor.red,UIColor.green, UIColor.blue)
        }
}
Ответ 18
Я реализовал это в своем коде.
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 31.0f)];
view1.backgroundColor = [UIColor clearColor];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = view1.bounds;
UIColor *topColor = [UIColor colorWithRed:132.0/255.0 green:222.0/255.0 blue:109.0/255.0 alpha:1.0];
UIColor *bottomColor = [UIColor colorWithRed:31.0/255.0 green:150.0/255.0 blue:99.0/255.0 alpha:1.0];
gradient.colors = [NSArray arrayWithObjects:(id)[topColor CGColor], (id)[bottomColor CGColor], nil];
[view1.layer insertSublayer:gradient atIndex:0];
Теперь я вижу градиент на моем представлении.
Ответ 19
Чтобы придать UIView градиентный цвет (swift 4.2)
func makeGradientLayer('for' object : UIView, startPoint : CGPoint, endPoint : CGPoint, gradientColors : [Any]) -> CAGradientLayer {
        let gradient: CAGradientLayer = CAGradientLayer()
        gradient.colors = gradientColors
        gradient.locations = [0.0 , 1.0]
        gradient.startPoint = startPoint
        gradient.endPoint = endPoint
        gradient.frame = CGRect(x: 0, y: 0, w: object.frame.size.width, h: object.frame.size.height)
        return gradient
    }
Как пользоваться
let start : CGPoint = CGPoint(x: 0.0, y: 1.0)
let end : CGPoint = CGPoint(x: 1.0, y: 1.0)
let gradient: CAGradientLayer = makeGradientLayer(for: cell, startPoint: start, endPoint: end, gradientColors: [
                    UIColor(red:0.92, green:0.07, blue:0.4, alpha:1).cgColor,
                    UIColor(red:0.93, green:0.11, blue:0.14, alpha:1).cgColor
                    ])
self.vwTemp.layer.insertSublayer(gradient, at: 0)




