Dumitru Rogojinaru
Dumitru Rogojinaru

Reputation: 301

Filling Undefined forms with Gradient color SWIFT

I am new to programming and I have no idea how I can fill a undefined geometrical form with a gradient color... I managed to do with a simple color like that:

 func fillRegion(pixelX: Int, pixelY: Int, withColor color: UIColor) {

    var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0
    color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)

    var newColor = (UInt32)(alpha*255)<<24 | (UInt32)(red*255)<<16 | (UInt32)(green*255)<<8 | (UInt32)(blue*255)<<0

    let pixelColor = regionsData.advanced(by: (pixelY * imageHeight) + pixelX).pointee

    if pixelColor == blackColor { return }

    var pointerRegionsData: UnsafeMutablePointer<UInt32> = regionsData
    var pointerImageData: UnsafeMutablePointer<UInt32> = imageData

    var pixelsChanged = false

    for i in 0...(imageHeight * imageHeight - 1) {
        if pointerRegionsData.pointee == pixelColor {
            pointerImageData = imageData.advanced(by: i)
            if pointerImageData.pointee != newColor {
//                    newColor = newColor + 1
                pointerImageData.pointee = newColor
                pixelsChanged = true
            }
        }
        pointerRegionsData = pointerRegionsData.successor()
    }

    if pixelsChanged {
        self.image = UIImage(cgImage: imageContext.makeImage()!)
        DispatchQueue.main.async {
            CATransaction.setDisableActions(true)
            self.layer.contents = self.image.cgImage
            self.onImageDraw?(self.image)
        }
        self.playTapSound()
    }
}

Pixel by pixel it fill the color (ignoring the black color) any ideas how to do that with Gradient color? thanks!

Upvotes: 1

Views: 448

Answers (2)

Josh Homann
Josh Homann

Reputation: 16327

You can make a gradient layer and apply an image or a shape layer as its mask. Here is a playground.

    import PlaygroundSupport
    import UIKit

    class V: UIView {
        private lazy var gradientLayer: CAGradientLayer = {
            let gradientLayer = CAGradientLayer()
            gradientLayer.colors =  [UIColor.red.cgColor,
                                     UIColor.purple.cgColor,
                                     UIColor.blue.cgColor,
                                     UIColor.white.cgColor]
            gradientLayer.locations = [0, 0.3, 0.9, 1]
            gradientLayer.startPoint = CGPoint(x: 0, y: 0)
            gradientLayer.endPoint = CGPoint(x: 0, y: 1)
            gradientLayer.mask = self.strokeLayer
            self.layer.addSublayer(gradientLayer)
            return gradientLayer
        }()

        private lazy var strokeLayer: CAShapeLayer = {
            let strokeLayer = CAShapeLayer()
            strokeLayer.path = UIBezierPath(ovalIn: CGRect(x:0, y: 0, width: 100, height: 100)).cgPath
            return strokeLayer
        }()

        override func layoutSubviews() {
            super.layoutSubviews()
            strokeLayer.path = UIBezierPath(ovalIn: bounds).cgPath
            gradientLayer.frame = bounds

            layer.addSublayer(gradientLayer)
        }
    }
    let v = V(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
    PlaygroundPage.current.liveView = v

Upvotes: 1

Maury Markowitz
Maury Markowitz

Reputation: 9279

I'm not 100% sure I understand the question, but it seems like you want to fill any-old shape with a gradient, right? If so, there are a couple of ways to do that, but the easiest is to make a gradient that's the same size as the boundary of the shape and then apply that as its color. I'm typing this on my PC so I'm sure there's syntax errors, but here goes...

let size = CGSize(width, height)
UIGraphicsRenderer(size, false, 0) // I KNOW I have this one wrong
let colors = [tColour.cgColor, bColour.cgColor] as CFArray
let colorSpace = CGColorSpaceCreateDeviceRGB()
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors , locations: nil)

Set the colors array as needed and then send that into the UIImage. You can use locations: to change the orientation.

Upvotes: 0

Related Questions