2013-03-26 3 views
10

Ich muss wissen, wie ich CGPath herabsetzen oder herauf, damit es UIView passen kann?Maßstab CGPath zu passen UIVIew

die Hintergrundfarbe gelb Set, um die Ansicht klar

self.frame = CGRectMake(0, 0, 181, 154); 
self.backgroundColor = [UIColor yellowColor]; 

CAShapeLayer

CAShapeLayer *shape = [CAShapeLayer layer]; 
shape.path = aPath; 

shape.strokeColor = [[UIColor blueColor] CGColor]; 
shape.lineWidth = 5; 
shape.fillColor = [[UIColor clearColor] CGColor]; 

[self.layer addSublayer:shape]; 

Dann bekomme ich Draw zu sehen: enter image description here

Was ich will, ist dies: enter image description here

Vielen Dank Entwickler :)

+0

Wie beurteilen Sie den Pfad in dem ersten bekommen Ort? Abhängig davon, wie der Pfad eingerichtet ist, ist es möglicherweise einfach, den 'Rahmen' auf der Formebene festzulegen. – DBD

+0

@DBD Ich habe diese Klasse verwendet, [link] (https://github.com/arielelkin/PocketSVG) – MAMN84

Antwort

25

Ich gehe davon aus, dass Sie die Form vollständig ausfüllen (ohne zu verzerren), um die Ansicht anzupassen. Ich gehe auch davon aus, dass Sie bereits eine Formebene mit dem Pfad haben, da die Frage CAShapeLayer getaggt ist.


In diesem Fall würden Sie den Begrenzungsrahmen der Formebenen Weg zu erhalten und den entsprechenden Skalierungsfaktor berechnen, um den Weg zu beantragen.

Je nach dem Seitenverhältnis der Form und der Ansicht, die es aufnehmen soll, sind es entweder die Breiten oder die Höhen, die den Skalierungsfaktor bestimmen.

Sobald Sie den Skalierungsfaktor haben, erstellen Sie eine Transformation, die auf den Pfad angewendet wird. Da der Pfad möglicherweise nicht bei (0,0) beginnt, wird auch der Pfad in der Transformation in den Ursprung des Begrenzungsrahmens übersetzt (verschoben).

Wenn der neue Pfad in der Mitte der Ansicht sein soll, müssen Sie berechnen, wie viel er bewegt werden soll. Sie können diesen Code auskommentieren, wenn Sie ihn nicht brauchen, aber ich habe ihn für andere Personen eingefügt, die diese Antwort ebenfalls lesen.

Schließlich haben Sie einen neuen Pfad. Sie müssen lediglich eine neue Formebene erstellen, den Pfad zuweisen, ihn entsprechend formatieren und zur Ansicht hinzufügen.

// I'm assuming that the view and original shape layer is already created 
CGRect boundingBox = CGPathGetBoundingBox(shapeLayer.path); 

CGFloat boundingBoxAspectRatio = CGRectGetWidth(boundingBox)/CGRectGetHeight(boundingBox); 
CGFloat viewAspectRatio = CGRectGetWidth(viewToFitIn.frame)/CGRectGetHeight(viewToFitIn.frame); 

CGFloat scaleFactor = 1.0; 
if (boundingBoxAspectRatio > viewAspectRatio) { 
    // Width is limiting factor 
    scaleFactor = CGRectGetWidth(viewToFitIn.frame)/CGRectGetWidth(boundingBox); 
} else { 
    // Height is limiting factor 
    scaleFactor = CGRectGetHeight(viewToFitIn.frame)/CGRectGetHeight(boundingBox); 
} 


// Scaling the path ... 
CGAffineTransform scaleTransform = CGAffineTransformIdentity; 
// Scale down the path first 
scaleTransform = CGAffineTransformScale(scaleTransform, scaleFactor, scaleFactor); 
// Then translate the path to the upper left corner 
scaleTransform = CGAffineTransformTranslate(scaleTransform, -CGRectGetMinX(boundingBox), -CGRectGetMinY(boundingBox)); 

// If you want to be fancy you could also center the path in the view 
// i.e. if you don't want it to stick to the top. 
// It is done by calculating the heigth and width difference and translating 
// half the scaled value of that in both x and y (the scaled side will be 0) 
CGSize scaledSize = CGSizeApplyAffineTransform(boundingBox.size, CGAffineTransformMakeScale(scaleFactor, scaleFactor)); 
CGSize centerOffset = CGSizeMake((CGRectGetWidth(viewToFitIn.frame)-scaledSize.width)/(scaleFactor*2.0), 
           (CGRectGetHeight(viewToFitIn.frame)-scaledSize.height)/(scaleFactor*2.0)); 
scaleTransform = CGAffineTransformTranslate(scaleTransform, centerOffset.width, centerOffset.height); 
// End of "center in view" transformation code 

CGPathRef scaledPath = CGPathCreateCopyByTransformingPath(shapeLayer.path, 
                  &scaleTransform); 

// Create a new shape layer and assign the new path 
CAShapeLayer *scaledShapeLayer = [CAShapeLayer layer]; 
scaledShapeLayer.path = scaledPath; 
scaledShapeLayer.fillColor = [UIColor blueColor].CGColor; 
[viewToFitIn.layer addSublayer:scaledShapeLayer]; 

CGPathRelease(scaledPath); // release the copied path 

In meinem Beispiel-Code (und Form) sah es aus wie diese

enter image description here

+0

Vielen Dank, das "Zentrum in Sicht" hat wirklich geholfen. – MAMN84

+0

Ich löse ein ähnliches Problem und ich hatte keine Ahnung, dass diese API auf 'CGPath' existiert. Tausend Dank dafür! – cbowns

+0

Sie sind ein Lebensretter, danke! – dbanksdesign

0

swift 4.0-Version von David Rönnqvist Antwort

func resizepath(Fitin frame : CGRect , path : CGPath) -> CGPath{ 


      let boundingBox = path.boundingBox 
      let boundingBoxAspectRatio = boundingBox.width/boundingBox.height 
      let viewAspectRatio = frame.width/frame.height 
      var scaleFactor : CGFloat = 1.0 
      if (boundingBoxAspectRatio > viewAspectRatio) { 
       // Width is limiting factor 

       scaleFactor = frame.width/boundingBox.width 
      } else { 
       // Height is limiting factor 
       scaleFactor = frame.height/boundingBox.height 
      } 


      var scaleTransform = CGAffineTransform.identity 
      scaleTransform = scaleTransform.scaledBy(x: scaleFactor, y: scaleFactor) 
      scaleTransform.translatedBy(x: -boundingBox.minX, y: -boundingBox.minY) 

     let scaledSize = boundingBox.size.applying(CGAffineTransform (scaleX: scaleFactor, y: scaleFactor)) 
     let centerOffset = CGSize(width: (frame.width - scaledSize.width)/scaleFactor * 2.0, height: (frame.height - scaledSize.height)/scaleFactor * 2.0) 
     scaleTransform = scaleTransform.translatedBy(x: centerOffset.width, y: centerOffset.height) 
     //CGPathCreateCopyByTransformingPath(path, &scaleTransform) 
     let scaledPath = path.copy(using: &scaleTransform) 


     return scaledPath! 
    } 
Verwandte Themen