gpt4 book ai didi

iphone - 如何制作类似于客涯应用中的进度 View

转载 作者:可可西里 更新时间:2023-11-01 06:20:50 24 4
gpt4 key购买 nike

我想知道如何制作一个看起来像KAYAK应用程序(它是一个搜索航类和酒店的旅行应用程序)中的进度 View ,截图:

enter image description here

我在越狱的 iPhone 上挖掘了 KAYAK 应用程序的资源,发现以下 3 张图像构成了这个进度 View :

进度条背景@2x.png

enter image description here

progressbar-gradient@2x.png

enter image description here

progressbar-overlay@2x.png

enter image description here

考虑到进度 View 有一个移动的叠加图像,它与渐变图像一起重复移动。

任何想法或示例代码将不胜感激。

最佳答案

我制作了整个工作包,将模仿您发布的这个进度 View 。但是,为了让它更可定制,我没有使用任何图像,而是使用 CoreGraphics 来绘制它。该软件包可以在 lightdesign/LDProgressView 找到.我也可能会把它变成 CocoaPod如果你知道那是什么。

如何绘制类似 KAYAK 的进度 View

进度 View 的所有内部工作原理以及如何模仿 KAYAK 进度 View 可以在 this file 中找到。 .为了更容易理解,我在代码块中添加了一些注释。这是drawRect方法:

- (void)drawRect:(CGRect)rect {
[self setAnimateIfNotSet];
CGContextRef context = UIGraphicsGetCurrentContext();
[self drawProgressBackground:context inRect:rect];
if (self.progress > 0) {
[self drawProgress:context withFrame:rect];
}
}

这是不言自明的。如果尚未设置 animate 属性,我会设置它并绘制背景。然后,如果进度大于 0,我将在总帧内绘制进度。让我们继续讨论 drawProgressBackground:inRect:方法:
- (void)drawProgressBackground:(CGContextRef)context inRect:(CGRect)rect {
CGContextSaveGState(context);

// Draw the background with a gray color within a rounded rectangle
UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:10];
CGContextSetFillColorWithColor(context, [UIColor colorWithRed:0.51f green:0.51f blue:0.51f alpha:1.00f].CGColor);
[roundedRect fill];

// Create the inner shadow path
UIBezierPath *roundedRectangleNegativePath = [UIBezierPath bezierPathWithRect:CGRectMake(-10, -10, rect.size.width+10, rect.size.height+10)];
[roundedRectangleNegativePath appendPath:roundedRect];
roundedRectangleNegativePath.usesEvenOddFillRule = YES;
CGSize shadowOffset = CGSizeMake(0.5, 1);
CGContextSaveGState(context);
CGFloat xOffset = shadowOffset.width + round(rect.size.width);
CGFloat yOffset = shadowOffset.height;
CGContextSetShadowWithColor(context,
CGSizeMake(xOffset + copysign(0.1, xOffset), yOffset + copysign(0.1, yOffset)), 5, [[UIColor blackColor] colorWithAlphaComponent:0.7].CGColor);

// Draw the inner shadow
[roundedRect addClip];
CGAffineTransform transform = CGAffineTransformMakeTranslation(-round(rect.size.width), 0);
[roundedRectangleNegativePath applyTransform:transform];
[[UIColor grayColor] setFill];
[roundedRectangleNegativePath fill];

CGContextRestoreGState(context);
}

在这里,我在 View 中创建了一个半径为 10 的圆角矩形。 (稍后我可能允许对其进行自定义)并填充它。然后剩下的代码是绘制内部阴影,我真的不需要详细介绍。现在,这是在方法 drawProgress:withFrame: 中绘制进度的代码:
- (void)drawProgress:(CGContextRef)context withFrame:(CGRect)frame {
CGRect rectToDrawIn = CGRectMake(0, 0, frame.size.width * self.progress, frame.size.height);
CGRect insetRect = CGRectInset(rectToDrawIn, 0.5, 0.5);

UIBezierPath *roundedRect = [UIBezierPath bezierPathWithRoundedRect:insetRect cornerRadius:10];
if ([self.flat boolValue]) {
CGContextSetFillColorWithColor(context, self.color.CGColor);
[roundedRect fill];
} else {
CGContextSaveGState(context);
[roundedRect addClip];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = {0.0, 1.0};
NSArray *colors = @[(__bridge id)[self.color lighterColor].CGColor, (__bridge id)[self.color darkerColor].CGColor];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);

CGContextDrawLinearGradient(context, gradient, CGPointMake(insetRect.size.width / 2, 0), CGPointMake(insetRect.size.width / 2, insetRect.size.height), 0);
CGContextRestoreGState(context);

CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}

CGContextSetStrokeColorWithColor(context, [[self.color darkerColor] darkerColor].CGColor);
[self drawStripes:context inRect:insetRect];
[roundedRect stroke];

[self drawRightAlignedLabelInRect:insetRect];
}

这种方法有 4 个主要部分。首先,我根据 self.progress计算进度占用的帧数。属性(property)。其次,如果 flat,我绘制纯色属性已设置,或者我绘制了一个计算梯度(方法 lighterColordarkerColor 属于 UIColor 类别)。第三,我画条纹,最后画百分比标签。让我们快速介绍这两种方法。这是 drawStripes:inRect:方法:
- (void)drawStripes:(CGContextRef)context inRect:(CGRect)rect {
CGContextSaveGState(context);
[[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:10] addClip];
CGContextSetFillColorWithColor(context, [[UIColor whiteColor] colorWithAlphaComponent:0.2].CGColor);
CGFloat xStart = self.offset, height = rect.size.height, width = STRIPE_WIDTH;
while (xStart < rect.size.width) {
CGContextSaveGState(context);
CGContextMoveToPoint(context, xStart, height);
CGContextAddLineToPoint(context, xStart + width * 0.25, 0);
CGContextAddLineToPoint(context, xStart + width * 0.75, 0);
CGContextAddLineToPoint(context, xStart + width * 0.50, height);
CGContextClosePath(context);
CGContextFillPath(context);
CGContextRestoreGState(context);
xStart += width;
}
CGContextRestoreGState(context);
}

这就是动画“魔法”发生的地方。基本上我根据 self.offset 绘制这些条纹介于 -STRIPE_WIDTH 之间和 0由计时器递增。然后,我创建了一个简单的循环,以便只创建足够的条纹来完全填充 View 的进度部分。我也留下了 STRIPE_WIDTH的25%空白,这样条纹就不会相互挤在一起。这是最终的绘制方法 drawRightAlignedLabelInRect: :
- (void)drawRightAlignedLabelInRect:(CGRect)rect {
UILabel *label = [[UILabel alloc] initWithFrame:rect];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentRight;
label.text = [NSString stringWithFormat:@"%.0f%%", self.progress*100];
label.font = [UIFont boldSystemFontOfSize:17];
UIColor *baseLabelColor = [self.color isLighterColor] ? [UIColor blackColor] : [UIColor whiteColor];
label.textColor = [baseLabelColor colorWithAlphaComponent:0.6];
[label drawTextInRect:CGRectOffset(rect, -6, 0)];
}

在这种方法中,我创建了一个带有文本的标签,该标签从浮点数(在 0.01.0 之间)转换为百分比(从 0%100% )。然后我根据所选进度颜色的深浅将颜色设置为深或浅,并在 CGContext 中绘制标签。 .

可定制性

可以直接在 LDProgressView 的实例上设置三个属性。或事先在 UIAppearance方法。
  • 颜色

  • 颜色显然会设置选择器的整体外观。渐变、条纹和/或轮廓颜色由此确定。 UIAppearance方法将是这样的:
     [[LDProgressView appearance] setColor:[UIColor colorWithRed:0.87f green:0.55f blue:0.09f alpha:1.00f]];

  • 这将决定进度 View 的背景是渐变还是只是 color属性(property)。此 UIAppearance方法看起来像这样:
    [[LDProgressView appearance] setFlat:@NO];
  • 动画

  • 最后,这将决定是否对条纹进行动画处理。此 UIAppearance也可以为 LDProgressView 的所有实例一般设置方法看起来像这样:
    [[LDProgressView appearance] setAnimate:@YES];

    结论

    哇!那是一个很长的答案。我希望我没有让你们太厌烦。如果你只是跳到这里,这里是用代码而不是图像绘制的要点。如果你有时间/经验,我认为 CoreGraphics 是一种在 iOS 上绘图的绝佳方式,因为它允许更多的自定义,而且我相信它往往会更快。

    这是最终的工作产品的图片:

    LDProgressView

    关于iphone - 如何制作类似于客涯应用中的进度 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18887142/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com