如何在 XCode 6 中为 UISlider 添加渐变色?
How to add a gradient tint color to a UISlider in XCode 6?
我正在开发一个设计应用程序,其中有一个部分用于通过 RGB 的三个滑块 selecting 颜色。
正如我们在 xcode 中看到的那样,我们希望通过 RGB 值 select 颜色,滑块色调颜色是一种渐变颜色,当我们改变滑块时它会发生变化。我想在我的应用程序中使用它。但我不知道该怎么做?
我在博客中找到了这段代码。但对我不起作用。
- (void)setGradientToSlider:(UISlider *)Slider WithColors:(NSArray *)Colors{
UIView * view = (UIView *)[[Slider subviews]objectAtIndex:0];
UIImageView * maxTrackImageView = (UIImageView *)[[view subviews]objectAtIndex:0];
CAGradientLayer * maxTrackGradient = [CAGradientLayer layer];
CGRect rect = maxTrackImageView.frame;
rect.origin.x = view.frame.origin.x;
maxTrackGradient.frame = rect;
maxTrackGradient.colors = Colors;
[maxTrackGradient setStartPoint:CGPointMake(0.0, 0.5)];
[maxTrackGradient setEndPoint:CGPointMake(1.0, 0.5)];
[[maxTrackImageView layer] insertSublayer:maxTrackGradient atIndex:0];
/////////////////////////////////////////////////////
UIImageView * minTrackImageView = (UIImageView *)[[view subviews]objectAtIndex:1];
CAGradientLayer * minTrackGradient = [CAGradientLayer layer];
rect = minTrackImageView.frame;
rect.size.width = maxTrackImageView.frame.size.width;
rect.origin.x = 0;
rect.origin.y = 0;
minTrackGradient.frame = rect;
minTrackGradient.colors = Colors;
[minTrackGradient setStartPoint:CGPointMake(0.0, 0.5)];
[minTrackGradient setEndPoint:CGPointMake(1.0, 0.5)];
[minTrackImageView.layer insertSublayer:minTrackGradient atIndex:0];
}
如果有任何帮助,我将不胜感激。谢谢
以下是可能的解决方案:
用法:
//array of CGColor objects, color1 and color2 are UIColor objects
NSArray *colors = [NSArray arrayWithObjects:(id)color1.CGColor, (id)color2.CGColor, nil];
//your UISlider
[slider setGradientBackgroundWithColors:colors];
实施:
在 UISlider
上创建类别:
- (void)setGradientBackgroundWithColors:(NSArray *)colors
{
CAGradientLayer *trackGradientLayer = [CAGradientLayer layer];
CGRect frame = self.frame;
frame.size.height = 5.0; //set the height of slider
trackGradientLayer.frame = frame;
trackGradientLayer.colors = colors;
//setting gradient as horizontal
trackGradientLayer.startPoint = CGPointMake(0.0, 0.5);
trackGradientLayer.endPoint = CGPointMake(1.0, 0.5);
UIImage *trackImage = [[UIImage imageFromLayer:trackGradientLayer] resizableImageWithCapInsets:UIEdgeInsetsZero];
[self setMinimumTrackImage:trackImage forState:UIControlStateNormal];
[self setMaximumTrackImage:trackImage forState:UIControlStateNormal];
}
其中 colors
是 CGColor 数组。
我还在 UIImage
上创建了一个类别,它根据图层创建图像,因为您需要一个 UIImage
来设置滑块上的渐变。
+ (UIImage *)imageFromLayer:(CALayer *)layer
{
UIGraphicsBeginImageContextWithOptions(layer.frame.size, layer.opaque, 0.0);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
}
虽然它没有给我想要的结果,但对于那些想要尝试的人来说,上面的答案是一个肮脏的 Swift 版本。
func setSlider(slider:UISlider) {
let tgl = CAGradientLayer()
let frame = CGRectMake(0, 0, slider.frame.size.width, 5)
tgl.frame = frame
tgl.colors = [UIColor.blueColor().CGColor, UIColor.greenColor().CGColor, UIColor.yellowColor().CGColor, UIColor.orangeColor().CGColor, UIColor.redColor().CGColor]
tgl.startPoint = CGPointMake(0.0, 0.5)
tgl.endPoint = CGPointMake(1.0, 0.5)
UIGraphicsBeginImageContextWithOptions(tgl.frame.size, tgl.opaque, 0.0);
tgl.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
image.resizableImageWithCapInsets(UIEdgeInsetsZero)
slider.setMinimumTrackImage(image, forState: .Normal)
//slider.setMaximumTrackImage(image, forState: .Normal)
}
更新 Swift 4.0
func setSlider(slider:UISlider) {
let tgl = CAGradientLayer()
let frame = CGRect.init(x:0, y:0, width:slider.frame.size.width, height:5)
tgl.frame = frame
tgl.colors = [UIColor.blue.cgColor, UIColor.green.cgColor, UIColor.yellow.cgColor, UIColor.orange.cgColor, UIColor.red.cgColor]
tgl.startPoint = CGPoint.init(x:0.0, y:0.5)
tgl.endPoint = CGPoint.init(x:1.0, y:0.5)
UIGraphicsBeginImageContextWithOptions(tgl.frame.size, tgl.isOpaque, 0.0);
tgl.render(in: UIGraphicsGetCurrentContext()!)
if let image = UIGraphicsGetImageFromCurrentImageContext() {
UIGraphicsEndImageContext()
image.resizableImage(withCapInsets: UIEdgeInsets.zero)
slider.setMinimumTrackImage(image, for: .normal)
}
}
这是我在大量网络搜索后发现的一种非常有效的方法。所以最好在这里分享它作为一个完整的答案。以下代码是一个 Swift Class
,您可以使用它来创建渐变并将其用作 UIView
或 UIImage
。
import Foundation
import UIKit
class Gradient: UIView{
// Gradient Color Array
private var Colors: [UIColor] = []
// Start And End Points Of Linear Gradient
private var SP: CGPoint = CGPoint.zeroPoint
private var EP: CGPoint = CGPoint.zeroPoint
// Start And End Center Of Radial Gradient
private var SC: CGPoint = CGPoint.zeroPoint
private var EC: CGPoint = CGPoint.zeroPoint
// Start And End Radius Of Radial Gradient
private var SR: CGFloat = 0.0
private var ER: CGFloat = 0.0
// Flag To Specify If The Gradient Is Radial Or Linear
private var flag: Bool = false
// Some Overrided Init Methods
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
// Draw Rect Method To Draw The Graphics On The Context
override func drawRect(rect: CGRect) {
// Get Context
let context = UIGraphicsGetCurrentContext()
// Get Color Space
let colorSpace = CGColorSpaceCreateDeviceRGB()
// Create Arrays To Convert The UIColor to CG Color
var colorComponent: [CGColor] = []
var colorLocations: [CGFloat] = []
var i: CGFloat = 0.0
// Add Colors Into The Color Components And Use An Index Variable For Their Location In The Array [The Location Is From 0.0 To 1.0]
for color in Colors {
colorComponent.append(color.CGColor)
colorLocations.append(i)
i += CGFloat(1.0) / CGFloat(self.Colors.count - 1)
}
// Create The Gradient With The Colors And Locations
let gradient: CGGradientRef = CGGradientCreateWithColors(colorSpace, colorComponent, colorLocations)
// Create The Suitable Gradient Based On Desired Type
if flag {
CGContextDrawRadialGradient(context, gradient, SC, SR, EC, ER, 0)
} else {
CGContextDrawLinearGradient(context, gradient, SP, EP, 0)
}
}
// Get The Input Data For Linear Gradient
func CreateLinearGradient(startPoint: CGPoint, endPoint: CGPoint, colors: UIColor...) {
self.Colors = colors
self.SP = startPoint
self.EP = endPoint
self.flag = false
}
// Get The Input Data For Radial Gradient
func CreateRadialGradient(startCenter: CGPoint, startRadius: CGFloat, endCenter: CGPoint, endRadius: CGFloat, colors: UIColor...) {
self.Colors = colors
self.SC = startCenter
self.EC = endCenter
self.SR = startRadius
self.ER = endRadius
self.flag = true
}
// Function To Convert Gradient To UIImage And Return It
func getImage() -> UIImage {
// Begin Image Context
UIGraphicsBeginImageContext(self.bounds.size)
// Draw The Gradient
self.drawRect(self.frame)
// Get Image From The Current Context
let image = UIGraphicsGetImageFromCurrentImageContext()
// End Image Context
UIGraphicsEndImageContext()
// Return The Result Gradient As UIImage
return image
}
}
对于 Swift 3 并且为了防止滑块缩放最小图像,请在设置其图像时应用此选项。没有必要重新计算滑块的左侧。只有在可以更改渐变颜色的情况下才重新计算。 Max 图像似乎没有缩放,但您可能应该应用相同的设置以保持一致性。不应用插图时,Max 图像略有不同。
slider.setMinimumTrackImage(image?.resizableImage(withCapInsets:.zero), for: .normal)
出于某种原因,它只有在 resizableImage(withCapInsets:.zero) 同时完成时才能正常工作。 运行 分开的部分不允许图像工作并被缩放。
这是Swift 3中的整个例程:
func setSlider(slider:UISlider) {
let tgl = CAGradientLayer()
let frame = CGRect(x: 0.0, y: 0.0, width: slider.bounds.width, height: 5.0 )
tgl.frame = frame
tgl.colors = [ UIColor.yellow.cgColor,UIColor.black.cgColor]
tgl.endPoint = CGPoint(x: 1.0, y: 1.0)
tgl.startPoint = CGPoint(x: 0.0, y: 1.0)
UIGraphicsBeginImageContextWithOptions(tgl.frame.size, false, 0.0)
tgl.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
slider.setMaximumTrackImage(image?.resizableImage(withCapInsets:.zero), for: .normal)
slider.setMinimumTrackImage(image?.resizableImage(withCapInsets:.zero), for: .normal)
}
我正在开发一个设计应用程序,其中有一个部分用于通过 RGB 的三个滑块 selecting 颜色。 正如我们在 xcode 中看到的那样,我们希望通过 RGB 值 select 颜色,滑块色调颜色是一种渐变颜色,当我们改变滑块时它会发生变化。我想在我的应用程序中使用它。但我不知道该怎么做?
我在博客中找到了这段代码。但对我不起作用。
- (void)setGradientToSlider:(UISlider *)Slider WithColors:(NSArray *)Colors{
UIView * view = (UIView *)[[Slider subviews]objectAtIndex:0];
UIImageView * maxTrackImageView = (UIImageView *)[[view subviews]objectAtIndex:0];
CAGradientLayer * maxTrackGradient = [CAGradientLayer layer];
CGRect rect = maxTrackImageView.frame;
rect.origin.x = view.frame.origin.x;
maxTrackGradient.frame = rect;
maxTrackGradient.colors = Colors;
[maxTrackGradient setStartPoint:CGPointMake(0.0, 0.5)];
[maxTrackGradient setEndPoint:CGPointMake(1.0, 0.5)];
[[maxTrackImageView layer] insertSublayer:maxTrackGradient atIndex:0];
/////////////////////////////////////////////////////
UIImageView * minTrackImageView = (UIImageView *)[[view subviews]objectAtIndex:1];
CAGradientLayer * minTrackGradient = [CAGradientLayer layer];
rect = minTrackImageView.frame;
rect.size.width = maxTrackImageView.frame.size.width;
rect.origin.x = 0;
rect.origin.y = 0;
minTrackGradient.frame = rect;
minTrackGradient.colors = Colors;
[minTrackGradient setStartPoint:CGPointMake(0.0, 0.5)];
[minTrackGradient setEndPoint:CGPointMake(1.0, 0.5)];
[minTrackImageView.layer insertSublayer:minTrackGradient atIndex:0];
}
如果有任何帮助,我将不胜感激。谢谢
以下是可能的解决方案:
用法:
//array of CGColor objects, color1 and color2 are UIColor objects
NSArray *colors = [NSArray arrayWithObjects:(id)color1.CGColor, (id)color2.CGColor, nil];
//your UISlider
[slider setGradientBackgroundWithColors:colors];
实施:
在 UISlider
上创建类别:
- (void)setGradientBackgroundWithColors:(NSArray *)colors
{
CAGradientLayer *trackGradientLayer = [CAGradientLayer layer];
CGRect frame = self.frame;
frame.size.height = 5.0; //set the height of slider
trackGradientLayer.frame = frame;
trackGradientLayer.colors = colors;
//setting gradient as horizontal
trackGradientLayer.startPoint = CGPointMake(0.0, 0.5);
trackGradientLayer.endPoint = CGPointMake(1.0, 0.5);
UIImage *trackImage = [[UIImage imageFromLayer:trackGradientLayer] resizableImageWithCapInsets:UIEdgeInsetsZero];
[self setMinimumTrackImage:trackImage forState:UIControlStateNormal];
[self setMaximumTrackImage:trackImage forState:UIControlStateNormal];
}
其中 colors
是 CGColor 数组。
我还在 UIImage
上创建了一个类别,它根据图层创建图像,因为您需要一个 UIImage
来设置滑块上的渐变。
+ (UIImage *)imageFromLayer:(CALayer *)layer
{
UIGraphicsBeginImageContextWithOptions(layer.frame.size, layer.opaque, 0.0);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
}
虽然它没有给我想要的结果,但对于那些想要尝试的人来说,上面的答案是一个肮脏的 Swift 版本。
func setSlider(slider:UISlider) {
let tgl = CAGradientLayer()
let frame = CGRectMake(0, 0, slider.frame.size.width, 5)
tgl.frame = frame
tgl.colors = [UIColor.blueColor().CGColor, UIColor.greenColor().CGColor, UIColor.yellowColor().CGColor, UIColor.orangeColor().CGColor, UIColor.redColor().CGColor]
tgl.startPoint = CGPointMake(0.0, 0.5)
tgl.endPoint = CGPointMake(1.0, 0.5)
UIGraphicsBeginImageContextWithOptions(tgl.frame.size, tgl.opaque, 0.0);
tgl.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
image.resizableImageWithCapInsets(UIEdgeInsetsZero)
slider.setMinimumTrackImage(image, forState: .Normal)
//slider.setMaximumTrackImage(image, forState: .Normal)
}
更新 Swift 4.0
func setSlider(slider:UISlider) {
let tgl = CAGradientLayer()
let frame = CGRect.init(x:0, y:0, width:slider.frame.size.width, height:5)
tgl.frame = frame
tgl.colors = [UIColor.blue.cgColor, UIColor.green.cgColor, UIColor.yellow.cgColor, UIColor.orange.cgColor, UIColor.red.cgColor]
tgl.startPoint = CGPoint.init(x:0.0, y:0.5)
tgl.endPoint = CGPoint.init(x:1.0, y:0.5)
UIGraphicsBeginImageContextWithOptions(tgl.frame.size, tgl.isOpaque, 0.0);
tgl.render(in: UIGraphicsGetCurrentContext()!)
if let image = UIGraphicsGetImageFromCurrentImageContext() {
UIGraphicsEndImageContext()
image.resizableImage(withCapInsets: UIEdgeInsets.zero)
slider.setMinimumTrackImage(image, for: .normal)
}
}
这是我在大量网络搜索后发现的一种非常有效的方法。所以最好在这里分享它作为一个完整的答案。以下代码是一个 Swift Class
,您可以使用它来创建渐变并将其用作 UIView
或 UIImage
。
import Foundation
import UIKit
class Gradient: UIView{
// Gradient Color Array
private var Colors: [UIColor] = []
// Start And End Points Of Linear Gradient
private var SP: CGPoint = CGPoint.zeroPoint
private var EP: CGPoint = CGPoint.zeroPoint
// Start And End Center Of Radial Gradient
private var SC: CGPoint = CGPoint.zeroPoint
private var EC: CGPoint = CGPoint.zeroPoint
// Start And End Radius Of Radial Gradient
private var SR: CGFloat = 0.0
private var ER: CGFloat = 0.0
// Flag To Specify If The Gradient Is Radial Or Linear
private var flag: Bool = false
// Some Overrided Init Methods
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
// Draw Rect Method To Draw The Graphics On The Context
override func drawRect(rect: CGRect) {
// Get Context
let context = UIGraphicsGetCurrentContext()
// Get Color Space
let colorSpace = CGColorSpaceCreateDeviceRGB()
// Create Arrays To Convert The UIColor to CG Color
var colorComponent: [CGColor] = []
var colorLocations: [CGFloat] = []
var i: CGFloat = 0.0
// Add Colors Into The Color Components And Use An Index Variable For Their Location In The Array [The Location Is From 0.0 To 1.0]
for color in Colors {
colorComponent.append(color.CGColor)
colorLocations.append(i)
i += CGFloat(1.0) / CGFloat(self.Colors.count - 1)
}
// Create The Gradient With The Colors And Locations
let gradient: CGGradientRef = CGGradientCreateWithColors(colorSpace, colorComponent, colorLocations)
// Create The Suitable Gradient Based On Desired Type
if flag {
CGContextDrawRadialGradient(context, gradient, SC, SR, EC, ER, 0)
} else {
CGContextDrawLinearGradient(context, gradient, SP, EP, 0)
}
}
// Get The Input Data For Linear Gradient
func CreateLinearGradient(startPoint: CGPoint, endPoint: CGPoint, colors: UIColor...) {
self.Colors = colors
self.SP = startPoint
self.EP = endPoint
self.flag = false
}
// Get The Input Data For Radial Gradient
func CreateRadialGradient(startCenter: CGPoint, startRadius: CGFloat, endCenter: CGPoint, endRadius: CGFloat, colors: UIColor...) {
self.Colors = colors
self.SC = startCenter
self.EC = endCenter
self.SR = startRadius
self.ER = endRadius
self.flag = true
}
// Function To Convert Gradient To UIImage And Return It
func getImage() -> UIImage {
// Begin Image Context
UIGraphicsBeginImageContext(self.bounds.size)
// Draw The Gradient
self.drawRect(self.frame)
// Get Image From The Current Context
let image = UIGraphicsGetImageFromCurrentImageContext()
// End Image Context
UIGraphicsEndImageContext()
// Return The Result Gradient As UIImage
return image
}
}
对于 Swift 3 并且为了防止滑块缩放最小图像,请在设置其图像时应用此选项。没有必要重新计算滑块的左侧。只有在可以更改渐变颜色的情况下才重新计算。 Max 图像似乎没有缩放,但您可能应该应用相同的设置以保持一致性。不应用插图时,Max 图像略有不同。
slider.setMinimumTrackImage(image?.resizableImage(withCapInsets:.zero), for: .normal)
出于某种原因,它只有在 resizableImage(withCapInsets:.zero) 同时完成时才能正常工作。 运行 分开的部分不允许图像工作并被缩放。
这是Swift 3中的整个例程:
func setSlider(slider:UISlider) {
let tgl = CAGradientLayer()
let frame = CGRect(x: 0.0, y: 0.0, width: slider.bounds.width, height: 5.0 )
tgl.frame = frame
tgl.colors = [ UIColor.yellow.cgColor,UIColor.black.cgColor]
tgl.endPoint = CGPoint(x: 1.0, y: 1.0)
tgl.startPoint = CGPoint(x: 0.0, y: 1.0)
UIGraphicsBeginImageContextWithOptions(tgl.frame.size, false, 0.0)
tgl.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
slider.setMaximumTrackImage(image?.resizableImage(withCapInsets:.zero), for: .normal)
slider.setMinimumTrackImage(image?.resizableImage(withCapInsets:.zero), for: .normal)
}