2013-07-23 60 views
11

Tôi muốn vẽ văn bản lên lớp con trên UIView để văn bản được cắt ra khỏi hình dạng và hậu cảnh phía sau màn hình hiển thị qua, giống như trong logo OSX Mavericks được tìm thấy here.Lớp phủ UIView iOS, vẽ văn bản xem qua đến hình nền

Tôi có thể nói rằng tôi là một nhà phát triển iOS trung cấp/cao cấp hơn nên cảm thấy tự do khi ném một số giải pháp điên rồ cho tôi. Tôi hy vọng tôi sẽ phải ghi đè lên drawRect để thực hiện việc này.

Xin cảm ơn các bạn!

EDIT:

tôi nên đề cập rằng nỗ lực đầu tiên của tôi đã làm cho văn bản [UIColor clearColor] mà không làm việc vì đó chỉ cần đặt các thành phần alpha của văn bản để 0, mà chỉ cho thấy quan điểm thông qua các văn bản.

+2

Chỉ cần làm rõ bạn đang sử dụng Core Text để vẽ chứ không phải UILabels? – feliun

+0

Vâng, đúng vậy. – barndog

Trả lời

15

Tuyên bố từ chối trách nhiệm: Tôi đang viết bài này mà không cần kiểm tra, vì vậy hãy tha thứ cho tôi nếu tôi sai ở đây.

Bạn nên đạt được những gì bạn cần bằng hai bước sau:

  1. Tạo một CATextLayer với kích thước của tầm nhìn của bạn, thiết lập các backgroundColor là hoàn toàn minh bạch và foregroundColor được đục (bởi [UIColor colorWithWhite:0 alpha:1][UIColor colorWithWhite:0 alpha:0]. sau đó thiết lập các string tài sản cho chuỗi bạn muốn render, fontfontSize, vv

  2. đặt mặt nạ xem của bạn lớp để lớp này: myView.layer.mask = textLayer. Bạn sẽ phải nhập QuartzCore để truy cập vào CALayer chế độ xem của mình.

Lưu ý rằng tôi có thể chuyển đổi giữa màu đục và trong suốt trong bước đầu tiên.

Chỉnh sửa: Thật vậy, Noah đã đúng. Để khắc phục điều này, tôi đã sử dụng CoreGraphics với chế độ hòa trộn kCGBlendModeDestinationOut.

Thứ nhất, một cái nhìn mẫu cho thấy rằng nó thực sự hoạt động:

@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 

Sau khi thêm này để điều khiển xem, bạn sẽ thấy một cái nhìn đằng sau TestView nơi Hello! được rút ra.

Tại sao công việc này:

Các chế độ hòa trộn được định nghĩa là R = D*(1 - Sa), có nghĩa là chúng ta cần giá trị alpha đối diện hơn trong lớp mask tôi đề nghị trước đó. Do đó, tất cả những gì bạn cần làm là vẽ với màu đục và điều này sẽ bị trừ khỏi nội dung bạn đã vẽ trên chế độ xem trước đó.

+0

Điều đó sẽ dẫn đến việc che giấu chế độ xem với văn bản chứ không phải cắt văn bản ra khỏi văn bản đó. Mặt nạ lớp sử dụng độ mờ đục của lớp mặt nạ. –

+0

Nếu bạn đảo ngược alpha của lớp, nó sẽ để lại quan điểm và cắt văn bản, không? Sau đó, thay vì vẽ trên chính khung nhìn, hãy vẽ trên lớp mặt nạ. – StatusReport

+0

"Đảo ngược alpha của lớp" không phải là một điều. Nếu bạn thiết lập một lớp văn bản để có một màu nền vững chắc và một màu văn bản trong suốt, alpha của nó sẽ là một hình chữ nhật đầy. –

1

Tôi thực sự đã tìm ra cách làm điều đó một cách đáng ngạc nhiên nhưng câu trả lời của @ StatusReport hoàn toàn hợp lệ và hoạt động như hiện tại.

Đây là cách tôi đã làm nó:

-(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]; 
    } 
} 

Tôi có một lời tuyên bố @synthesize cho textToDraw vì vậy tôi có thể ghi đè lên các setter và gọi [self setNeedsDisplay]. Không chắc chắn nếu đó là hoàn toàn cần thiết hay không.

Tôi chắc chắn điều này có một số lỗi chính tả nhưng tôi có thể đảm bảo với bạn, phiên bản kiểm tra chính tả chỉ chạy tốt.

Các vấn đề liên quan