Forum Archive

Transparent label text

rb

Hi there
Simple question but I can’t seem to get this working.
When a ui.SegmentedControl is selected the background goes black and the text transparent. How can I replicate this transparent text on a solid black background with a ui.label text?
Tried setting text_color (0,0,0,0) and background_color (0,0,0,1) to no avail.

mikael

@rb, sorry for being slow, but what is the effective difference between transparent and black text on black background?

rb

no it’s more of a cut out text that reveals an underlying image/bg effect

JonB

shouldnt it be tint_color, not text_color?

mikael

@rb, here’s a quick custom label class which does what you want, I think.

import ui

class SeeThroughLabel(ui.View):

  def __init__(self, text, **kwargs):
    super().__init__(**kwargs)
    self.draw_background_color=self.background_color
    self.background_color='transparent'
    self.text = text
    if not hasattr(self, 'font'):
      self.font = ('<system>', 12)
    if not hasattr(self, 'alignment'):
      self.alignment = ui.ALIGN_CENTER
    if not hasattr(self, 'line_break_mode'):
      self.line_break_mode = ui.LB_WORD_WRAP
    if not hasattr(self, 'max_width'):
      self.max_width = 0
    self.size_to_fit()

  def size_to_fit(self):
    fit_to_size = ui.measure_string(
      self.text,
      max_width=self.max_width, 
      font=self.font, 
      alignment=self.alignment, 
      line_break_mode=self.line_break_mode)
    self.bounds = (0, 0) + tuple(fit_to_size)
    self.bounds = self.bounds.inset(-8, -8)

  def draw(self):
    ui.set_color(self.draw_background_color)
    ui.fill_rect(*self.bounds)
    ui.set_blend_mode(ui.BLEND_CLEAR)
    ui.draw_string(self.text,   
      rect=self.bounds.inset(8, 8),
      font=self.font, color='black', 
      alignment=self.alignment, 
      line_break_mode=self.line_break_mode)

if __name__ == '__main__':
  v = ui.View()
  v.background_color = 'red'

  tl = SeeThroughLabel(
    text='Test',
    background_color='black',
    font=('Chalkduster', 36))

  tl.center = v.bounds.center()
  tl.flex = 'RLTB'

  v.add_subview(tl)
  v.present()
mikael

For future reference: I also looked into setting an ObjC mask view, but UIKit does not have any nice built-in method for inverting the alpha channel of the mask, so that would have ended up having as much code as the above solution.