2013-03-26 33 views
10

Tôi cần biết làm thế nào tôi có thể thu nhỏ hoặc lên CGPath để nó có thể phù hợp với UIView?Quy mô CGPath để phù hợp với UIVIew

Đặt màu nền sang màu vàng, Để xem xem rõ

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

Vẽ 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]; 

Sau đó, tôi nhận được này: : enter image description here

Những gì tôi muốn đây là enter image description here

Cảm ơn bạn Nhà phát triển :)

+0

Làm thế nào để bạn có được những con đường trong lần đầu tiên địa điểm? Tùy thuộc vào cách đường dẫn được thiết lập có thể đơn giản là thiết lập 'khung' trên lớp hình dạng của bạn. – DBD

+0

@DBD Tôi đã sử dụng lớp này, [link] (https://github.com/arielelkin/PocketSVG) – MAMN84

Trả lời

25

Tôi giả định rằng bạn muốn điền đầy đủ (không bóp méo) hình dạng để vừa với chế độ xem của bạn. Tôi cũng giả định rằng bạn có một lớp hình dạng với đường dẫn đã có, vì câu hỏi được gắn thẻ CAShapeLayer.


Trong trường hợp này, bạn sẽ nhận được hộp giới hạn của đường dẫn hình dạng và tính toán hệ số tỷ lệ thích hợp để áp dụng cho đường dẫn.

Tùy thuộc vào tỷ lệ co của hình dạng và chế độ xem được cho là vừa với nó hoặc là chiều rộng hoặc chiều cao xác định hệ số tỷ lệ.

Khi bạn có yếu tố tỷ lệ, bạn sẽ tạo một biến đổi để áp dụng cho đường dẫn. Vì đường dẫn có thể không bắt đầu tại (0,0), bạn cũng dịch (di chuyển) đường dẫn trong biến đổi sang nguồn gốc của hộp giới hạn.

Nếu bạn muốn đường dẫn mới ở chính giữa chế độ xem, bạn cần tính toán số lượng di chuyển nó. Bạn có thể nhận xét mã đó nếu bạn không cần nó nhưng tôi cũng đưa nó vào cho những người khác cũng đọc câu trả lời này.

Cuối cùng bạn có một đường dẫn mới để tất cả những gì bạn phải làm là tạo một lớp hình mới, gán đường dẫn, tạo kiểu cho nó phù hợp và thêm nó vào khung nhìn.

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

Trong mã ví dụ của tôi (và hình dạng) nó trông giống như phiên bản này

enter image description here

+0

Cảm ơn bạn, "trung tâm trong xem" thực sự đã giúp. – MAMN84

+0

Tôi đang giải quyết một vấn đề tương tự và tôi không biết API này tồn tại trên 'CGPath'. Một triệu nhờ điều này! – cbowns

+0

Bạn là người cảm ơn cuộc sống! – dbanksdesign

0

nhanh chóng 4.0 của câu trả lời David Rönnqvist của

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! 
    } 
Các vấn đề liên quan