2016-05-14 9 views
5

Ich habe das folgende Stück Code nur bestimmte Ecken Blick abzurunden:Runde bestimmte Ecken und zeigen Schatten auf bestimmte Seiten nur

- (void)roundOnlySpecifiedCornersInView:(UIView *)view corners:(UIRectCorner)corners 
{ 
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:(corners) cornerRadii:CGSizeMake(4.0, 4.0)]; 
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; 

    maskLayer.path = maskPath.CGPath; 
    view.layer.mask = maskLayer; 
} 

Das funktioniert perfekt isoliert. Jetzt möchte ich auch Schatten meiner Meinung nach, aber ich möchte speziell Schatten in verschiedenen Fällen anzuwenden:

  • auf allen Seiten
  • alle Seiten mit Ausnahme Boden
  • allen Seiten mit Ausnahme oben
  • links/rechts Seiten nur

Alle Techniken, die ich vorfand, arbeiten, indem ich einen Einsatz der Ansicht erstelle. Das Problem dabei ist, dass Sie, wenn Sie nur Schatten auf der linken/rechten Seite behalten möchten, den unteren und oberen Rand verschieben. Da das Rect jetzt weniger hoch ist, deckt der Schatten links und rechts nicht die gesamte Höhe der Ansicht ab. Die Maskenebene, die zum Abrunden der Ecken verwendet wird, bewirkt, dass der Schatten nicht mehr erscheint.

Beispielcode für diese:

innerView.layer.shadowColor = [[UIColor colorWithWhite:0.0f alpha:0.1f] CGColor]; 
    innerView.layer.shadowOpacity = 1.0f; 
    innerView.layer.shadowOffset = CGSizeMake(0.0f, 0.0f); 
    innerView.layer.shadowRadius = 6.0f; 

    CGRect shadowFrame = UIEdgeInsetsInsetRect(innerView.bounds, UIEdgeInsetsMake(9, 0, 9, 0)); 
    CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:shadowFrame].CGPath; 

    innerView.layer.shadowPath = shadowPath; 

Wie kann ich bestimmte Ecken in einer Ansicht abzurunden und gleichzeitig zeigen Schattenzeit nur zu bestimmten Seiten?

Antworten in Swift werden auch geschätzt!

Screenshots von dem, was ich will (dies ist einfach, da alle Ecken abgerundet werden müssen, so kann ich .layer.cornerRadius verwenden und es hat auf allen Seiten Schatten): enter image description here

Jetzt will ich runde gerade nur 2 von die Ecken (oben links und oben rechts, unten links und unten rechts) und fügen nur einigen Seiten Schatten hinzu.

+0

Können Sie Screenshots von dem zeigen, was Sie haben/wollen? – jtbandes

+0

http://stackoverflow.com/questions/22679886/how-to-make-a-uiview-with-optional-rounded-corners-and-border/22680538#22680538 –

+0

@KiritModi Sie beziehen sich auf die exakt gleichen Code I schon für abgerundete Ecken. – edwardmp

Antwort

3

Ich bin mir nicht sicher, ob es Ihre Nachfrage erfüllt. Der Code erstellt ein Bild mit oberem und unterem Schatten, und an jeder runden Ecke können Sie den Code ändern, um das zu erreichen, was Sie brauchen. Sie können das Bild als Hintergrund Ihrer Zelle verwenden (es scheint, dass es UITableViewCell ist)

Lassen Sie mich wissen, wenn es für Sie nicht funktioniert.

Das Bild:

enter image description here

// create a shadow image 
CGSize size = CGSizeMake(ScreenWidth, ScreenWidth); 
UIGraphicsBeginImageContextWithOptions(size, NO, 0); 
CGContextRef context = UIGraphicsGetCurrentContext(); 

UIColor *backgroundColor = [UIColor colorWithRed:246.0/255.0 green:246.0/255.0 blue:246.0/255.0 alpha:1.0]; 
UIColor *fillColor = [UIColor whiteColor]; 
CGRect rect = CGRectMake(10, 10, 100, 44); 

// re-draw the background 
CGContextSetFillColorWithColor(context, backgroundColor.CGColor); 
CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height)); 

// set top and bottom shadow 
CGRect rectTop = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, 5); 
CGContextSaveGState(context); 
CGContextSetShadowWithColor(context, CGSizeMake(0, -5), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor); 
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor); 
CGContextFillRect(context, rectTop); 
CGContextRestoreGState(context); 

CGRect rectBottom = CGRectMake(rect.origin.x, rect.origin.y+rect.size.height-5, rect.size.width, 5); 
CGContextSaveGState(context); 
CGContextSetShadowWithColor(context, CGSizeMake(0, 5), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor); 
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor); 
CGContextFillRect(context, rectBottom); 
CGContextRestoreGState(context); 

// re-draw the background 
CGContextSetFillColorWithColor(context, backgroundColor.CGColor); 
CGContextFillRect(context, rect); 

CGContextSaveGState(context); 
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(4.0, 4.0)]; 
[maskPath addClip]; 
CGContextSetFillColorWithColor(context, fillColor.CGColor); 
CGContextFillRect(context, rect); 
CGContextRestoreGState(context); 

Sie den Code ändern können oben links Schatten zu bekommen:

enter image description here

// create a shadow image 
CGSize size = CGSizeMake(ScreenWidth, ScreenWidth); 
UIGraphicsBeginImageContextWithOptions(size, NO, 0); 
CGContextRef context = UIGraphicsGetCurrentContext(); 

UIColor *backgroundColor = [UIColor colorWithRed:246.0/255.0 green:246.0/255.0 blue:246.0/255.0 alpha:1.0]; 
UIColor *fillColor = [UIColor whiteColor]; 
CGRect rect = CGRectMake(10, 10, 100, 44); 

// re-draw the background 
CGContextSetFillColorWithColor(context, backgroundColor.CGColor); 
CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height)); 

// set top and left shadow 
CGRect rectTop = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, 5); 
CGContextSaveGState(context); 
CGContextSetShadowWithColor(context, CGSizeMake(0, -5), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor); 
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor); 
CGContextFillRect(context, rectTop); 
CGContextRestoreGState(context); 

CGRect rectLeft = CGRectMake(rect.origin.x, rect.origin.y, 5, rect.size.height); 
CGContextSaveGState(context); 
CGContextSetShadowWithColor(context, CGSizeMake(-5, 0), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor); 
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor); 
CGContextFillRect(context, rectLeft); 
CGContextRestoreGState(context); 

// re-draw the background 
CGContextSetFillColorWithColor(context, backgroundColor.CGColor); 
CGContextFillRect(context, rect); 

CGContextSaveGState(context); 
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(4.0, 4.0)]; 
[maskPath addClip]; 
CGContextSetFillColorWithColor(context, fillColor.CGColor); 
CGContextFillRect(context, rect); 
CGContextRestoreGState(context); 

HTH

+0

Danke für Ihre Antwort. Für die Schatten vermisse ich nur Schatten links und rechts, aber ich denke, ich kann es aus deinen Antworten ableiten. – edwardmp

-1

für spezifische Eckgarnitur Eckenradius

beziehen von: how to set cornerRadius for only top-left and top-right corner of a UIView?

UIBezierPath *maskPath; 
maskPath = [UIBezierPathbezierPathWithRoundedRect:_backgroundImageView.bounds 
          byRoundingCorners:(UIRectCornerBottomLeft|UIRectCornerBottomRight) 
            cornerRadii:CGSizeMake(3.0, 3.0)]; 

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; 
maskLayer.frame = self.bounds; 
maskLayer.path = maskPath.CGPath; 
_imageView.layer.mask = maskLayer; 
[maskLayer release]; 
+0

Ihr Code ist praktisch der gleiche wie der Code, den ich in meinem ersten Post gegeben habe (gleicher Block) – edwardmp

1

In vielen, möchten viele Fälle Sie dies erreichen, mit dem Schatten, natürlich zeichnen.Sie können jedoch den folgenden Ansatz in Erwägung ziehen: Verwenden Sie ein streckbares Bild mit dem Schatten nur auf den Seiten, die Sie benötigen, z. etwas Ähnliches (dieser hat Schatten auf allen Seiten though):

enter image description here

Kurz bevor Sie sagen: „Ewwwww Er ist ein Bild für einen einfachen Schatten mit“ lassen Sie mich betonen, dass dies funktionieren wird viel besser in Bezug auf die Leistung. Wenn Sie zum Beispiel viele Zellen in einem UICollectionView haben und jeder seinen Schatten neu zeichnet, kann dies Ihre App beim Scrollen erheblich verlangsamen, während sie bei einem bildbasierten Schatten im Wesentlichen gleich ist.

Ich würde sogar noch weiter gehen und vorschlagen, dass Sie tatsächlich ein dehnbares Bild für verwenden könnten, um die Ansicht mit abgerundeten Ecken zu maskieren, auch! Nun, das sieht vielleicht etwas zu weit aus, aber wenn Sie einen drastischen Leistungsabfall bemerken, würde ich es versuchen. Was Sie im Wesentlichen tun müssen, ist ein anderes dehnbares Bild mit einem transparenten "mittleren" Teil und abgerundeten Ecken der gleichen Farbe wie Ihr Hintergrund vorzubereiten. Etwas wie:

enter image description here

Und wieder, bevor Sie diese downvote bizarre Weise etwas zu tun, die sich leicht mit zwei Zeilen Code erreicht werden kann ...

view.layer.cornerRadius = 20 
view.layer.masksToBounds = true 

... Lassen Sie mich Punkt heraus, dass dies funktioniert lächerlich schneller in Fällen, wenn Sie eine Reihe dieser maskierten Ansichten gleichzeitig anzeigen müssen: zum Beispiel, Maskierung UICollectionViewCell s. Grundsätzlich, wenn Sie eine Maske auf eine UIView Ebene setzen, wird diese Maske neu berechnet und in Echtzeit angewendet, was Sie beim häufigen Neuzeichnen der UIView Inhalte in Bezug auf die Leistung sehr kosten würde - beim Scrollen a UITableView oder UICollectionView, zum Beispiel.

Offensichtlich würde dies nicht funktionieren, wenn Ihr Hintergrund nicht von einer Volltonfarbe ist und einen Gradienten zum Beispiel hat. In vielen anderen Fällen kann dies jedoch helfen, die Leistung der Benutzeroberfläche zu verbessern. Ein weiterer Vorteil in Ihrem speziellen Fall ist, dass Sie leicht steuern können, welche Ecken Sie maskieren und wo der Schatten fallen soll.

Noch einmal, Ich unterstelle nicht, dass dies der Weg ist, in jedem Fall zu gehen. Was ich sagen möchte, ist, dass es viele Fälle gibt, in denen dies die Leistung erheblich steigern könnte: zum Beispiel, wenn Sie zu viele Ansichten maskieren, die gleichzeitig auf dem Bildschirm gerendert werden und das Layout dies erwartet oft neu gezeichnet werden.