Reputation: 301
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
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
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