2013-03-26 14 views
10

Ho bisogno di sapere come posso ridimensionare o aumentare CGPath in modo che possa adattarsi a UIView?Scala CGPath per adattarsi UIVIew

impostare il colore di sfondo al giallo, per vedere la vista chiaramente

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

Disegna 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]; 

Allora ottengo questo: enter image description here

Quello che voglio è questo: enter image description here

Grazie sviluppatori :)

+0

Come si ottiene il percorso nel primo posto? A seconda di come viene impostato il percorso, potrebbe essere una semplice impostazione il 'frame' sul tuo livello forma. – DBD

+0

@DBD Ho usato questa classe, [link] (https://github.com/arielelkin/PocketSVG) – MAMN84

risposta

25

Suppongo che tu voglia riempire completamente (senza distorcere) la forma per adattarla alla vista. Suppongo anche che tu abbia già un livello forma con il percorso, poiché la domanda è contrassegnata da CAShapeLayer.


In questo caso si otterrebbe il rettangolo di selezione del percorso di livelli forma e calcolare il fattore di scala opportuno applicare al percorso.

A seconda delle proporzioni della forma e della vista che si suppone che si adatti, saranno le larghezze o le altezze che determinano il fattore di scala.

Una volta ottenuto il fattore di scala, verrà creata una trasformazione da applicare al percorso. Poiché il percorso non può iniziare in (0,0), anche tu traduci (muovi) il percorso nella trasformazione verso l'origine delle caselle di delimitazione.

Se si desidera che il nuovo percorso si trovi al centro della vista, è necessario calcolare quanto spostarlo. Puoi commentare quel codice se non ne hai bisogno, ma l'ho incluso anche per altre persone che stanno leggendo questa risposta.

Finalmente hai un nuovo percorso, quindi tutto ciò che devi fare è creare un nuovo livello forma, assegnare il percorso, adattarlo in modo appropriato e aggiungerlo alla vista.

// 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 

Nel mio codice di esempio (e forma) sembrava che questa versione

enter image description here

+0

Grazie, il "centro in vista" mi è stato di grande aiuto. – MAMN84

+0

Sto risolvendo un problema simile e non avevo idea che questa API esistesse su 'CGPath'. Un milione di ringraziamenti per questo! – cbowns

+0

Sei un risparmiatore di vita grazie! – dbanksdesign

0

rapida 4.0 della risposta di David Rönnqvist

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! 
    } 
Problemi correlati