SORU
19 HAZİRAN 2014, PERŞEMBE


Nasıl CAShapeLayer ve UİBezierPath ile düzgün bir daire çizmek için?

Bir CAShapeLayer kullanarak ve dairesel bir yolunu ayarlayarak okşadı bir daire çizmek için çalışıyorum. Ancak, bu yöntemi kullanarak borderRadius daha ekrana işlenmiş veya bir CGContextRef yolu doğrudan çizim yaparken sürekli olarak daha az doğru.

Burada her üç yöntem sonuçları: enter image description here

Üçüncü kötü, özellikle üst ve alt kontur içinde oluşturulur dikkat edin.

Benvar[UIScreen mainScreen].scale contentsScale özelliğini ayarlayın.

İşte bu üç daire için resim kodu. Eksik CAShapeLayer sorunsuz çizim yapmak için ne?

@interface BCViewController ()

@end

@interface BCDrawingView : UIView

@end

@implementation BCDrawingView

- (id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame])) {
        self.backgroundColor = nil;
        self.opaque = YES;
    }

    return self;
}

- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];

    [[UIColor whiteColor] setFill];
    CGContextFillRect(UIGraphicsGetCurrentContext(), rect);

    CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), NULL);
    [[UIColor redColor] setStroke];
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 1);
    [[UIBezierPath bezierPathWithOvalInRect:CGRectInset(self.bounds, 4, 4)] stroke];
}

@end

@interface BCShapeView : UIView

@end

@implementation BCShapeView

  (Class)layerClass
{
    return [CAShapeLayer class];
}

- (id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame])) {
        self.backgroundColor = nil;
        CAShapeLayer *layer = (id)self.layer;
        layer.lineWidth = 1;
        layer.fillColor = NULL;
        layer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(self.bounds, 4, 4)].CGPath;
        layer.strokeColor = [UIColor redColor].CGColor;
        layer.contentsScale = [UIScreen mainScreen].scale;
        layer.shouldRasterize = NO;
    }

    return self;
}

@end


@implementation BCViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIView *borderView = [[UIView alloc] initWithFrame:CGRectMake(24, 104, 36, 36)];
    borderView.layer.borderColor = [UIColor redColor].CGColor;
    borderView.layer.borderWidth = 1;
    borderView.layer.cornerRadius = 18;
    [self.view addSubview:borderView];

    BCDrawingView *drawingView = [[BCDrawingView alloc] initWithFrame:CGRectMake(20, 40, 44, 44)];
    [self.view addSubview:drawingView];

    BCShapeView *shapeView = [[BCShapeView alloc] initWithFrame:CGRectMake(20, 160, 44, 44)];
    [self.view addSubview:shapeView];

    UILabel *borderLabel = [UILabel new];
    borderLabel.text = @"CALayer borderRadius";
    [borderLabel sizeToFit];
    borderLabel.center = CGPointMake(borderView.center.x   26   borderLabel.bounds.size.width/2.0, borderView.center.y);
    [self.view addSubview:borderLabel];

    UILabel *drawingLabel = [UILabel new];
    drawingLabel.text = @"drawRect: UIBezierPath";
    [drawingLabel sizeToFit];
    drawingLabel.center = CGPointMake(drawingView.center.x   26   drawingLabel.bounds.size.width/2.0, drawingView.center.y);
    [self.view addSubview:drawingLabel];

    UILabel *shapeLabel = [UILabel new];
    shapeLabel.text = @"CAShapeLayer UIBezierPath";
    [shapeLabel sizeToFit];
    shapeLabel.center = CGPointMake(shapeView.center.x   26   shapeLabel.bounds.size.width/2.0, shapeView.center.y);
    [self.view addSubview:shapeLabel];
}


@end

EDİT: farkı görmek isteyenler İçin birbiri ve Yakınlaştırılmış: daireler çizdim

Burada drawRect: ile kırmızı bir daire çizilmiş ve sonra tekrar drawRect: ile özdeş bir çember üstünde yeşil çizdim. Sınırlı kırmızı kanamaya dikkat edin. Hem bu çevrelerin "" (cornerRadius uygulama aynıdır): pürüzsüz

enter image description here

Bu ikinci örnekte, sorunu göreceksiniz. Yeşil aynı yolu drawRect: bir uygulama ile, ama üstünde kırmızı CAShapeLayer kullanarak bir kez, tekrar çizdim. Çok fazla kırmızı Daire altında kanama ile daha fazla tutarsızlık görebilirsiniz unutmayın. Açıkça (ve kötü) farklı bir şekilde çizilmiş.

enter image description here

CEVAP
11 AĞUSTOS 2014, PAZARTESİ


Bir daire çizmek için bir çok yol vardır kim bilir?

TL;DR:Eğer CAShapeLayer kullanma ve hala düzgün daireler elde etmek istiyorsanız, shouldRasterize rasterizationScale dikkatli kullanmanız gerekir.

Özgün

enter image description here

İşte özgün CAShapeLayer drawRect sürümünden bir fark. Retina ekranlı iPad Mini bir ekran görüntüsü yaptım, sonra Photoshop masaj ve 200'e patladı. Açıkça gördüğünüz gibi, CAShapeLayer sürümü görünür farklılıklar, özellikle sol ve sağ kenarları (diff en karanlık piksel) vardır.

Ekran ölçekte bu seçeneği kullanın

enter image description here

Hadi ekranında retina cihazlarda 2.0 hangi ölçekte, bu seçeneği kullanın. Bu kodu ekleyin:

layer.rasterizationScale = [UIScreen mainScreen].scale;
layer.shouldRasterize = YES;

rasterizationScale bile varsayılan belirsizliğini shouldRasterize için hesap retina cihazlar 1.0 varsayılan unutmayın.

Daire şimdi biraz daha yumuşak olabilir, ama kötü bit (diff en karanlık piksel) üst ve alt kenarlarına akın etti. Hayır rasterleştirme daha kesinlikle daha iyi değil!

2x ekranında bu seçeneği kullanın ölçek

enter image description here

layer.rasterizationScale = 2.0 * [UIScreen mainScreen].scale;
layer.shouldRasterize = YES;

Bu retina cihazlarda 2x ekran ölçekte, veya 4.0 yol rasterleştirir.

Çember artık gözle görülür bir şekilde daha yumuşak, farklar çok hafif ve eşit bir şekilde yayıldı.

Ben de Araçların bu koştu: Temel Animasyon ve Temel Animasyon hata Ayıklama Seçenekleri. herhangi bir büyük farklılıklar göremedim Ancak ölçek küçültme sadece ekran için ekran dışında bir bitmap ekran olduğu için daha yavaş olabilir. Ayrıca animasyon geçici süre shouldRasterize = NO ayarlamak gerekebilir.

Ne işe yaramazsa

  • Kendisi tarafından shouldRasterize = YES ayarlayın.Retina cihazlarda bu rasterizationScale != screenScale çünkü bulanık görünüyor.

  • contentScale = screenScale ayarlayın.CAShapeLayer veya rasterleştirme olup olmadığını contents, içine çekmek değil bu yana, bu yorumu etkilemez.

Humaan ilk dikkatimi çekti, keskin bir grafik tasarımcı Jay Hollywood için kredi.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Charles Renaud

    Charles Rena

    10 Kasım 2007
  • Joanna Okrajni

    Joanna Okraj

    4 EYLÜL 2010
  • pleated-jeans

    pleated-jean

    6 HAZİRAN 2013