Câu trả lời bởi dmaclach chỉ thích hợp cho hình dạng mà có thể dễ dàng được đảo ngược. Giải pháp của tôi là chế độ xem tùy chỉnh hoạt động với mọi hình dạng và văn bản. Nó đòi hỏi iOS 4 và có độ phân giải độc lập.
Đầu tiên, giải thích bằng hình ảnh về mã của mã. Hình dạng ở đây là hình tròn.
Mã vẽ văn bản có màu trắng. Nếu nó không được yêu cầu, mã có thể được tái cấu trúc thêm, bởi vì dropshadow cần phải được che dấu khác nhau. Nếu bạn cần nó trên một phiên bản cũ của iOS, bạn sẽ phải thay thế khối và sử dụng một (gây phiền nhiễu) CGBitmapContext.
- (UIImage*)blackSquareOfSize:(CGSize)size {
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
[[UIColor blackColor] setFill];
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width, size.height));
UIImage *blackSquare = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return blackSquare;
}
- (CGImageRef)createMaskWithSize:(CGSize)size shape:(void (^)(void))block {
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
block();
CGImageRef shape = [UIGraphicsGetImageFromCurrentImageContext() CGImage];
UIGraphicsEndImageContext();
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(shape),
CGImageGetHeight(shape),
CGImageGetBitsPerComponent(shape),
CGImageGetBitsPerPixel(shape),
CGImageGetBytesPerRow(shape),
CGImageGetDataProvider(shape), NULL, false);
return mask;
}
- (void)drawRect:(CGRect)rect {
UIFont *font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:40.0f];
CGSize fontSize = [text_ sizeWithFont:font];
CGImageRef mask = [self createMaskWithSize:rect.size shape:^{
[[UIColor blackColor] setFill];
CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
[[UIColor whiteColor] setFill];
// custom shape goes here
[text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), 0) withFont:font];
[text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -1) withFont:font];
}];
CGImageRef cutoutRef = CGImageCreateWithMask([self blackSquareOfSize:rect.size].CGImage, mask);
CGImageRelease(mask);
UIImage *cutout = [UIImage imageWithCGImage:cutoutRef scale:[[UIScreen mainScreen] scale] orientation:UIImageOrientationUp];
CGImageRelease(cutoutRef);
CGImageRef shadedMask = [self createMaskWithSize:rect.size shape:^{
[[UIColor whiteColor] setFill];
CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
CGContextSetShadowWithColor(UIGraphicsGetCurrentContext(), CGSizeMake(0, 1), 1.0f, [[UIColor colorWithWhite:0.0 alpha:0.5] CGColor]);
[cutout drawAtPoint:CGPointZero];
}];
// create negative image
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
[[UIColor blackColor] setFill];
// custom shape goes here
[text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -1) withFont:font];
UIImage *negative = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef innerShadowRef = CGImageCreateWithMask(negative.CGImage, shadedMask);
CGImageRelease(shadedMask);
UIImage *innerShadow = [UIImage imageWithCGImage:innerShadowRef scale:[[UIScreen mainScreen] scale] orientation:UIImageOrientationUp];
CGImageRelease(innerShadowRef);
// draw actual image
[[UIColor whiteColor] setFill];
[text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -0.5) withFont:font];
[[UIColor colorWithWhite:0.76 alpha:1.0] setFill];
[text_ drawAtPoint:CGPointMake((self.bounds.size.width/2)-(fontSize.width/2), -1) withFont:font];
// finally apply shadow
[innerShadow drawAtPoint:CGPointZero];
}
Tôi cũng muốn biết điều này để mô phỏng một UITextField cách đây khá lâu và đã sử dụng Quartz (như gợi ý) nhưng có một số vấn đề về hiệu suất, tôi khá chắc chắn rằng hoạt hình giới hạn của UILabel rendering bóng theo cách đó sẽ không đẹp. Nó sẽ trông chậm chạp. Trong trường hợp của tôi tôi đã kết thúc bằng cách sử dụng một UIImage kéo dài: stretchableImageWithLeftCapWidth: topCapHeight: nó nhanh hơn nhiều nếu nó phù hợp với nhu cầu của bạn – nacho4d
Liên kết hình ảnh trong câu hỏi của bạn bị hỏng – jjxtra