Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
373 views
in Technique[技术] by (71.8m points)

ios - UILabel: background dependent color

I have tried to search for solutions for this problem, but I am not even able to put it correctly in words I guess.

Basically I have a bar that gets filled up with a color while an operation proceeds. I have a label with the progress percentage that has the same color has the fill color, so I need it to change when the fill color is on the back. Something like this:

enter image description here

Is it possible in anyway to achieve this result? And in case, how?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The easiest way is to create a UIView subclass that has a progress property and overwrites -drawRect:.

All the code you need is this:

- (void)drawRect:(CGRect)rect {

    CGContextRef context = UIGraphicsGetCurrentContext();

    // Set up environment.
    CGSize size = [self bounds].size;
    UIColor *backgroundColor = [UIColor colorWithRed:108.0/255.0 green:200.0/255.0 blue:226.0/255.0 alpha:1.0];
    UIColor *foregroundColor = [UIColor whiteColor];
    UIFont *font = [UIFont boldSystemFontOfSize:42.0];

    // Prepare progress as a string.
    NSString *progress = [NSString stringWithFormat:@"%d%%", (int)round([self progress] * 100)];
    NSMutableDictionary *attributes = [@{ NSFontAttributeName : font } mutableCopy];
    CGSize textSize = [progress sizeWithAttributes:attributes];
    CGFloat progressX = ceil([self progress] * size.width);
    CGPoint textPoint = CGPointMake(ceil((size.width - textSize.width) / 2.0), ceil((size.height - textSize.height) / 2.0));

    // Draw background + foreground text
    [backgroundColor setFill];
    CGContextFillRect(context, [self bounds]);
    attributes[NSForegroundColorAttributeName] = foregroundColor;
    [progress drawAtPoint:textPoint withAttributes:attributes];

    // Clip the drawing that follows to the remaining progress' frame.
    CGContextSaveGState(context);
    CGRect remainingProgressRect = CGRectMake(progressX, 0.0, size.width - progressX, size.height);
    CGContextAddRect(context, remainingProgressRect);
    CGContextClip(context);

    // Draw again with inverted colors.
    [foregroundColor setFill];
    CGContextFillRect(context, [self bounds]);
    attributes[NSForegroundColorAttributeName] = backgroundColor;
    [progress drawAtPoint:textPoint withAttributes:attributes];

    CGContextRestoreGState(context);
}

- (void)setProgress:(CGFloat)progress {
    _progress = fminf(1.0, fmaxf(progress, 0.0));
    [self setNeedsDisplay];
}

You can expand the class as needed with properties for background color, text color, font, etc.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...