3 Stimmen

Verwirrt über UIBezierPath + applyTransform + CGPath

Ich skaliere UIBezierPath (bestehend aus einem [0,0 - 1x1] Rect) um den Faktor 2 in x- und y-Richtung. UIBezierPath ".bounds" ist in Ordnung (d.h. skaliert wie erwartet), während ".CGPath" unverändert bleibt...

コードです。

#import <UIKit/UIKit.h>

int main(int argc, char *argv[])
{
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0,
                                                                     1, 1)];
    NSLog(@"path.bounds box before transform:%@",
          NSStringFromCGRect(path.bounds));
    NSLog(@"path.CGPath box before transform:%@",
          NSStringFromCGRect(CGPathGetBoundingBox(path.CGPath)));

    [path applyTransform:CGAffineTransformMakeScale(2, 2)];

    NSLog(@"path.bounds box after transform:%@",
          NSStringFromCGRect(path.bounds));
    NSLog(@"path.CGPath box after transform:%@",
          NSStringFromCGRect(CGPathGetBoundingBox(path.CGPath)));

    return 0;        
}

Ausgabe:

path.bounds box before transform:{{0, 0}, {1, 1}}
path.CGPath box before transform:{{0, 0}, {1, 1}}
path.bounds box after transform:{{0, 0}, {2, 2}}
path.CGPath box after transform:{{0, 0}, {1, 1}}

Warum?

7voto

Dafydd Williams Punkte 1222

Ab iOS 5.1 wird die CGPath zurückgegeben von UIBezier 's .CGPath Eigenschaft wird tatsächlich aktualisiert, wenn die UIBezierPath wird eine neue Transformation angewendet.

Dies schließt jedoch eine Lösung für ältere iOS-Versionen nicht aus. Sie können die CGPath von der UIBezierPath direkt transformieren und dann wieder auf die UIBezierPath . Und siehe da, alle anderen Eigenschaften, wie Grenzen und Ursprünge, werden korrekt und sofort aktualisiert.

UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(0.0f, 0.0f,
                                                                 1.0f, 1.0f)];

CGAffineTransform transform = CGAffineTransformMakeScale(2.0f, 2.0f);
CGPathRef intermediatePath = CGPathCreateCopyByTransformingPath(path.CGPath,
                                                                &transform);

path.CGPath = intermediatePath;

CGPathRelease(intermediatePath);

4voto

Kurt Arnlund Punkte 319

Der Grund für diesen Unterschied ist, dass der Aufruf von applyTransform einfach die Transformationsmatrix im Pfadobjekt speichert. Der Pfad selbst wird dadurch nicht verändert. path.bounds ist eine berechnete Eigenschaft, die aus der Transformation abgeleitet wird, während der Aufruf von CGPathGetBoundingBox einfach die Elemente des übergebenen CGPath-Objekts durchläuft.

Da es potenziell eine große Anzahl von Pfadelementen geben kann, wird die Speicherung der Transformationsmatrix optimiert, so dass nicht jedes Mal, wenn eine neue Matrix zugewiesen wird, alle Pfadelemente geändert werden müssen. Diese Arbeit wird nur einmal oder minimal durchgeführt, wenn nur bestimmte Eigenschaften, wie die Grenzen, des UIBezierPaths abgefragt werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X