【问题标题】:UILabel over UIProgressView with multiple colors具有多种颜色的 UIProgressView 上的 UILabel
【发布时间】:2014-08-08 03:53:03
【问题描述】:

所以我还没有这样做,我正在尝试弄清楚如何做到这一点。所以我制作了一个 UITableView,每个单元格都有一个关联的 NSTimer。现在,在每个自定义 UITableViewCell 中,我都有一个 UIProgressView 作为背景,拉伸以填充单元格。现在我想在 UIProgressView 上添加一个剩余时间的 UILabel。但是由于进度条填充颜色和背景颜色有很大不同(海军蓝色进度填充和白色背景/未填充区域),我想知道如何在进度条填充时动态更改文本颜色。就像 UILabel 的海军蓝色填充部分一样,文本颜色应该是白色的。白色背景上的部分,文本应该是黑色的。 Something like this, but in objective-c.

【问题讨论】:

    标签: ios objective-c uitableview uilabel uiprogressview


    【解决方案1】:

    刚刚为你解决了这个问题:)

    结果

    这是 ZWProgressView 的模拟器结果:

    视图控制器文件

    这是一个示例用法:

    #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
    

    ZWProgressView 类

    注意:屏蔽代码取自:

    Simply mask a UIView with a rectangle

    头文件

    #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
    

    实现文件

    #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
    

    【讨论】:

    • @Zhang 这真的很酷。我拿走了你的代码(我给了你原始代码的功劳)并向它添加了一些功能。 Here it is on GitHub
    【解决方案2】:

    您可以使用两个 UILabel 轻松完成此操作,一个在前面带有文本颜色,另一个在后面带有文本颜色。它们应该正好在彼此之上。然后,您可以根据计时器缩小顶部标签的宽度,底部的标签将开始显示。这应该会给您想要的效果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-14
      相关资源
      最近更新 更多