首页 > 解决方案 > Objective-C UIImage 凹角(又名自定义进度条)

问题描述

我需要帮助在 Objective-c 中以编程方式创建此图像。凹面半径是图像高度的一半。

带圆圈的盒子被取出,而不是左侧被取出

我的目标是有一个进度条,其中左侧是图像,中间是包含视图背景颜色,右侧是可拉伸图像。

两端有上述形状的彩条


编辑

@Rob 的解决方案是要走的路。但是,我必须错误地实施它。

我创建了头文件和实现文件,并将类添加到现有的 UIView、progressBarView。CustomProgress 视图显示在 IB 中,一切看起来都很棒......

IB 示例

...但是当我尝试用...设置进度值时

self.progressBarView.progress = 0.75;

...我收到Property 'progress' not found on object of type 'UIView *'语义警告。

标签: iosobjective-cuiimage

解决方案


而不是创建任何图像,我可能只是将 acornerRadius应用于主要进度视图以及显示进度的视图。因此,想象以下视图层次结构:

在此处输入图像描述

主要的进度视图是背面的白色边框视图。它有一个子视图,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被定义为 aUIView而不是 a CustomProgressView


推荐阅读