358 Stimmen

Wie kann ich einen Schatten unter einer UIView zeichnen?

Ich versuche, einen Schatten unter den unteren Rand eines UIView in Cocoa Touch. Ich verstehe, dass ich Folgendes verwenden sollte CGContextSetShadow() um den Schatten zu zeichnen, aber die Quartz 2D-Programmieranleitung ist ein wenig vage:

  1. Speichern Sie den Grafikstatus.
  2. Rufen Sie die Funktion CGContextSetShadow und übergibt die entsprechenden Werte.
  3. Führen Sie alle Zeichnungen aus, auf die Sie Schatten anwenden möchten.
  4. Wiederherstellung des Grafikstatus

Ich habe das Folgende in einer UIView Unterklasse:

- (void)drawRect:(CGRect)rect {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSaveGState(currentContext);
    CGContextSetShadow(currentContext, CGSizeMake(-15, 20), 5);
    CGContextRestoreGState(currentContext);
    [super drawRect: rect];
}

aber das funktioniert bei mir nicht, und ich weiß nicht, (a) wie ich weiter vorgehen soll und (b) ob ich irgendetwas an meinem UIView damit das funktioniert?

3voto

Mazen Kasser Punkte 3389

Für diejenigen, die es nicht geschafft haben, dies zum Laufen zu bringen (wie ich!), nachdem sie alle Antworten hier ausprobiert haben, stellen Sie einfach sicher, dass Clip-Unteransichten ist im Attributinspektor nicht aktiviert...

2voto

Sandip Patel - SM Punkte 3256

Sie können meine Utility-Funktion für Schatten und Eckenradius wie unten beschrieben verwenden:

- (void)addShadowWithRadius:(CGFloat)shadowRadius withShadowOpacity:(CGFloat)shadowOpacity withShadowOffset:(CGSize)shadowOffset withShadowColor:(UIColor *)shadowColor withCornerRadius:(CGFloat)cornerRadius withBorderColor:(UIColor *)borderColor withBorderWidth:(CGFloat)borderWidth forView:(UIView *)view{

    // drop shadow
    [view.layer setShadowRadius:shadowRadius];
    [view.layer setShadowOpacity:shadowOpacity];
    [view.layer setShadowOffset:shadowOffset];
    [view.layer setShadowColor:shadowColor.CGColor];

    // border radius
    [view.layer setCornerRadius:cornerRadius];

    // border
    [view.layer setBorderColor:borderColor.CGColor];
    [view.layer setBorderWidth:borderWidth];
}

Hoffentlich hilft es Ihnen!!!

1voto

Josh O'Connor Punkte 4480

Mauersegler 3

self.paddingView.layer.masksToBounds = false
self.paddingView.layer.shadowOffset = CGSize(width: -15, height: 10)
self.paddingView.layer.shadowRadius = 5
self.paddingView.layer.shadowOpacity = 0.5

1voto

iamVishal16 Punkte 1642

Alle Antworten sind gut, aber ich möchte einen weiteren Punkt hinzufügen

Wenn Sie auf ein Problem stoßen, wenn Sie Tabellenzellen haben, Deque eine neue Zelle gibt es eine Fehlanpassung in Schatten, so dass in diesem Fall, müssen Sie Ihre Schatten-Code in einem layoutSubviews Methode, so dass es schön in allen Bedingungen verhalten wird.

-(void)layoutSubviews{
    [super layoutSubviews];

    [self.contentView setNeedsLayout];
    [self.contentView layoutIfNeeded];
    [VPShadow applyShadowView:self];
}

oder in ViewControllern für bestimmte Ansichten Schattencode innerhalb der folgenden Methode platzieren, damit es gut funktioniert

-(void)viewDidLayoutSubviews{
    [super viewDidLayoutSubviews];

    [self.viewShadow layoutIfNeeded];
    [VPShadow applyShadowView:self.viewShadow];
}

Ich habe meine Schatten-Implementierung für neue Entwickler modifiziert, um eine allgemeinere Form zu erhalten:

/*!
 @brief Add shadow to a view.

 @param layer CALayer of the view.

 */
+(void)applyShadowOnView:(CALayer *)layer OffsetX:(CGFloat)x OffsetY:(CGFloat)y blur:(CGFloat)radius opacity:(CGFloat)alpha RoundingCorners:(CGFloat)cornerRadius{
    UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:layer.bounds cornerRadius:cornerRadius];
    layer.masksToBounds = NO;
    layer.shadowColor = [UIColor blackColor].CGColor;
    layer.shadowOffset = CGSizeMake(x,y);// shadow x and y
    layer.shadowOpacity = alpha;
    layer.shadowRadius = radius;// blur effect
    layer.shadowPath = shadowPath.CGPath;
}

1voto

Martin Zikmund Punkte 36811

Für die Xamarianer unter Ihnen würde die Xamarin.iOS/C#-Version der Antwort wie folgt aussehen:

public override void DrawRect(CGRect area, UIViewPrintFormatter formatter)
{
    CGContext currentContext = UIGraphics.GetCurrentContext();
    currentContext.SaveState();
    currentContext.SetShadow(new CGSize(-15, 20), 5);
    base.DrawRect(area, formatter);
    currentContext.RestoreState();                
}

Der Hauptunterschied besteht darin, dass Sie eine Instanz von CGContext mit denen Sie die entsprechenden Methoden direkt aufrufen.

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