2015-04-14 9 views
7

Ich bin ganz neu bei der Verwendung von UIBezierPfads zum Zeichnen von Formen. Alle Beispiele, die ich bisher gefunden habe, beinhalten zuerst das Unterklassen einer Ansicht, dann das Überschreiben der drawRect: Methode und das Zeichnen innerhalb der Zeichnung, aber ich konnte nichts finden, das mit absoluter Sicherheit sagt, ob dies die einzige Möglichkeit zum Zeichnen ist UIBezierPfads innerhalb einer UIView, oder wenn dies nur der pragmatischste Weg ist.Zeichnen UIBezierPaths in UIView ohne Unterklassen?

Gibt es einen anderen Weg (außer Swizzling), einen UIBezierPath in einer UIView zu zeichnen, ohne ihn zu untergliedern?

Antwort

15

Eine andere Möglichkeit, ohne Bézierpfade zu ziehen drawRect verwendet, ist CAShapeLayers zu verwenden. Legen Sie die Pfadeigenschaft einer Formebene auf einen CGPath fest, der aus dem Bezierpfad erstellt wurde. Fügen Sie die Formebene als Unterlayer zur Ebene Ihrer Ansicht hinzu.

UIBezierPath *shape = [UIBezierPath bezierPathWithOvalInRect:self.view.bounds]; 
    CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 
    shapeLayer.path = shape.CGPath; 
    shapeLayer.fillColor = [UIColor colorWithRed:.5 green:1 blue:.5 alpha:1].CGColor; 
    shapeLayer.strokeColor = [UIColor blackColor].CGColor; 
    shapeLayer.lineWidth = 2; 

    [self.view.layer addSublayer:shapeLayer]; 
+0

Das scheint genau das zu sein, wonach ich gesucht habe! Wünschte, ich hätte dies gestern gewusst = P Gibt es unvorhergesehene Einschränkungen oder Merkmale von UIBezierPath, die auf diese Weise nicht zugänglich sind? – n00neimp0rtant

+0

@ n00neimp0rtant Ich kenne keine bestimmten Einschränkungen, noch weiß ich, was die Speicherfolgen wären, besonders wenn Sie mehrere Ebenen haben möchten. Sie müssten ein Profiling durchführen, um es herauszufinden. – rdelmar

0

Sie könnten: 1) UIBezierPaths in Bildkontext rendern. 2) Fügen Sie UIImageView als Unteransicht Ihrer Ansicht hinzu und legen Sie die image -Eigenschaft mit dem gerenderten Bild fest. Etwas wie folgt aus:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.imageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; 
    [self.view addSubview:self.imageView]; 
    [self drawPaths]; 
} 

- (void)drawPaths { 
     UIGraphicsBeginImageContext(self.view.bounds); 
     //draw... 
     self.imageView.image = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
} 
+1

Sie würden also im Wesentlichen die Bezier-Pfad als UIImage machen, und es dann in einem UIImageView anzuzeigen ? Dies könnte in einigen Fällen möglicherweise besser als Unterklassen sein, aber es scheint ziemlich teuer zu sein, besonders wenn es neu gezeichnet wird, wenn die Größe einer Ansicht geändert wird. – n00neimp0rtant

+0

Aber die Antwort ist völlig korrekt und funktioniert. – ninjaproger

5

Swift-Version akzeptierte Antwort:

let shape = UIBezierPath(ovalInRect: view.bounds) 
    let shapeLayer = CAShapeLayer() 
    shapeLayer.path = shape.CGPath 
    shapeLayer.fillColor = UIColor(red: 0.5, green: 1, blue: 0.5, alpha: 1).CGColor 
    shapeLayer.strokeColor = UIColor.blackColor().CGColor 
    shapeLayer.lineWidth = 2.0 
    view.layer.addSublayer(shapeLayer) 
0

Swift 3 akzeptierte Antwort:

let shape = UIBezierPath(ovalIn: view.bounds) 
let shapeLayer = CAShapeLayer() 
shapeLayer.path = shape.cgPath 
shapeLayer.fillColor = UIColor(red: 0.5, green: 1, blue: 0.5, alpha: 1).cgColor 
shapeLayer.strokeColor = UIColor.black.cgColor 
shapeLayer.lineWidth = 2.0 
view.layer.addSublayer(shapeLayer)