如何在iOS中如下图所示制作量规视图?

时间:2019-03-26 12:29:39

标签: ios objective-c swift iphone gauge

我看过像gaugekit这样的库,但是它们不能解决我的问题。 是否还有其他用于制作标尺视图的库,如图所示? 如果没有,那我该如何解决?

@DonMag指出。 我试图通过在量具视图的顶部添加一个视图来对具规工具包进行更改。...但事实并非如此。

因此,我无法在实际仪表之间留出空间。

https://imgur.com/Qk1EpcV

2 个答案:

答案 0 :(得分:2)

我建议您创建自己的自定义视图,这并不困难。这就是我要怎么做。为了清楚起见,我省略了一些细节,但是您可以在评论中看到我建议的解决方案。

首先,创建UIVew的子类。我们将需要一个属性来跟踪量规位置。这将进入您的.h文件。

@interface GaugeView : UIView

@property (nonatomic) CGFloat knobPosition;

@end

接下来,添加实现。 GaugeView本身就是一个视图,因此它将用作我们想要的其他零件的容器。我已经使用awakeFromNib函数进行了初始化,因此您可以在Storyboard中将类用于UIView。如果愿意,还可以通过init函数进行初始化。

我没有在中间提供旋钮的代码,但是我建议您简单地创建一个带有白色光盘的视图(或两个以创建灰色圆圈),并在其中放置文本部分的标签。使用灰色指针添加图像视图。可以通过旋转变换来移动指针。

- (void)awakeFromNib {
    [super awakeFromNib];

    // Initialization part could also be placed in init
    [self createSegmentLayers];

    // Add knob views to self
    // :

    // Start somewhere
    self.knobPosition = 0.7;
}

接下来,创建细分。此处未添加实际形状,因为它们将需要视图的大小。最好将其推迟到layoutSubviews

- (void)createSegmentLayers {
    for (NSInteger segment = 0; segment < 10; ++segment) {
        // Create the shape layer and set fixed properties
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];

        // Color can be set differently for each segment
        shapeLayer.strokeColor = [UIColor blueColor].CGColor;
        shapeLayer.lineWidth = 1.0;

        [self.layer addSublayer:shapeLayer];
    }
}

接下来,我们需要响应视图的大小更改。这也是我们创建实际形状的地方。

- (void)layoutSubviews {
    [super layoutSubviews];

    // Dynamically create the segment paths and scale them to the current view width
    NSInteger segment = 0;
    for (CAShapeLayer *layer in self.layer.sublayers) {
        layer.frame = self.layer.bounds;
        layer.path = [self createSegmentPath:segment radius:self.bounds.size.width / 2.0].CGPath;

        // If we should fill or not depends on the knob position
        // Since the knobPosition's range is 0.0..1.0 we can just multiply by 10
        // and compare to the segment number
        layer.fillColor = segment < (_knobPosition * 10) ? layer.strokeColor : nil;

        // Assume we added the segment layers first
        if (++segment >= 10)
            break;
    }

    // Move and size knob images
    // :
}

然后我们需要形状。

- (UIBezierPath *)createSegmentPath:(NSInteger)segment radius:(CGFloat)radius {
    UIBezierPath *path = [UIBezierPath bezierPath];

    // We could also use a table with start and end angles for different segment sizes
    CGFloat startAngle = segment * 21.0 + 180.0 - 12.0;
    CGFloat endAngle = startAngle + 15.0;

    // Draw the path, two arcs and two implicit lines
    [path addArcWithCenter:CGPointMake(radius, radius) radius:0.9 * radius startAngle:DEG2RAD(startAngle) endAngle:DEG2RAD(endAngle) clockwise:YES];
    [path addArcWithCenter:CGPointMake(radius, radius) radius:0.75 * radius startAngle:DEG2RAD(endAngle) endAngle:DEG2RAD(startAngle) clockwise:NO];
    [path closePath];

    return path;
}

最后,我们要响应对knobPosition属性的更改。呼叫setNeedsLayout将触发对layoutSubviews的呼叫。

// Position is 0.0 .. 1.0
- (void)setKnobPosition:(CGFloat)knobPosition {
    // Rotate the knob image to point at the right segment
    // self.knobPointerImageView.transform = CGAffineTransformMakeRotation(DEG2RAD(knobPosition * 207.0 + 180.0));

    _knobPosition = knobPosition;
    [self setNeedsLayout];
}

这就是现在的样子。添加旋钮,一些颜色以及可能不同大小的片段,就可以完成!

enter image description here

答案 1 :(得分:1)

基于图像,我看到最简单的解决方案可能是创建12张图像,然后随着图像所代表的值的增大或缩小,以编程方式交换图像。