ios - 如何在 ios 中实现 seecarc(半圆形搜索栏)?

标签 ios objective-c iphone swift

我想实现带有进度百分比的半圆形搜索栏,如下图所示。

enter image description here

最佳答案

好的。挺难的哈。但严重不是。相信我! 没有问题。只需使用下面的代码。

创建继承自 UIView 的类(例如 SgkProgressView)。

现在打开 SgkProgressView.h 并添加以下代码

#import <UIKit/UIKit.h>

@interface SgkProgressView : UIView

@property (assign, nonatomic) IBInspectable CGFloat gaugeWidth;

@property (assign, nonatomic) IBInspectable CGFloat minValue;
@property (assign, nonatomic) IBInspectable CGFloat maxValue;
@property (assign, nonatomic) IBInspectable CGFloat currentValue;

@property (strong, nonatomic) IBInspectable UIColor *baseColor;
@property (strong, nonatomic) IBInspectable UIColor *normalConditionColor;

@property (assign, nonatomic) IBInspectable BOOL enableSeeker;
@property (assign, nonatomic) IBInspectable CGFloat seekerWidth;
@property (strong, nonatomic) IBInspectable UIColor *seekerColor;

@end

现在打开SgkProgressView.m,添加如下代码

#import "SgkProgressView.h"

#define SGKDegToRad(degrees) (((degrees) / 180.0) * M_PI)
#define SGKRadToDeg(radians) (((radians) * 180.0) / M_PI)

IB_DESIGNABLE
@implementation SgkProgressView

- (void)baseInit {
    // do here initial settings. but we have already made them in IB.
}

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self baseInit];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self baseInit];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    CGFloat maxAngle = 30;
    CGFloat minAngle = 150;

    if (maxAngle <= minAngle)
        maxAngle += 360.0;

    CGFloat currentAngle = ((((_currentValue - _minValue) * (maxAngle - minAngle)) / (_maxValue - _minValue)) + minAngle);

    CGPoint center = CGPointMake(self.frame.size.width / 2.0, self.frame.size.height / 2.0);
    CGFloat basePathRadius = MIN(center.x, center.y) - (_gaugeWidth / 2.0);

    if (_enableSeeker)
        basePathRadius -= (_seekerWidth / 2.0);

    [self drawArcWithCenter:center radius:basePathRadius startAngle:minAngle endAngle:maxAngle withColor:_baseColor];

    [self drawArcWithCenter:center radius:basePathRadius startAngle:minAngle endAngle:currentAngle withColor:_normalConditionColor];

    if (_enableSeeker) {
        CGFloat x = center.x + (basePathRadius * cosf(SGKDegToRad(currentAngle)));
        CGFloat y = center.y + (basePathRadius * sinf(SGKDegToRad(currentAngle)));
        UIBezierPath *seeker = [UIBezierPath bezierPathWithArcCenter:CGPointMake(x, y) radius:(_seekerWidth / 2.0) startAngle:SGKDegToRad(0.0) endAngle:SGKDegToRad(360.0) clockwise:YES];
        [_seekerColor setFill];
        [seeker fill];
    }
}

- (void)drawArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle withColor:(UIColor *)pathColor {
    CGFloat smallArcRadius = _gaugeWidth / 2.0;

    CGFloat x = center.x + (radius * cosf(SGKDegToRad(startAngle)));
    CGFloat y = center.y + (radius * sinf(SGKDegToRad(startAngle)));
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(x, y) radius:smallArcRadius startAngle:SGKDegToRad(startAngle - 180.0) endAngle:SGKDegToRad(startAngle) clockwise:YES];
    [path addArcWithCenter:center radius:(radius + smallArcRadius) startAngle:SGKDegToRad(startAngle) endAngle:SGKDegToRad(endAngle) clockwise:YES];
    x = center.x + (radius * cosf(SGKDegToRad(endAngle)));
    y = center.y + (radius * sinf(SGKDegToRad(endAngle)));
    [path addArcWithCenter:CGPointMake(x, y) radius:smallArcRadius startAngle:SGKDegToRad(endAngle) endAngle:SGKDegToRad(endAngle + 180.0) clockwise:YES];
    [path addArcWithCenter:center radius:(radius - smallArcRadius) startAngle:SGKDegToRad(endAngle) endAngle:SGKDegToRad(startAngle) clockwise:NO];
    [path closePath];
    [pathColor setFill];
    [path fill];
}

- (void)setEnableSeeker:(BOOL)enableSeeker {
    _enableSeeker = enableSeeker;
    [self setNeedsDisplay];
}

- (void)setSeekerWidth:(CGFloat)seekerWidth {
    _seekerWidth = seekerWidth;
    [self setNeedsDisplay];
}

- (void)setCurrentValue:(CGFloat)currentValue {
    _currentValue = currentValue;
    [self setNeedsDisplay];
}

- (void)setGaugeWidth:(CGFloat)gaugeWidth {
    _gaugeWidth = gaugeWidth;
    [self setNeedsDisplay];
}

@end

现在在您的 ViewController 的 View 中,添加一个 UIView。将其自定义类设置为 SgkProgressView。现在在属性检查器中设置属性,如下所示。

enter image description here

最后你会看到如下图。

enter image description here

您以后可以更改颜色和其他属性。

关于ios - 如何在 ios 中实现 seecarc(半圆形搜索栏)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41240980/

相关文章:

ios - NSLinguisticTagger enumerateTagsInRange 在具有 NSLinguisticTagSchemeNameTypeOrLexicalClass 的设备上不起作用

ios - UIView 容器中的嵌入 TableView

iphone - 合成属性是否已经 alloc/init -ed?

iPhone 3.1 SDK : UIViewController category is affecting ALL ViewControllers

iphone - 类的全局实例

iphone - iOS4 iPhone 离线 Web 应用程序上的 HTML5 音频无法播放?

iphone - 关卡 - Cocos2d

ios - 如何在 AVFoundation 中混合/屏蔽视频?

ios - Hybrid Webview IOS 停止缩放

ios - 如果他们引用的对象被释放,守卫是否可以在使用 [weak self] 的闭包中让 `self` = self 导致崩溃?