Сглаживание диагональных ребер 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.