Ich versuche, Ansichten, die übereinander liegen, einen Schlagschatten hinzuzufügen. Die Ansichten werden reduziert, sodass Inhalte in anderen Ansichten angezeigt werden können. In diesem Sinne möchte ich eingeschaltet bleiben, view.clipsToBounds
damit beim Reduzieren der Ansichten deren Inhalte abgeschnitten werden.
Dies scheint es mir schwer gemacht zu haben, den Ebenen einen Schlagschatten hinzuzufügen, da beim clipsToBounds
Einschalten auch die Schatten abgeschnitten werden.
Ich habe versucht zu manipulieren view.frame
und view.bounds
um dem Rahmen einen Schlagschatten hinzuzufügen, aber die Grenzen sollten groß genug sein, um ihn zu erfassen, aber ich hatte kein Glück damit.
Hier ist der Code, mit dem ich einen Schatten hinzufüge (dies funktioniert nur mit clipsToBounds
AUS wie gezeigt)
view.clipsToBounds = NO;
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(0,5);
view.layer.shadowOpacity = 0.5;
Hier ist ein Screenshot des Schattens, der auf die hellste graue Ebene angewendet wird. Hoffentlich gibt dies eine Vorstellung davon, wie sich mein Inhalt überschneidet, wenn clipsToBounds
AUS ist.
Wie kann ich meinem Schatten einen Schatten hinzufügen UIView
und meinen Inhalt beschneiden lassen?
Bearbeiten: Ich wollte nur hinzufügen, dass ich auch mit Hintergrundbildern mit Schatten herumgespielt habe, was gut funktioniert, aber ich würde immer noch gerne die beste codierte Lösung dafür kennen.
masksToBounds = NO;
zu meinem Original hinzuzufügen. Bei beiden Versuchen, die ichclipsToBounds = YES;
aktiviert habe, konnten beide den Inhalt nicht ausschneiden. Hier ist eine Bildschirmabdeckung dessen, was mit Ihrem Beispiel passiert istUIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds cornerRadius:5.0];
. Nicht getestet, sollte aber das gewünschte Ergebnis liefern.layoutSubviews()
wird aufgerufen. Und wenn wir dies an dieser Stelle nicht durch Anpassen dershadowPath
an die aktuelle Größe anpassen , hätten wir eine vergrößerte Ansicht, aber der Schatten würde immer noch die alte (anfängliche) Größe haben und entweder nicht anzeigen oder herausschauen, wo er nicht sollte .Wasabisis Antwort in Swift 2.3:
Und in Swift 3/4/5:
Fügen Sie diesen Code in layoutSubviews () ein, wenn Sie AutoLayout verwenden.
In SwiftUI ist das alles viel einfacher:
quelle
layoutSubviews
CGSize(width: 0, height: 0.5)
view.bounds
dassshadowPath
es nicht so offensichtlich erstellt wurde, dass ich nicht auf das Rechteck der Ansicht verweisen kann, sondern auf einigeCGRectZero
. Wie auch immer, dies unter zu setzen,layoutSubviews
löste mein Problem endlich!Der Trick besteht darin, die
masksToBounds
Eigenschaft der Ebene Ihrer Ansicht richtig zu definieren:und es sollte funktionieren.
( Quelle )
quelle
Sie können eine Erweiterung für UIView erstellen, um im Entwurfseditor auf diese Werte zuzugreifen
quelle
Sie können Ihre Ansicht auch über das Storyboard mit Schatten versehen
quelle
In viewWillLayoutSubviews:
Verwenden der UIView-Erweiterung:
Verwendung:
quelle
targetView: UIView
und entfernen Sie einfach die Pony.self
? Scheint mir viel bequemer.if let
Syntax anstelle von!
Ja, Sie sollten die Eigenschaft shadowPath für die Leistung bevorzugen, aber auch: Aus der Header-Datei von CALayer.shadowPath
Wenn Sie den Pfad explizit mit dieser Eigenschaft angeben, wird * normalerweise die Renderleistung verbessert, und es wird dieselbe Pfadreferenz * über mehrere Ebenen hinweg verwendet
Ein weniger bekannter Trick besteht darin, dieselbe Referenz über mehrere Ebenen hinweg zu teilen. Natürlich müssen sie dieselbe Form verwenden, aber dies ist bei Tabellen- / Sammlungsansichtszellen üblich.
Ich weiß nicht, warum es schneller wird, wenn Sie Instanzen freigeben. Ich vermute, es speichert das Rendering des Schattens zwischen und kann es für andere Instanzen in der Ansicht wiederverwenden. Ich frage mich, ob das mit noch schneller geht
quelle