450 Stimmen

UIView mit abgerundeten Ecken und Schlagschatten?

Ich arbeite seit ein paar Jahren an einer Anwendung und habe eine einfache Designanfrage erhalten: Runden Sie die Ecken einer UIView ab und fügen Sie einen Schlagschatten hinzu, wie unten angegeben.

Ich möchte eine individuelle UIView ... : Ich wollte nur eine leere weiße Ansicht mit abgerundeten Ecken und einem leichten Schlagschatten (ohne Lichteffekt). Ich kann jede von denen eine nach der anderen zu tun, aber die üblichen clipToBounds / maskToBounds Konflikte auftreten.

enter image description here

748voto

Suragch Punkte 420096

Schnell

enter image description here

// corner radius
blueView.layer.cornerRadius = 10

// border
blueView.layer.borderWidth = 1.0
blueView.layer.borderColor = UIColor.black.cgColor

// shadow
blueView.layer.shadowColor = UIColor.black.cgColor
blueView.layer.shadowOffset = CGSize(width: 3, height: 3)
blueView.layer.shadowOpacity = 0.7
blueView.layer.shadowRadius = 4.0

Sondierung der Optionen

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

Problem 1: Schatten wird abgeschnitten

Was ist, wenn es Unterebenen oder Unteransichten (wie ein Bild) gibt, deren Inhalt wir auf die Grenzen unserer Ansicht beschränken wollen?

enter image description here

Wir können dies erreichen mit

blueView.layer.masksToBounds = true

(Alternativ dazu, blueView.clipsToBounds = true gibt die dasselbe Ergebnis .)

enter image description here

Aber, Oh nein! Der Schatten wurde auch abgeschnitten, weil er außerhalb der Grenzen liegt! Was ist zu tun? Was ist zu tun?

Lösung

Verwenden Sie separate Ansichten für den Schatten und den Rand. Die Basisansicht ist transparent und enthält den Schatten. Die Ansicht "Rand" klammert jeden anderen Unterinhalt, den sie hat, an ihren Rand.

// add the shadow to the base view
baseView.backgroundColor = UIColor.clear
baseView.layer.shadowColor = UIColor.black.cgColor
baseView.layer.shadowOffset = CGSize(width: 3, height: 3)
baseView.layer.shadowOpacity = 0.7
baseView.layer.shadowRadius = 4.0

// add the border to subview
let borderView = UIView()
borderView.frame = baseView.bounds
borderView.layer.cornerRadius = 10
borderView.layer.borderColor = UIColor.black.cgColor
borderView.layer.borderWidth = 1.0
borderView.layer.masksToBounds = true
baseView.addSubview(borderView)

// add any other subcontent that you want clipped
let otherSubContent = UIImageView()
otherSubContent.image = UIImage(named: "lion")
otherSubContent.frame = borderView.bounds
borderView.addSubview(otherSubContent)

Daraus ergibt sich das folgende Ergebnis:

enter image description here

Problem 2: Schlechte Leistung

Das Hinzufügen von abgerundeten Ecken und Schatten kann ein Leistungsschub sein. Sie können die Leistung verbessern, indem Sie einen vordefinierten Pfad für den Schatten verwenden und außerdem angeben, dass er gerastert werden soll. Der folgende Code kann dem obigen Beispiel hinzugefügt werden.

baseView.layer.shadowPath = UIBezierPath(roundedRect: baseView.bounds, cornerRadius: 10).cgPath
baseView.layer.shouldRasterize = true
baseView.layer.rasterizationScale = UIScreen.main.scale

Voir diese Stelle für weitere Einzelheiten. Siehe aquí y aquí auch.

Diese Antwort wurde mit Swift 4 und Xcode 9 getestet.

464voto

Evan Mulawski Punkte 53325

Der folgende Codeschnipsel fügt einen Rahmen, einen Rahmenradius und einen Schlagschatten zu v , a UIView :

// border radius
[v.layer setCornerRadius:30.0f];

// border
[v.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[v.layer setBorderWidth:1.5f];

// drop shadow
[v.layer setShadowColor:[UIColor blackColor].CGColor];
[v.layer setShadowOpacity:0.8];
[v.layer setShadowRadius:3.0];
[v.layer setShadowOffset:CGSizeMake(2.0, 2.0)];

Swift 5 Version :

// border radius
v.layer.cornerRadius = 30.0

// border
v.layer.borderColor = UIColor.lightGray.cgColor
v.layer.borderWidth = 1.5

// drop shadow
v.layer.shadowColor = UIColor.black.cgColor
v.layer.shadowOpacity = 0.8
v.layer.shadowRadius = 3.0
v.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)

Sie können die Einstellungen an Ihre Bedürfnisse anpassen.

Fügen Sie außerdem das QuartzCore-Framework zu Ihrem Projekt hinzu und:

#import <QuartzCore/QuartzCore.h>

Voir meine andere Antwort zu masksToBounds .


Nota

Dies funktioniert möglicherweise nicht in allen Fällen. Wenn Sie feststellen, dass diese Methode andere Zeichenvorgänge beeinträchtigt, lesen Sie bitte diese Antwort .

102voto

Sergey Grischyov Punkte 11929

Überprüfen Sie die Beispielprojekt auf GitHub um sicherzustellen, dass Sie die Komponente richtig verwenden.

Einfache Swift 5-Lösung ohne zusätzliche Unteransichten oder Unterklassen:

extension UIView {

    func addShadow(offset: CGSize, color: UIColor, radius: CGFloat, opacity: Float) {
        layer.masksToBounds = false
        layer.shadowOffset = offset
        layer.shadowColor = color.cgColor
        layer.shadowRadius = radius
        layer.shadowOpacity = opacity

        let backgroundCGColor = backgroundColor?.cgColor
        backgroundColor = nil
        layer.backgroundColor =  backgroundCGColor
    }
}

Beachten Sie, dass Sie Ihre Ansicht mit Eckradius und anderen Eigenschaften einrichten sollten vor dem Aufruf addShadow .

Danach rufen Sie dies einfach von viewDidLoad wie diese:

button.addShadow(offset: CGSize.init(width: 0, height: 3), color: UIColor.black, radius: 2.0, opacity: 0.35)

Endgültiges Ergebnis:

result

Superleicht und einfach!

79voto

David C. Punkte 817

Eine Möglichkeit besteht darin, die Ansicht mit den abgerundeten Ecken in eine Ansicht mit dem Schlagschatten zu setzen.

UIView* roundedView = [[UIView alloc] initWithFrame: frame];
roundedView.layer.cornerRadius = 5.0;
roundedView.layer.masksToBounds = YES;

UIView* shadowView = [[UIView alloc] initWithFrame: frame];
shadowView.layer.shadowColor = [UIColor blackColor].CGColor;
shadowView.layer.shadowRadius = 5.0;
shadowView.layer.shadowOffset = CGSizeMake(3.0, 3.0);
shadowView.layer.shadowOpacity = 1.0;
[shadowView addSubview: roundedView];

Dann können Sie die Schattenansicht an beliebiger Stelle einfügen.

43voto

Ade Punkte 631

Das hat bei mir funktioniert. Der Trick war, die Hintergrundfarbe von der Hauptansicht auf die Ebene zu verschieben.

CALayer *layer = view.layer;
layer.cornerRadius = 15.0f;
layer.masksToBounds = NO;

layer.shadowOffset = CGSizeMake(0, 3);
layer.shadowColor = [[UIColor blackColor] CGColor];
layer.shadowRadius = 2.0f;
layer.shadowOpacity = 0.35f;
layer.shadowPath = [[UIBezierPath bezierPathWithRoundedRect:layer.bounds cornerRadius:layer.cornerRadius] CGPath];

CGColorRef  bColor = view.backgroundColor.CGColor;
view.backgroundColor = nil;
layer.backgroundColor =  bColor ;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X