2016-06-12 4 views
2

Я рисую colorWheel в своем приложении. Я делаю это, создавая CGImage в отдельной функции и используя CGContextDrawImage в drawRect, чтобы разместить его на экране.Почему мой CGImage не отображается правильно после setNeedsDisplay

На начальном этапе это выглядит нормально, но после вызова setNeedsDisplay (или setNeedsDisplayInRect) изображение становится черным/искаженным. Я должен делать что-то глупое, но не могу понять.

Cool Wheel Cool Wheel

DrawRect код выглядит следующим образом:

override func drawRect(rect: CGRect) { 

    if let context = UIGraphicsGetCurrentContext() { 

     let wheelFrame = CGRectMake(0,0,circleRadius*2,circleRadius*2) 
     CGContextSaveGState(context) 

      //create clipping mask for circular wheel 
     CGContextAddEllipseInRect(context, wheelFrame) 
     CGContextClip(context) 

      //draw the wheel 
     if colorWheelImage != nil { CGContextDrawImage(context, CGRectMake(0,0,circleRadius*2,circleRadius*2), colorWheelImage) } 
     CGContextRestoreGState(context) 

      //draw a selector element 
     self.drawSliderElement(context) 
    } 
} 

функция генерации CGimage:

func generateColorWheelImage() { 

    let width  = Int(circleRadius*2) 
    let height  = Int(circleRadius*2) 

    var pixels = [PixelData]() 

    for yIndex in 0..<width { 
     for xIndex in 0..<height { 
      pixels.append(colorAtPoint(CGPoint(x: xIndex, y: yIndex))) 
     } 
    } 

    let rgbColorSpace = CGColorSpaceCreateDeviceRGB() 
    let bitmapInfo  = CGBitmapInfo.ByteOrderDefault 

    let bitsPerComponent: Int = 8 
    let bitsPerPixel: Int  = 24 

    let renderingIntent = CGColorRenderingIntent.RenderingIntentDefault 

    assert(pixels.count == Int(width * height)) 

    var data = pixels 

    let providerRef = CGDataProviderCreateWithData(nil, data, data.count * sizeof(PixelData), nil) 

    colorWheelImage = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, width * Int(sizeof(PixelData)), rgbColorSpace, bitmapInfo, providerRef, nil, true,renderingIntent) 

} 

ответ

0

я, наконец, нашел ответ (здесь: https://stackoverflow.com/a/10798750/5233176) к этой проблеме, когда я начал запуская код на ipad, а не симулятор, и получил BAD_ACCESS_ERROR, скорее, увидев di резкое изображение.

В ответ объясняется: «[C] CMSampleBuffer используется непосредственно для создания CGImageRef, поэтому [CGImageRef станет недействительным после освобождения буфера».

Следовательно, проблема была с этой линией:

let providerRef = CGDataProviderCreateWithData(nil, data, data.count * sizeof(PixelData), nil) 

И проблема может быть решена с помощью копии буфера, например, так:

let providerData = NSData(bytes: data, length: data.count * sizeof(PixelData)) 
    let provider  = CGDataProviderCreateWithCFData(providerData)