Вместо того, чтобы создавать какие-либо изображения вообще, я мог бы просто применить cornerRadius
как к основному виду прогресса, так и к виду, который показывает прогресс.Итак, представьте следующую иерархию представлений:
Основным видом выполнения является вид сзади с белыми рамками.У него есть подпредставление, progressSubview
(выделено синим цветом выше), которое показывает прогресс на данный момент (и изменится, когда мы обновим свойство progress
).А зеленый и синий виды просто подпредставлений фиксированного размера progressSubview
, которые отображаются как progressSubview
, который обрезает свои подпредставления, меняет размер.
Применение радиусов углов очень просто.И, избегая любых изображений или пользовательских drawRect
, мы можем анимировать изменения progressSubview
, если мы хотим:
Например
// CustomProgressView.h
@import UIKit;
NS_ASSUME_NONNULL_BEGIN
IB_DESIGNABLE
@interface CustomProgressView : UIView
@property (nonatomic) CGFloat progress;
@end
NS_ASSUME_NONNULL_END
И
// CustomProgressView.m
#import "CustomProgressView.h"
@interface CustomProgressView ()
@property (nonatomic, weak) UIView *progressSubview;
@property (nonatomic, weak) UIView *greenView;
@property (nonatomic, weak) UIView *redView;
@end
@implementation CustomProgressView
- (instancetype)init {
return [self initWithFrame:CGRectZero];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
[self configure];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
[self configure];
}
return self;
}
- (void)configure {
UIView *subview = [[UIView alloc] init];
subview.backgroundColor = [UIColor clearColor];
subview.clipsToBounds = true;
self.layer.borderColor = [[UIColor whiteColor] CGColor];
self.layer.borderWidth = 1;
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
self.redView = redView;
UIView *greenView = [[UIView alloc] init];
greenView.backgroundColor = [UIColor greenColor];
self.greenView = greenView;
[self addSubview:subview];
[subview addSubview:redView];
[subview addSubview:greenView];
self.progressSubview = subview;
}
- (void)layoutSubviews {
[super layoutSubviews];
self.layer.cornerRadius = MIN(self.bounds.size.height, self.bounds.size.width) / (CGFloat)2.0;
self.progressSubview.layer.cornerRadius = MIN(self.bounds.size.height, self.bounds.size.width) / (CGFloat)2.0;
[self updateProgressSubview];
self.redView.frame = self.bounds;
CGRect rect = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.origin.x + self.bounds.size.width / 2.0, self.bounds.origin.y + self.bounds.size.height);
self.greenView.frame = rect;
}
- (void)setProgress:(CGFloat)progress {
_progress = progress;
[self updateProgressSubview];
}
- (void)updateProgressSubview {
CGRect rect = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.origin.x + self.bounds.size.width * self.progress, self.bounds.origin.y + self.bounds.size.height);
self.progressSubview.frame = rect;
}
- (void)prepareForInterfaceBuilder {
[super prepareForInterfaceBuilder];
self.progress = 0.75;
}
@end
Затем вы можете обновить прогресс следующим образом:
[UIView animateWithDuration:0.25 animations:^{
self.progressView.progress = 0.75;
}];
... Я получаю свойство «прогресс» ненайдено в объекте типа 'UIView *' семантическое предупреждение
Может показаться, что ваш IBOutlet
определен как UIView
, а не CustomProgressView
.