Сглаживание диагональных ребер CALayer

Когда я устанавливаю свойство transform моего CALayer с помощью CATransform3DRotate, слой корректно поворачивается. Однако края слоя зазубренные и не сглаживаются. Я прочитал пару сообщений на эту тему:

iPhone: CALayer + повернуть в 3D + сглаживание?

iPhone - неровные края при применении перспективы к CALayer

Я попытался включить их совет, установив следующие свойства на моем диагональном слое

CALayer* layer = myView.layer;
layer.shadowOpacity = 0.01;
layer.edgeAntialiasingMask = kCALayerTopEdge | kCALayerBottomEdge | kCALayerRightEdge | kCALayerLeftEdge;
layer.borderWidth = 1.0;
layer.borderColor = [UIColor clearColor].CGColor;
layer.backgroundColor = [UIColor greenColor].CGColor;

Я также переопределил drawLayer:inContext: метод моего диагонального слоя, чтобы обеспечить сглаживание:

-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context
{
    CGContextSetAllowsAntialiasing(context, true);
    CGContextSetShouldAntialias(context, true);
    CGContextSetFillColorWithColor(context, [UIColor greenColor].CGColor);
    CGContextFillRect(context, self.bounds);
}

Что мне не хватает?

2 ответа

Решение

Я только что сделал пост об этом для изображений. Может быть, это поможет.

Я нашел несколько уловок, которые помогают, и установка только границы не делала то, что я думал, что будет. Что вы можете сделать, это установить несколько параметров, чтобы помочь с интерполяцией, растеризацией и rasterisationScale.

Посмотрите, поможет ли что-нибудь из этого кода:

    UIImage * img =[UIImage imageWithData:[NSData dataWithContentsOfFile:[[[NSBundle mainBundle ] resourcePath ] stringByAppendingPathComponent:@"AliasImage.png" ] ] ];
CGRect imageRect = CGRectMake( 0 , 0 , img.size.width + 4 , img.size.height + 4 );
UIGraphicsBeginImageContext( imageRect.size );
[img drawInRect:CGRectMake( imageRect.origin.x + 2 , imageRect.origin.y + 2 , imageRect.size.width - 4 , imageRect.size.height - 4 ) ];
CGContextSetInterpolationQuality( UIGraphicsGetCurrentContext() , kCGInterpolationHigh );
img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[aliasImage setImage:img ];

aliasImage.transform = CGAffineTransformScale(aliasImage.transform , 0.45 , 0.45 );
aliasImage.layer.shouldRasterize = YES;
aliasImage.layer.rasterizationScale = 0.45;
aliasImage.layer.edgeAntialiasingMask = kCALayerLeftEdge | kCALayerRightEdge | kCALayerBottomEdge | kCALayerTopEdge;
aliasImage.clipsToBounds = NO;
aliasImage.layer.masksToBounds = NO;

У меня есть несколько примеров, размещенных здесь

Начиная с iOS7, теперь это наконец возможно для каждого слоя и без каких-либо уродливых хаков, таких как прозрачные пиксели или обходных путей, таких как растеризация:

layer.allowsEdgeAntialiasing = YES;

Интересно, что это не охватывается официальной документацией CALayer, но определенно является публичным API. См. Различие API iOS7 и замечательную статью Питера Стейнбергера о скрытых драгоценных камнях и обходных путях в iOS7.

Другие вопросы по тегам