iOS 动画虚线矩形边框

Posted

技术标签:

【中文标题】iOS 动画虚线矩形边框【英文标题】:iOS Animate Dashed Rectangle Border 【发布时间】:2011-09-30 17:28:15 【问题描述】:

我有一个 UIImageView 显示图像。我想通过绘制圆角矩形轮廓来“突出显示”图像的一部分。我想用粗虚线绘制轮廓,通过不断改变线条“开始”的位置来“动画化”。

我想画一个具有我想要的外观的圆,然后简单地对其进行动画处理,但我真的需要一个矩形解决方案,所以就这样了。

背景:

我正在通过计算 8 个点并绘制 4 条直线和 4 条曲线来绘制圆角矩形边框。 (也许这可以更容易,但它不是损坏的部分!)

我的想法是我将使用一个“偏移”变量,它从圆角矩形的左上角开始,左上角的曲线与顶部的直线相交。然后,我将在圆角矩形的顶部增加这个“偏移量”,直到它到达右上角的曲线,然后我会将“偏移量”变量“重置”为其原始值。

这几乎可以按照我的意愿工作,直到“重置”发生。在这一点上,动画是生涩的(有点意料之中),但在恢复“向前”运动之前,它也似乎在一小部分时间内反向移动。最后,在我的虚线的开头/结尾,我在虚线上得到了一个超长的段。我知道它们不可能都是等长的(可以吗?如何计算?),但我怎样才能制作 2 个较短的段而不是 1 个较长的段?

有人知道我可以做些什么来获得平滑的“行进蚂蚁”外观吗?关于(使用动画)将用户的眼睛吸引到屏幕的特定区域的好方法的任何其他想法? (它需要围绕一个特定的区域而不遮挡它。)

当前代码:

- (void)drawRect:(CGRect)rect

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, rect);

    // Rounded corner will be 10% of average side length (i.e., (w + h) / 2)
    float averageSide = ([self HighlightRect].size.width + [self HighlightRect].size.height) / 2.0;
    float roundSize = averageSide * 0.10;

    // offset is a static, class variable
    offset += roundSize / 4.0;
    if ([WhereIAmView offset] < roundSize) 
        offset = roundSize;
    
    if ([WhereIAmView offset] > ([self HighlightRect].size.width - roundSize)) 
        offset = roundSize;
    

    // Set the "main" color of the rounded rectangle
    UIColor *lineColor = [UIColor colorWithRed:027.0/255.0 green:050.0/255.0 blue:224.0/255.0 alpha:1.0];
    CGContextSetStrokeColorWithColor(context, [lineColor CGColor]);
    CGContextSetLineWidth(context, 16.0);
    CGFloat pattern[] = 25.0, 5.0;
    CGContextSetLineDash(context, offset, pattern, 2);

    CGRect rRect = [self HighlightRect];
    // The top left corner
    CGPoint topLeft = CGPointMake(rRect.origin.x, rRect.origin.y);
    // The top right corner
    CGPoint topRight = CGPointMake(rRect.origin.x + rRect.size.width, rRect.origin.y);
    // The bottom right corner
    CGPoint bottomRight = CGPointMake(rRect.origin.x + rRect.size.width, rRect.origin.y + rRect.size.height);
    // The bottom left corner
    CGPoint bottomLeft = CGPointMake(rRect.origin.x, rRect.origin.y +     rRect.size.height);

    // The two points across the top of the rounded rectangle (left to right)
    CGPoint point1 = CGPointMake(rRect.origin.x + roundSize, rRect.origin.y);
    CGPoint point2 = CGPointMake(rRect.origin.x + rRect.size.width - roundSize, rRect.origin.y);
    // The two points along the right of the rounded rectangle (top to bottom)
    CGPoint point3 = CGPointMake(rRect.origin.x + rRect.size.width, rRect.origin.y + roundSize);
    CGPoint point4 = CGPointMake(rRect.origin.x + rRect.size.width, rRect.origin.y + rRect.size.height - roundSize);
    // The two points along the bottom of the rounded rectangle (right to left)
    CGPoint point5 = CGPointMake(rRect.origin.x + rRect.size.width - roundSize, rRect.origin.y + rRect.size.height);
    CGPoint point6 = CGPointMake(rRect.origin.x + roundSize, rRect.origin.y + rRect.size.height);
    // The two points along the left of the rounded rectangle (bottom to top)
    CGPoint point7 = CGPointMake(rRect.origin.x, rRect.origin.y + rRect.size.height - roundSize);
    CGPoint point8 = CGPointMake(rRect.origin.x, rRect.origin.y + roundSize);

    // Move to point 1
    CGContextMoveToPoint(context, point1.x, point1.y);
    // Add line to point 2 (this is the straight portion across the top)
    CGContextAddLineToPoint(context, point2.x, point2.y);
    // Add curve to point 3 (this is the rounded portion in top right)
    CGContextAddArcToPoint(context, topRight.x, topRight.y, point3.x, point3.y, roundSize);
    // Add line to point 4 (this is the straight portion across the right)
    CGContextAddLineToPoint(context, point4.x, point4.y);
    // Add curve to point 5 (this is the rounded portion in bottom right)
    CGContextAddArcToPoint(context, bottomRight.x, bottomRight.y, point5.x, point5.y, roundSize);
    // Add line to point 6 (this is the straight portion across the bottom)
    CGContextAddLineToPoint(context, point6.x, point6.y);
    // Add curve to point 7 (this is the rounded portion in bottom left)
    CGContextAddArcToPoint(context, bottomLeft.x, bottomLeft.y, point7.x, point7.y, roundSize);
    // Add line to point 8 (this is the straight portion across the left)
    CGContextAddLineToPoint(context, point8.x, point8.y);
    // Add curve to point 1 (this is the rounded portion in top left)
    CGContextAddArcToPoint(context, topLeft.x, topLeft.y, point1.x, point1.y, roundSize);

    // Stroke the path
    CGContextStrokePath(context);


撞 磕磕碰碰

【问题讨论】:

你想要圆角图像的“行军蚂蚁”效果吗?。 【参考方案1】:

尝试将 CAShapeLayer 与您的形状的 CGPath 一起使用。

圆角矩形路径可以使用 Uibezierpath 便捷方法构造。

您可以为形状图层设置线条图案。为形状图层的 line 属性设置动画将给出“marching ants like effect”。

shapeLayer = [CAShapeLayer layer];
CGRect shapeRect = CGRectMake(0.0f, 0.0f, 200.0f, 100.0f);
[shapeLayer setBounds:shapeRect];
[shapeLayer setPosition:CGPointMake(160.0f, 140.0f)];
[shapeLayer setFillColor:[[UIColor clearColor] CGColor]];
[shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]];
[shapeLayer setLineWidth:1.0f];
[shapeLayer setLineJoin:kCALineJoinRound];
[shapeLayer setLineDashPattern:
 [NSArray arrayWithObjects:[NSNumber numberWithInt:10], 
  [NSNumber numberWithInt:5], 
  nil]];
  UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:shapeRect cornerRadius:15.0];
[shapeLayer setPath:path.CGPath];
[[imageview layer] addSublayer:shapeLayer];

动画功能可以,

- (void)toggleMarching
  
if ([shapeLayer animationForKey:@"linePhase"])
    [shapeLayer removeAnimationForKey:@"linePhase"];
else 
    CABasicAnimation *dashAnimation;
    dashAnimation = [CABasicAnimation 
                     animationWithKeyPath:@"lineDashPhase"];

    [dashAnimation setFromValue:[NSNumber numberWithFloat:0.0f]];
    [dashAnimation setToValue:[NSNumber numberWithFloat:15.0f]];
    [dashAnimation setDuration:0.75f];
    [dashAnimation setRepeatCount:10000];

    [shapeLayer addAnimation:dashAnimation forKey:@"linePhase"];


  

【讨论】:

男孩!该代码看起来很熟悉,cimgf.com/2009/10/20/marching-ants-with-core-animation。归因肯定会很好。 @Matt 实际上,我确实打算通过说“像行进蚂蚁一样的效果”来给出归属,并为其提供链接。但是,可惜链接丢失了。我已编辑。顺便谢谢! 嗨,马特,我正在尝试将“行军蚂蚁效果”代码调整到 Mac,但没有成功。有什么建议吗?非常感谢!

以上是关于iOS 动画虚线矩形边框的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用 SVG 矩形作为具有可变高度的 HTML 元素的边框

iOS:带边框的圆角矩形颜色

IOS / Objective-C:矩形的圆顶角不擦除边框

CSS(下)

逐渐在iOS中添加矩形动画

使用 java.awt.BasicStroke 动画虚线