2013-07-23 17 views
11

UIView'deki alt sınıfıma metin çizmek istiyorum, böylece metnin şekli kesildi ve arka planın arka planı OSX Mavericks logosunda olduğu gibi bulunan here.iOS UIView alt sınıfı, arka plana doğru görünen metin çizin

Daha fazla orta/gelişmiş bir iOS geliştiricisi olduğumu söyleyebilirim, bu yüzden bana bazı çılgın çözümler atmaktan çekinmeyin. Bunu yapmak için drawRect'u geçersiz kılmam gerektiğini tahmin ediyorum.

Teşekkürler çocuklar!

DÜZENLEME:

benim ilk girişim bu sadece sadece metin görüntüleme yoluyla gösterdi 0, metnin alfa bileşeni ayarlamak beri işe yaramadı metin [UIColor clearColor] yapmakta olduğunu belirtmek gerekir.

+2

UILabels'i çizmek için değil, Çekirdek Metni kullandığınızı açıklığa kavuşturmak ister misiniz? – feliun

+0

Evet, doğru. – barndog

cevap

15

Yasal Uyarı: Bunu test etmeden yazıyorum, bu yüzden burada yanılıyorsam beni affet.

Sen bu iki basamakla gerekenleri başarmak olmalıdır:

  1. sizin bakış boyutu ile bir CATextLayer oluşturma [UIColor colorWithWhite:0 alpha:1] ve [UIColor colorWithWhite:0 alpha:0] tarafından (tamamen şeffaf olmak backgroundColor kurmak ve foregroundColor opak olması. Sonra işlemek istediğiniz dizeye string özelliğini ayarlayın, font ve fontSize vb

  2. Bu katman için görünümünüzün katmanın maske ayarlayın: myView.layer.mask = textLayer. Görünümünüzün CALayer numarasına erişmek için QuartzCore'u içe aktarmanız gerekir.

İlk adımda opak ve saydam renk arasında geçiş yapılabileceğini unutmayın.

Düzeltme: Gerçekten de, Noah haklıydı. Bunu aşmak için CoreGraphics'i kCGBlendModeDestinationOut karışım modunu kullanarak kullandım.

Birincisi, gerçekten çalıştığını gösteren bir örnek görünüm:

@implementation TestView 

- (id)initWithFrame:(CGRect)frame { 
    if (self = [super initWithFrame:frame]) { 
    self.backgroundColor = [UIColor clearColor]; 
    } 
    return self; 
} 

- (void)drawRect:(CGRect)rect { 
    [[UIColor redColor] setFill]; 
    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:10]; 
    [path fill]; 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSaveGState(context); { 
    CGContextSetBlendMode(context, kCGBlendModeDestinationOut); 
    [@"Hello!" drawAtPoint:CGPointZero withFont:[UIFont systemFontOfSize:24]]; 
    } CGContextRestoreGState(context); 
} 

@end 

görünümünüzü kontrolöre bu ekledikten sonra, Hello! çekilir TestView arkasında görünümünü görürsünüz.

bu işi yapar Neden:

karıştırma modu biz daha önce önerilen mask katmanda daha zıt alfa değerlerini ihtiyaç anlamına R = D*(1 - Sa) olarak tanımlanır. Bu nedenle, yapmanız gereken tek şey, opak bir renkle çizmektir ve bu, önceden çizdiğiniz nesnelerden çıkarılacaktır.

+0

Bu, yalnızca metni metnin maskelenmesiyle sonuçlanacak ve metni kesmeyecek. Katman maskeleri, maske katmanının opaklığını kullanır. –

+0

Katmanın alfaını tersine çevirirseniz, görünümü terketmeli ve metni kesmeli, değil mi? Ardından, görünümün kendisinin üzerine çizim yapmak yerine, maske katmanını çizin. – StatusReport

+0

“Katmanın alfaını ters çevirin” bir şey değil. Düz bir arka plan rengine ve saydam bir metin rengine sahip bir metin katmanı belirlerseniz, alfa doldurulmuş bir dikdörtgen olacaktır. –

1

Kendi kendime şaşırtıcı bir şekilde nasıl yapılacağını anladım ama @ StatusReport'un cevabı tamamen geçerli ve şu anki haliyle çalışıyor.

İşte öyle yapmıştım:

-(void)drawRect:(CGRect)rect{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    [[UIColor darkGrayColor]setFill]; //this becomes the color of the alpha mask 
    CGContextFillRect(context, rect); 
    CGContextSaveState(context); 
    [[UIColor whiteColor]setFill]; 
    //Have to flip the context since core graphics is done in cartesian coordinates 
    CGContextTranslateCTM(context, 0, rect.size.height); 
    CGContextScaleCTM(context, 1.0, -1.0); 
    [textToDraw drawInRect:rect withFont:[UIFont fontWithName:@"HelveticaNeue-Thin" size:40]; 
    CGContextRestoreGState(context); 
    CGImageRef alphaMask = CGBitmapContextCreateImage(context); 
    [[UIColor whiteColor]setFill]; 
    CGContextFillRect(context, rect); 
    CGContextSaveGState(context); 
    CGContentClipToMask(context, rect, alphaMask); 
    [backgroundImage drawInRect:rect]; 
    CGContextRestoreGState(context); 
    CGImageRelease(alphaMask); 
} 

- (void)setTextToDraw:(NSString*)text{ 
    if(text != textToDraw){ 
     textToDraw = text; 
     [self setNeedsDisplay]; 
    } 
} 

Ben bu yüzden ayarlayıcı geçersiz kılmak ve [self setNeedsDisplay] diyebiliriz textToDraw için bir @synthesize beyanı bulunmaktadır. Tamamen gerekli olup olmadığından emin değil.

Eminim bunun bazı yazım hataları vardır ancak sizi temin ederim, yazım denetimi sürümü düzgün çalışıyor.

İlgili konular