【问题标题】:How to add a gradient tint color to a UISlider in XCode 6?如何在 XCode 6 中向 UISlider 添加渐变色调?
【发布时间】:2015-01-15 15:55:22
【问题描述】:

我正在开发一个设计应用程序,该应用程序有一个部分用于通过三个滑块为 RGB 选择颜色。 正如我们在 xcode 中看到的,我们想通过 RGB 值选择颜色,滑块色调颜色是一种渐变颜色,当我们更改滑块时会发生变化。我想在我的应用程序中使用它。但我不知道该怎么做?

我在博客中找到了这段代码。但对我不起作用。

- (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];

}

如果有任何帮助,我将不胜感激。谢谢。

【问题讨论】:

    标签: objective-c ios8 xcode6 gradient uislider


    【解决方案1】:

    虽然它没有给我想要的结果,但对于那些想要尝试它的人来说,上面的答案是一个肮脏的 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 版本可以提供所需的结果。如果您想使用它,我会在这里分享它
    • @HosseinMaktoobian 它可以工作......只是不像我想要的那样。滑动时图像会缩放,例如,如果我只有红色和蓝色,我希望红色显示最多 50% 的幻灯片,然后其他 50% 显示蓝色。但这是红色和蓝色始终可见,只是按比例缩小以适合内容大小。
    • 看看我的回答。你应该为你的问题操纵位置。每当视图更改时,您都必须刷新渐变
    • 这应该是公认的解决方案!谢谢@DogCoffee
    • 渐变被添加,但控制被破坏 - 没有线帽,线增益 y 偏移等
    【解决方案2】:

    这是可能的解决方案:

    用法:

    //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;
    }
    

    【讨论】:

    • 太棒了!谢谢,虽然要 100% 正确,但我会使用 frame = [self trackRectForBounds:self.bounds];因此即使使用最大和最小图像也可以正常工作
    【解决方案3】:

    对于 Swift 3 并防止滑块缩放 Min 图像,在设置其图像时应用此设置。不需要重新计算滑块的左侧。仅当您可以更改渐变颜色时才重新计算。 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)
    }
    

    【讨论】:

      【解决方案4】:

      这是我经过大量网络搜索后发现的一种非常有效的方法。所以最好在这里分享它作为一个完整的答案。以下代码是Swift Class,您可以使用它来创建和使用渐变,如UIViewUIImage

      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
          }
      }
      

      【讨论】:

      • 能否提供这段代码的使用说明?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-01
      • 2021-12-31
      • 2022-11-13
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多