Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 当渐变重新启动时,如何在swift中使用图像时固定文本上的渐变_Ios_Swift_Uilabel_Core Graphics_Gradient - Fatal编程技术网

Ios 当渐变重新启动时,如何在swift中使用图像时固定文本上的渐变

Ios 当渐变重新启动时,如何在swift中使用图像时固定文本上的渐变,ios,swift,uilabel,core-graphics,gradient,Ios,Swift,Uilabel,Core Graphics,Gradient,我试图在文本上创建一个渐变,我使用UIGraphics来使用渐变图像来创建这个。我遇到的问题是梯度正在重新开始。有人知道如何缩放渐变以延伸到文本吗 文本位于线框上,将被更改几次。有时它是完美的,但有时它不是 渐变应该从黄色变为蓝色,但会重新启动,请参见下图: 每次标签大小更改时,您都必须重新绘制图像 这是因为图案UIColor仅平铺。发件人: 在绘制过程中,图案颜色的图像根据需要平铺以覆盖给定区域 因此,当标签的边界发生变化时,您需要自己更改图像大小,因为图案图像不支持拉伸。为此,可以将UIL

我试图在文本上创建一个渐变,我使用UIGraphics来使用渐变图像来创建这个。我遇到的问题是梯度正在重新开始。有人知道如何缩放渐变以延伸到文本吗

文本位于线框上,将被更改几次。有时它是完美的,但有时它不是

渐变应该从黄色变为蓝色,但会重新启动,请参见下图:

每次标签大小更改时,您都必须重新绘制图像 这是因为图案
UIColor
仅平铺。发件人:

在绘制过程中,图案颜色的图像根据需要平铺以覆盖给定区域

因此,当标签的边界发生变化时,您需要自己更改图像大小,因为图案图像不支持拉伸。为此,可以将
UILabel
子类化,并覆盖
layoutSubviews
方法。这样做应该可以达到预期的效果:

class GradientLabel: UILabel {
    
    let gradientImage = UIImage(named:"gradient.png")
    
    override func layoutSubviews() {
        
        guard let grad = gradientImage else { // skip re-drawing gradient if it doesn't exist
            return
        }
        
        // redraw your gradient image
        UIGraphicsBeginImageContext(frame.size)
        grad.drawInRect(bounds)
        let myGradient = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        // update text color
        textColor = UIColor(patternImage: myGradient)
    }
}

虽然值得一提的是,我总是更喜欢自己画一个渐变,因为你可以有更多的灵活性(比如说你想在以后添加另一种颜色)。此外,当您以不同的大小重新绘制图像时,图像的质量可能会降低(尽管由于渐变的性质,这应该是相当小的)

只需覆盖
UILabel
子类的
drawRect
,就可以绘制自己的渐变。例如:

override func drawRect(rect: CGRect) {
    
    // begin new image context to let the superclass draw the text in (so we can use it as a mask)
    UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
    do {
        // get your image context
        let ctx = UIGraphicsGetCurrentContext()
        
        // flip context
        CGContextScaleCTM(ctx, 1, -1)
        CGContextTranslateCTM(ctx, 0, -bounds.size.height)
        
        // get the superclass to draw text
        super.drawRect(rect)
    }
    
    // get image and end context
    let img = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    // get drawRect context
    let ctx = UIGraphicsGetCurrentContext()
    
    // clip context to image
    CGContextClipToMask(ctx, bounds, img.CGImage)
    
    // define your colors and locations
    let colors = [UIColor.orangeColor().CGColor, UIColor.redColor().CGColor, UIColor.purpleColor().CGColor, UIColor.blueColor().CGColor]
    let locs:[CGFloat] = [0.0, 0.3, 0.6, 1.0]
    
    // create your gradient
    let grad = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, locs)
    
    // draw gradient
    CGContextDrawLinearGradient(ctx, grad, CGPoint(x: 0, y:bounds.size.height*0.5), CGPoint(x:bounds.size.width, y:bounds.size.height*0.5), CGGradientDrawingOptions(rawValue: 0))

}
输出:


swift4&as子类
@OliverCanagh您需要在故事板中选择标签,然后进入身份检查器。然后可以将类字段更改为自定义类()。很高兴我的回答能帮上忙,请:)嗨,谢谢你回复我,现在效果很好!非常感谢你的帮助。抱歉,我无意中删除了我以前关于如何将渐变应用于标签的评论。下面是使用Swift 3的
NSTextView
示例:
override func drawRect(rect: CGRect) {
    
    // begin new image context to let the superclass draw the text in (so we can use it as a mask)
    UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
    do {
        // get your image context
        let ctx = UIGraphicsGetCurrentContext()
        
        // flip context
        CGContextScaleCTM(ctx, 1, -1)
        CGContextTranslateCTM(ctx, 0, -bounds.size.height)
        
        // get the superclass to draw text
        super.drawRect(rect)
    }
    
    // get image and end context
    let img = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    // get drawRect context
    let ctx = UIGraphicsGetCurrentContext()
    
    // clip context to image
    CGContextClipToMask(ctx, bounds, img.CGImage)
    
    // define your colors and locations
    let colors = [UIColor.orangeColor().CGColor, UIColor.redColor().CGColor, UIColor.purpleColor().CGColor, UIColor.blueColor().CGColor]
    let locs:[CGFloat] = [0.0, 0.3, 0.6, 1.0]
    
    // create your gradient
    let grad = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, locs)
    
    // draw gradient
    CGContextDrawLinearGradient(ctx, grad, CGPoint(x: 0, y:bounds.size.height*0.5), CGPoint(x:bounds.size.width, y:bounds.size.height*0.5), CGGradientDrawingOptions(rawValue: 0))

}
class GradientLabel: UILabel {
    
    // MARK: - Colors to create gradient from
    @IBInspectable open var gradientFrom: UIColor?
    @IBInspectable open var gradientTo: UIColor?
    
    override func draw(_ rect: CGRect) {
        // begin new image context to let the superclass draw the text in (so we can use it as a mask)
        UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0.0)
        do {
            // get your image context
            guard let ctx = UIGraphicsGetCurrentContext() else { super.draw(rect); return }
            // flip context
            ctx.scaleBy(x: 1, y: -1)
            ctx.translateBy(x: 0, y: -bounds.size.height)
            // get the superclass to draw text
            super.draw(rect)
        }
        // get image and end context
        guard let img = UIGraphicsGetImageFromCurrentImageContext(), img.cgImage != nil else { return }
        UIGraphicsEndImageContext()
        // get drawRect context
        guard let ctx = UIGraphicsGetCurrentContext() else { return }
        // clip context to image
        ctx.clip(to: bounds, mask: img.cgImage!)
        // define your colors and locations
        let colors: [CGColor] = [UIColor.orange.cgColor, UIColor.red.cgColor, UIColor.purple.cgColor, UIColor.blue.cgColor]
        let locs: [CGFloat] = [0.0, 0.3, 0.6, 1.0]
        // create your gradient
        guard let grad = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors as CFArray, locations: locs) else { return }
        // draw gradient
        ctx.drawLinearGradient(grad, start: CGPoint(x: 0, y: bounds.size.height*0.5), end: CGPoint(x:bounds.size.width, y: bounds.size.height*0.5), options: CGGradientDrawingOptions(rawValue: 0))
    }
}