Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make UILabel with non-English characters green when Color Blended Layer is enabled?

I have a table view with custom cells and I try to optimize it by making all subviews inside the cells in green color when Color Blended Layer is checked in the simulator.

When the background of an UILabel in the cell is set to white:

let title = UILabel()
contentView.addSubview(title)
title.background = UIColor.whiteColor()
title.text = "Hi, how are you?"

This UILabel subview will become green color in the simulator, which is good. However, if I change the text to some Chinese:

title.text = "你好"

The UILabel subview will become red. This SO post provides some explanation about the situation. Is there actually a solution for this?

like image 259
Joe Huang Avatar asked Feb 10 '16 06:02

Joe Huang


1 Answers

Use CATextLayer instead of UILabel. And don't forget to set its opaque property to true.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

        // You should definitely put layer handling logic into 
        // UITableViewCell subclass. I'm omitting it for clarity
    let layer = cell.contentView.layer

    let textLayer = CATextLayer()
    textLayer.string = "你好"
    textLayer.bounds = CGRect(x: 0, y: 0, width: 100, height: 50)
    textLayer.position = CGPoint(x: 50, y: 25)
    textLayer.opaque = true

    layer.addSublayer(textLayer)

    return cell
}

UPD: If a black background is not what you are looking for, a problem becomes a bit trickier, but yet solvable.

All you need is to inject two lines of code into drawing mechanism. There are two ways to achieve this:

  • to use a delegate of a CALayer or

  • to make a subclass of CATextLayer.

In our case I believe the latter is preferable. So instead of CATextLayer in the example below use this class:

class OpaqueTextLayerWithCustomizableBackgroundColor: CATextLayer {
    override func drawInContext(ctx: CGContext) {
        if let color = backgroundColor {
            CGContextSetFillColorWithColor(ctx, color)
            CGContextFillRect(ctx, bounds);
        }
        super.drawInContext(ctx)
    }
}
like image 104
Zapko Avatar answered Sep 22 '22 02:09

Zapko