如何在不改变大小和位置的情况下旋转矩形?

How to rotate a rectangle without changing its size and position?

我可以画出和上图一样的路径,但是如何让矩形的边框旋转呢? 圆形很容易旋转,但是矩形呢?该示例以 osx 编写,您还可以为 iOS 和 osx 提供此示例。谢谢

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];

    [self setWantsLayer:YES];
    self.layer.backgroundColor = [NSColor blackColor].CGColor;
    // Drawing code here.
    //NSBezierPath *path = [NSBezierPath bezierPathWithRect:NSMakeRect(10, 10, self.frame.size.width -20, self.frame.size.height -20)];

    [self round];

    NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(10, 10, self.frame.size.width -20, self.frame.size.height -20) xRadius:2 yRadius:2];



    shapeLayer = [CAShapeLayer layer];
    shapeLayer.lineWidth = 2;
    shapeLayer.fillColor = [NSColor clearColor].CGColor;
    shapeLayer.strokeColor = [NSColor redColor].CGColor;

    shapeLayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:10],
                                  [NSNumber numberWithInt:5],nil];
    shapeLayer.path = [self copyQuartzPathFromNSBezierPath:path];

    [self.layer addSublayer:shapeLayer];

}

- (void)round
{


    [CATransaction begin];


    CABasicAnimation *rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotation.toValue = [NSNumber numberWithFloat:-M_PI*2];
    rotation.duration = 0.5f;
    rotation.repeatCount = 1;
    [CATransaction setCompletionBlock:^{
    }];
    [shapeLayer addAnimation:rotation forKey:@"rotation"];
    shapeLayer.anchorPoint = CGPointMake(0.5, 0.5);
    [CATransaction commit];

}


- (CGPathRef)copyQuartzPathFromNSBezierPath:(NSBezierPath *)bezierPath
{
    NSInteger i, numElements;

    // Need to begin a path here.
    CGPathRef           immutablePath = NULL;

    // Then draw the path elements.
    numElements = [bezierPath elementCount];
    if (numElements > 0) {
        CGMutablePathRef    path = CGPathCreateMutable();
        NSPoint             points[3];
        BOOL                didClosePath = YES;

        for (i = 0; i < numElements; i++) {
            switch ([bezierPath elementAtIndex:i associatedPoints:points]) {
                case NSMoveToBezierPathElement:
                    CGPathMoveToPoint(path, NULL, points[0].x, points[0].y);
                    break;

                case NSLineToBezierPathElement:
                    CGPathAddLineToPoint(path, NULL, points[0].x, points[0].y);
                    didClosePath = NO;
                    break;

                case NSCurveToBezierPathElement:
                    CGPathAddCurveToPoint(path, NULL, points[0].x, points[0].y,
                                          points[1].x, points[1].y,
                                          points[2].x, points[2].y);
                    didClosePath = NO;
                    break;

                case NSClosePathBezierPathElement:
                    CGPathCloseSubpath(path);
                    didClosePath = YES;
                    break;
            }
        }

        // Be sure the path is closed or Quartz may not do valid hit detection.
        if (!didClosePath) {
            CGPathCloseSubpath(path);
        }

        immutablePath = CGPathCreateCopy(path);
        CGPathRelease(path);
    }

    return immutablePath;
}

编辑 我发现一个解决方案是使用 svg 并从 Webview 加载它。 主要代码是:

<style type="text/css">
    path {
    transition:all 1s linear;
    animation-name:ring;
    animation-duration:60s;
    animation-timing-function: linear;
    animation-iteration-count:infinite;
    }
    @keyframes ring {
        from {
            stroke-dashoffset:0;
        }
        to {
            stroke-dashoffset:2000;
        }
    }
  </style>

您尝试创建的效果通常称为 "marching ants"。

我建议不要像您问题中的代码那样使用 -drawRect:,而是建议对 CAShapeLayerlineDashPhase 进行动画处理。一旦您知道要搜索什么,网上就会有大量示例和解释。例如: