IPhone - сглаживание UIImageView и подвид к изображению = пустое изображение

У меня есть UIImageView с виллионами представлений. Некоторые из этих представлений имеют тени слоя или свечение. Этот вид немного больше экрана устройства.

Этот вид в основном представляет собой большой прозрачный вид, содержащий множество объектов (изображения, кнопки и т.д.).

Теперь я хочу сгладить все на этом представлении UIImage. Тогда я:

UIGraphicsBeginImageContext( [viewWithZillionsOfObjects bounds].size );
[[viewWithZillionsOfObjects layer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Результат

равен полностью прозрачному изображению, но имеет правильный размер.

Мне что-то не хватает?

спасибо

Ответ 1

В примере кода Apple они настраивают геометрию графического контекста в соответствии с геометрией слоя перед вызовом renderInContext:.

Они имеют дело с окном, но похоже, что код должен работать с любым представлением с некоторыми незначительными изменениями.

Я не пробовал это строить, но вот моя попытка изменить код Apple для работы с любым видом.

- (UIImage*)imageFromView:(UIView *)view 
{
    // Create a graphics context with the target size
    // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration
    // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext
    CGSize imageSize = [view bounds].size;
    if (NULL != UIGraphicsBeginImageContextWithOptions)
        UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
    else
        UIGraphicsBeginImageContext(imageSize);

    CGContextRef context = UIGraphicsGetCurrentContext();

    // -renderInContext: renders in the coordinate space of the layer,
    // so we must first apply the layer geometry to the graphics context
    CGContextSaveGState(context);
    // Center the context around the view anchor point
    CGContextTranslateCTM(context, [view center].x, [view center].y);
    // Apply the view transform about the anchor point
    CGContextConcatCTM(context, [view transform]);
    // Offset by the portion of the bounds left of and above the anchor point
    CGContextTranslateCTM(context,
                          -[view bounds].size.width * [[view layer] anchorPoint].x,
                          -[view bounds].size.height * [[view layer] anchorPoint].y);

    // Render the layer hierarchy to the current context
    [[view layer] renderInContext:context];

    // Restore the context
    CGContextRestoreGState(context);

    // Retrieve the screenshot image
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return image;
}

Ответ 2

Здесь общая версия (Swift 2.x), чтобы сгладить массив UIViews в один UIImage. В вашем случае просто передайте массив, состоящий из одного UIView, и он должен работать.

// Flattens <allViews> into single UIImage
func flattenViews(allViews: [UIView]) -> UIImage? {
    // Return nil if <allViews> empty
    if (allViews.isEmpty) {
        return nil
    }

    // If here, compose image out of views in <allViews>
    // Create graphics context
    UIGraphicsBeginImageContextWithOptions(UIScreen.mainScreen().bounds.size, false, UIScreen.mainScreen().scale)
    let context = UIGraphicsGetCurrentContext()
    CGContextSetInterpolationQuality(context, CGInterpolationQuality.High)

    // Draw each view into context
    for curView in allViews {
        curView.drawViewHierarchyInRect(curView.frame, afterScreenUpdates: false)
    }

    // Extract image & end context
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    // Return image
    return image
}