Was ist der beste Weg, um einen Schatten hinter einer UIImageView zu erstellen?

75

Ich habe eine UIImageView, hinter der ich einen Schatten hinzufügen möchte. Ich wünschte, Apple hätte das als Eigentum, aber sie müssen uns Programmierern viele Dinge schwer machen, also muss ich diese Frage stellen.

Jab
quelle
1
Wahrscheinlich möchten Sie die Zeichenfunktionen von Core Graphics verwenden, um den Schatten zu zeichnen.
Grant Paul

Antworten:

215

Es gibt einen besseren und einfacheren Weg, dies zu tun. UIImageView erbt von UIView, sodass es eine Layereigenschaft hat. Sie können auf die Schatteneigenschaften der Ebene zugreifen und erhalten einen Schatten.

Wenn Sie UIImageView als IBOutlet für eine NIB-Datei haben, können Sie einfach die awakeFromNib implementieren, z

Ziel c

- (void)awakeFromNib {
    imageView.layer.shadowColor = [UIColor purpleColor].CGColor;
    imageView.layer.shadowOffset = CGSizeMake(0, 1);
    imageView.layer.shadowOpacity = 1;
    imageView.layer.shadowRadius = 1.0;
    imageView.clipsToBounds = NO;
}

Vergiss es nicht #import "QuartzCore/CALayer.h"


Für Swift können Sie auf mehrere Arten vorgehen. Erstellen Sie eine Klassenerweiterung, Unterklasse oder eine imageView-Instanz. Unabhängig davon ist der Vorgang beim Ändern der Schatteneigenschaft der Ebenen derselbe.

Swift 3

override func awakeFromNib() {
    super.awakeFromNib()

    imageView.layer.shadowColor = UIColor.purple.cgColor
    imageView.layer.shadowOffset = CGSize(width: 0, height: 1)
    imageView.layer.shadowOpacity = 1
    imageView.layer.shadowRadius = 1.0
    imageView.clipsToBounds = false
}
Alex Nguyen
quelle
32
Möglicherweise benötigen Sie auch imageView.clipsToBounds = NO;oder der Schatten wird abgeschnitten.
mxcl
18
Sie müssen auch "QuartzCore / CALayer.h" importieren
dev
1
@MaxHowell mit clipsToBounds hat den Schatten hinzugefügt, aber jetzt sind auch die Grenzen meines Bildüberlaufs überschritten, wenn der Modus "Aspect Fill" verwendet wird. Gibt es eine Möglichkeit, das Bild zu beschneiden, aber nicht den Schatten?
Derek Dahmer
6
@DerekDahmer Sie müssen die Bildansicht als Unteransicht einer anderen Ansicht hinzufügen, auf die Sie dann den Schatten anwenden, und dann die Bildansicht, aber nicht die Containeransicht ausschneiden. Ich habe keinen anderen Weg gefunden, mit so etwas umzugehen.
mxcl
5
Add imageView.layer.shouldRasterize = YES; um die Verarbeitung zu beschleunigen
malaki1974
11

Am einfachsten ist es, Ihrer Bildansicht eine Schattenebene hinzuzufügen:

CALayer             *layer = [CALayer layer];
CGRect              bounds = self.bounds;

layer.bounds = bounds;
layer.position = CGPointMake(bounds.size.width / 2 + 3, bounds.size.height / 2 + 3);
layer.backgroundColor = [UIColor colorWithWhite: 0.25 alpha: 0.55].CGColor;
layer.zPosition = -5;

[self.layer addSublayer: layer];

Stellen Sie sicher, dass "Clip-Unteransichten" für die Ansicht deaktiviert ist

Ben Gottlieb
quelle
1
Warum erstellen Sie CGRect * -Grenzen, wenn Sie die Grenzen der Ebene einfach auf self.bounds setzen können? Und wo kommt der Schatten an seinen Platz?
Jab
Ich erstelle eine temporäre Variable für die Lesbarkeit; Das Eingeben von self.bounds ist etwas länger als nur Bounds und macht den Code etwas weniger lesbar. Diese Schicht ist der Schatten. Dies setzt natürlich voraus, dass Sie ein quadratisches Bild haben. Wenn Sie ein nicht rechteckiges Bild erstellen, müssen Sie eine benutzerdefinierte Bildmaske verwenden.
Ben Gottlieb
Nun, ich möchte, dass es verblasst und ich weiß nicht, wie ich das machen würde. Bitte helfen Sie!
Jab
1
Das Ausbleichen ist eine völlig separate Aufgabe. Wenn Sie einen benutzerdefinierten Schatten haben möchten (etwas anderes als ein einfaches dunkles Rechteck hinter Ihrem Bild), sollten Sie das Bild aufnehmen, es zu einer Maske machen (dh alles schwarz und transparent), Ihre Überblendung anwenden und es dann dahinter zeichnen das Original entweder mit Quarz oder in einer Schicht kleben.
Ben Gottlieb
9

Schnelle Lösung mit Erweiterung. Unterklassen sind nicht erforderlich. Anruf myImage.addShadow()von viewDidLoad(). Dies sollte für UIViewund funktionieren UIImageView.

extension UIView {

    func addShadow() {
        layer.shadowColor = UIColor.black.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 0)
        layer.shadowOpacity = 0.5
        layer.shadowRadius = 5
        clipsToBounds = false
    }
}
Boris Y.
quelle
Wenn ich versuche, dies aufzurufen, erhalte ich 'Wert vom Typ' UIImage 'hat kein Mitglied' addShadow '
user1904273
5

Darüber hinaus können Sie diesen Code verwenden, wenn Sie weiße Ränder und Schatten erstellen möchten:

//shadow part
imageView.layer.shadowColor = [UIColor blackColor].CGColor;
imageView.layer.shadowOffset = CGSizeMake(0, 1);
imageView.layer.shadowOpacity = 1;
imageView.layer.shadowRadius = 1.0;
//white border part
[imageView.layer setBorderColor: [[UIColor whiteColor] CGColor]];
[imageView.layer setBorderWidth: 2.0];
mturhan55
quelle
Aber wie können Sie in diesem Fall den Schatten Teil der .image-Eigenschaft machen, um beispielsweise das Bild an einem anderen Ort zu speichern oder anzuzeigen?
Alejandrormz
Das kannst du nicht. Sie bearbeiten das Bild nicht, sondern schmücken es zur Anzeige. Das eigentliche Bearbeiten der Bitmap-Daten ist viel komplizierter. Schmücken Sie das Bild einfach überall dort, wo Sie es anzeigen, da Sie Bilder im Allgemeinen nicht verarbeiten möchten, um diese Art von Effekten hinzuzufügen, es sei denn, Sie tun dies in einem Back-End, das sie stapelweise verarbeitet.
Tim