2016-01-05 3 views
0

Я пытаюсь выяснить, как создать овальный градиент, который не является идеальным кругом. Например, американский футбол/регби/форма глаз вместо круга.Создание овального градиента в форме

На данный момент я создал подкласс CALayer, как показано ниже, который создает круг. Как я могу получить это овальную форму (как упоминалось выше)?

class CircleGradientLayer: CALayer { 

var startRadius: CGFloat? 
var startCenter: CGPoint? 
var endCenter: CGPoint? 
var endRadius: CGFloat? 
var locations: [CGFloat]? 
var colors: [UIColor]? 

override func drawInContext(ctx: CGContext) { 
    super.drawInContext(ctx) 


    if let colors = self.colors, let locations = self.locations, let startRadius = self.startRadius, let startCenter = self.startCenter, let endCenter = self.endCenter, let endRadius = self.endRadius { 
     var colorSpace: CGColorSpaceRef? 

     var components = [CGFloat]() 
     for i in 0 ..< colors.count { 
      let colorRef = colors[i].CGColor 
      let colorComponents = CGColorGetComponents(colorRef) 
      let numComponents = CGColorGetNumberOfComponents(colorRef) 
      if colorSpace == nil { 
       colorSpace = CGColorGetColorSpace(colorRef) 
      } 
      for j in 0 ..< numComponents { 
       let component = colorComponents[j] 
       components.append(component) 
      } 
     } 

     if let colorSpace = colorSpace { 
      let gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, locations.count) 
      CGContextDrawRadialGradient(ctx, gradient, startCenter, startRadius, endCenter, endRadius, CGGradientDrawingOptions.DrawsAfterEndLocation) 

     } 
    } 
} 
} 

example

+0

Вы можете попробовать установить преобразование на уровне (например, 'CGAffineTransformMakeScale (1.5, 1.0)'). Это не очень изменяет сам градиент, просто растягивая слой, но это может быть ОК в зависимости от вашего варианта использования. –

+0

Мы уже используем преобразование, чтобы показать сам вид. Может ли преобразование применяться только к слою? – StuartM

+0

Да. См. Здесь: https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CALayer_class/#//apple_ref/occ/instp/CALayer/transform. Свойство 'transform' на' CALayer' имеет тип 'CATransform3D', но не' CGAffineTransform', поэтому вместо этого вы захотите использовать «CATransform3DMakeScale» и друзей. –

ответ

2

Один из способов сделать это было бы установить ваш слой преобразует путем масштабирования X вверх какой-либо фактор. Например:

layer.transform = CATransform3DMakeScale(1.5, 1.0) 

Не уверен, что это лучшее решение или нет, но оно должно работать!

+0

лучше повезло, установив радиус на максимальную ширину и высоту, а затем уменьшив масштаб – Chase

+0

Имеет смысл - у вас будет меньше скейлинговых артефактов, так как вы уменьшаете масштаб, а не вверх. Хороший улов! –