UILabel sobre UIProgressView con múltiples colors

Así que aún no lo he hecho, estoy intentando entender cómo hacerlo. Entonces hago un UITableView y cada celda tiene un NSTimer asociado. Ahora, en cada UITableViewCell personalizado, tengo un UIProgressView como background, estirado para llenar la celda. Ahora quiero agregar un UILabel con el time restante en el UIProgressView. Pero como la barra de progreso llena el color y el color de background son dramáticamente diferentes (relleno de progreso en azul marino y background blanco / área sin relleno), me pregunto cómo cambiar dinámicamente el color del text a medida que se llena la barra de progreso. Al igual que la parte de la UILabel que está en el relleno azul marino, el color del text debe ser blanco. La parte que está en el background blanco, el text debe ser negro. Algo así, pero en el objective c.

Simplemente hackeado esto por ti 🙂

El resultado

Aquí hay un resultado del simulador de ZWProgressView:

introduzca la descripción de la imagen aquí

El file del controller de vista

Aquí hay un ejemplo de uso:

#import "ViewController.h" #import "ZWProgressView.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. ZWProgressView *progressView = [[ZWProgressView alloc] init]; progressView.frame = CGRectMake((self.view.bounds.size.width - 200) / 2.0, self.view.bounds.size.height / 2.0 - 25.0, 200, 50); progressView.progress = 0.47; [self.view addSubview:progressView]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end 

La class ZWProgressView

Nota: código de enmascaramiento tomado de:

Simplemente enmascara una UIView con un rectángulo

El file de encabezado

 #import <UIKit/UIKit.h> @interface ZWProgressView : UIView @property (nonatomic, assign) CGFloat progress; @property (nonatomic, strong) UIColor *normalTextColor; @property (nonatomic, strong) UIColor *maskedTextColor; @property (nonatomic, strong) UIView *container; @property (nonatomic, strong) UIView *progressBar; @property (nonatomic, strong) UILabel *progressLabel; @property (nonatomic, strong) UILabel *maskedProgressLabel; @property (nonatomic, strong) UIView *mask; @end 

El file de implementación

 #import "ZWProgressView.h" @interface ZWProgressView() { NSLayoutConstraint *progressBarWidthConstraint; NSLayoutConstraint *progressBarMaskWidthConstraint; } @end @implementation ZWProgressView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code self.frame = frame; [self initView]; [self addAllConstraints]; } return self; } -(void)initView { self.layer.cornerRadius = 2.0; self.backgroundColor = [UIColor colorWithRed:0.85 green:0.85 blue:0.85 alpha:1.0]; self.normalTextColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1.0]; self.maskedTextColor = [UIColor whiteColor]; self.container = [[UIView alloc] init]; self.container.layer.borderWidth = 1.0; self.container.layer.borderColor = [UIColor grayColor].CGColor; self.container.backgroundColor = [UIColor whiteColor]; self.container.layer.cornerRadius = 3.0; self.container.clipsToBounds = YES; self.progressBar = [[UIView alloc] init]; self.progressBar.backgroundColor = [UIColor colorWithRed:0.2 green:0.3 blue:0.8 alpha:1.0]; self.progressLabel = [[UILabel alloc] init]; self.progressLabel.font = [UIFont fontWithName:@"Arial-BoldMT" size:30]; self.progressLabel.textAlignment = NSTextAlignmentCenter; self.progressLabel.textColor = self.normalTextColor; self.progressLabel.clipsToBounds = YES; self.maskedProgressLabel = [[UILabel alloc] init]; self.maskedProgressLabel.font = self.progressLabel.font; self.maskedProgressLabel.textAlignment = self.progressLabel.textAlignment; self.maskedProgressLabel.textColor = self.maskedTextColor; self.maskedProgressLabel.clipsToBounds = YES; self.mask = [[UIView alloc] init]; [self.container addSubview:self.progressBar]; [self.container addSubview:self.progressLabel]; [self.container addSubview:self.maskedProgressLabel]; [self.container addSubview:self.mask]; [self addSubview:self.container]; } -(void)addAllConstraints { self.container.translatesAutoresizingMaskIntoConstraints = NO; self.progressBar.translatesAutoresizingMaskIntoConstraints = NO; self.progressLabel.translatesAutoresizingMaskIntoConstraints = NO; self.maskedProgressLabel.translatesAutoresizingMaskIntoConstraints = NO; self.mask.translatesAutoresizingMaskIntoConstraints = NO; id views = @{@"container": self.container, @"progressBar": self.progressBar, @"progressLabel": self.progressLabel, @"maskedProgressLabel": self.maskedProgressLabel, @"mask": self.mask}; // container constraint [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[container]-5-|" options:0 metrics:nil views:views]]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-5-[container]-5-|" options:0 metrics:nil views:views]]; // progressBar constraint [self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[progressBar]" options:0 metrics:nil views:views]]; progressBarWidthConstraint = [NSLayoutConstraint constraintWithItem:self.progressBar attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]; [self.container addConstraint:progressBarWidthConstraint]; [self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[progressBar]|" options:0 metrics:nil views:views]]; // progressLabel constraint [self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[progressLabel]|" options:0 metrics:nil views:views]]; [self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[progressLabel]|" options:0 metrics:nil views:views]]; // maskedProgressLabel constraint [self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[maskedProgressLabel]|" options:0 metrics:nil views:views]]; [self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[maskedProgressLabel]|" options:0 metrics:nil views:views]]; // mask constraint [self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mask]" options:0 metrics:nil views:views]]; [self.container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[mask]|" options:0 metrics:nil views:views]]; progressBarMaskWidthConstraint = [NSLayoutConstraint constraintWithItem:self.mask attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]; [self.container addConstraint:progressBarMaskWidthConstraint]; } -(void)setProgress:(CGFloat)progress { int percentage = progress * 100; NSString *strProgress = [[NSString alloc] initWithFormat:@"%d%%", percentage]; self.progressLabel.text = strProgress; self.maskedProgressLabel.text = strProgress; // ------------------------------------------------------------------ // subtracting 10 pixel for the |-5-[progressBar]-5-| padding in // the constraint for the progresBar // ------------------------------------------------------------------ progressBarWidthConstraint.constant = progress * (self.bounds.size.width - 10.0); progressBarMaskWidthConstraint.constant = progressBarWidthConstraint.constant; [self layoutIfNeeded]; [self updateMask]; } -(void)updateMask { // ------------------------------------------------------------------------ // Masking code taken from: // // https://stackoverflow.com/questions/11391058/simply-mask-a-uiview-with-a-rectangle // ------------------------------------------------------------------------ CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; CGRect maskRect = CGRectMake(0, 0, progressBarMaskWidthConstraint.constant, self.mask.bounds.size.height); CGPathRef path = CGPathCreateWithRect(maskRect, NULL); maskLayer.path = path; CGPathRelease(path); self.maskedProgressLabel.layer.mask = maskLayer; } @end 

Puede hacer esto fácilmente usando dos UILabels, uno con el color del text anterior y otro con el color del text después. Deben estar exactamente uno encima del otro. A continuación, puede networkingucir el ancho de la label en la parte superior correspondiente al timer y la label en la parte inferior comenzará a mostrarse. Esto debería darle el efecto que está buscando.