2016-04-04 7 views
3

Hier ist ein Code, der Maske auf die gesamte UIView Anwendung:Bewerben CAShapeLayer zur Haupt UIView außer UIButton

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRect:self.view.bounds]; 
[maskPath appendPath:[UIBezierPath bezierPathWithArcCenter:self.mapCardsButton.center 
                radius:self.mapCardsButton.frame.size.height/2.0f 
               startAngle:0.0f 
                endAngle:2.0f*M_PI 
               clockwise:NO]]; 
CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
maskLayer.fillRule = kCAFillRuleEvenOdd; 
maskLayer.fillColor = [UIColor blackColor].CGColor; 
maskLayer.path = maskPath.CGPath; 
self.view.layer.mask = maskLayer; 

Das Problem ist, dass ich die Maske oben auf die gesamte UIView mit Ausnahme einer bestimmten UIButton (mapCardsButton anwenden möchten) welches auch auf der gleichen UIView ist. Ist es möglich zu tun?

UPD: Ich habe versucht,

[self.view.layer insertSublayer:maskLayer atIndex:0]; 

statt

self.view.layer.mask = maskLayer; 

aber meine self.view verloren Alpha-Kanal und Animation von Maskenebene funktioniert nicht mehr

Hier ist ein Projekt mit code: https://www.dropbox.com/s/b94qcwxzoi23kwk/test_04092016.zip?dl=0

+0

[self.view.layer insertSublayer: Gradient atIndex: 0]; –

+0

Nachdem ich diesen Code hinzugefügt habe, wird meine UIView schwarz ohne Alpha und die Animation von maskLayer funktioniert nicht mehr. – Sergio

+0

Sie möchten also die Vollansicht maskieren und nur den vollständigen Schaltflächenrahmen anzeigen, wie er gerade angezeigt wird. – HardikDG

Antwort

0

Warum versuchen Sie Folgendes nicht? anstelle des folgenden Stapel:

• Maske (Ansicht) -> Taste

die Ansicht Hintergrundfarbe deutlich zu machen, gegen eine zusätzliche subview und wie folgt vorgehen:

• Ansicht -> Maske (SubView) , Button

Auf diese Weise haben Sie den gleichen visuellen Effekt, aber verwenden Sie die Ansicht von unten als Container. In Code:

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRect:self.view.bounds]; 
[maskPath appendPath:[UIBezierPath bezierPathWithArcCenter:self.mapCardsButton.center 
                radius:self.mapCardsButton.frame.size.height/2.0f 
               startAngle:0.0f 
                endAngle:2.0f*M_PI 
               clockwise:NO]]; 
CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
maskLayer.fillRule = kCAFillRuleEvenOdd; 
maskLayer.fillColor = [UIColor blackColor].CGColor; 
maskLayer.path = maskPath.CGPath; 

UIView *maskedView = [[UIView alloc] initWithFrame:self.view.bounds];  
maskedView.mask = maskLayer; 

self.view.backgroundColor = [UIColor clearColor]; 
[self.view addSubView:maskedView]; 
[self.view addSubView:self.mapCardsButton]; 
0

Der einfachste Weg wäre für die UIButton eine Geschwisteransicht der maskierten Ansicht statt einer Unteransicht. Ich realisiere, dass es logisch Sinn macht, dass die Schaltfläche eine Unteransicht ist (besonders da es so aussieht, als ob Ihr Code wahrscheinlich aus einer UIViewController Unterklasse stammt), also würde ich einen Container UIView erstellen, der alle anderen Subviews abgesehen von mapCardsButton enthält Maske zu dieser neuen Ansicht.

So sagen Sie die neue Ansicht maskedContainerView genannt, dann:

  • self.view hat zwei Subviews: maskedContainerView und mapCardsButton
  • maskedContainerView alle hält die Subviews dass self.view verwendet, mit der Ausnahme mapCardsButton
  • maskedContainerView.layer.mask = maskLayer.
+0

Vielen Dank für die Antwort. Ich habe deine Lösung versucht, aber es funktioniert immer noch nicht. Jetzt zeigt es mapCardsButton an, macht aber kein "Loch". Hier ist ein Projekt mit Code: https://www.dropbox.com/s/b94qcwxzoi23kwk/test_04092016.zip?dl=0 – Sergio

+2

Hey. Entschuldigen Sie die Verspätung. Ich habe mir deinen Code angesehen. Ich denke, alles was fehlt ist, dass das 'maskedContainerView' den Inhalt von' self.view' enthalten sollte, dh 'maskedContainerView' sollte seine Hintergrundfarbe auf die grau/blaue Hintergrundfarbe setzen, die' self.view' aktuell eingestellt ist zu. Dann sollte 'self.view' vollständig transparent sein; 'self.view.backgroundColor = [UIColor clearColor]'. – stefandouganhyde

+0

stefandouganhyde, nette Abhilfe! Ich habe über diesen Fall nachgedacht – Sergio

0

[maskedContainerView.layer insertSublayer: Maskenebene atIndex: (unsigned) maskedContainerView.layer.sublayers.count];

Die Bedeutung ist view.layer.sublayers.count nicht 0 auf 'atIndex'

success Bitte nehmen Sie es!

0

Basis auf Ihrem Code. Ich bin mir nicht sicher, ob du das willst. enter image description here

Fügen Sie einfach den UIBezierPath der Schaltfläche zu Ihrem maskPath hinzu. der Code wie diese (Base auf Ihrem Code)

const NSInteger kHoleSize = 100; 

UIButton *mapCardsButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, kHoleSize, kHoleSize)]; 
[mapCardsButton setTitle:@"BUTTON" forState:UIControlStateNormal]; 
mapCardsButton.backgroundColor = [UIColor redColor]; 

[self.view addSubview:mapCardsButton]; 



UIBezierPath *maskPath = [UIBezierPath bezierPathWithRect:self.view.bounds]; 


UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:self.view.center 
                  radius:kHoleSize/2.0f 
                 startAngle:0.0f 
                 endAngle:2.0f*M_PI 
                 clockwise:NO]; 

UIBezierPath *buttonPath = [UIBezierPath bezierPathWithRect:mapCardsButton.frame]; 
[circlePath appendPath:buttonPath]; 


[maskPath appendPath:circlePath]; 
[maskPath setUsesEvenOddFillRule:YES]; 

CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
maskLayer.path = maskPath.CGPath; 
maskLayer.fillRule = kCAFillRuleEvenOdd; 
maskLayer.fillColor = [UIColor blackColor].CGColor; 
maskLayer.opacity = 0.9; 

[self.view.layer addSublayer:maskLayer]; 
Verwandte Themen