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

27voto

Alex Stone Punkte 44118

Ich habe das Problem mit folgendem Trick bei der Zuweisung des Schattenpfades für die Containeransicht gelöst:

[UIBezierPath bezierPathWithRoundedRect:cell.bounds cornerRadius:12]

Beachten Sie, dass der Pfad des Schattens ein abgerundetes Rechteck mit demselben Eckenradius ist wie der Hintergrund, den die Zelle enthält:

//this is the border for the UIView that is added to a cell
cell.backgroundView.layer.cornerRadius = 12;
cell.backgroundView.layer.masksToBounds = YES;
cell.backgroundView.layer.borderColor = [UIColor darkGrayColor].CGColor;
cell.backgroundView.layer.borderWidth = 1;

//this is the shadow around the cell itself (cannot have round corners with borders and shadow, need to use two views
cell.layer.shadowRadius = 2;
cell.layer.cornerRadius = 12;
cell.layer.masksToBounds = NO;
[[cell layer] setShadowColor:[[UIColor darkGrayColor] CGColor]];

[[cell layer] setShadowOffset:CGSizeMake(0.0,0.0)];
[[cell layer] setShadowOpacity:1.0];

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:cell.bounds cornerRadius:12];
[[cell layer] setShadowPath:[path CGPath]];

17voto

daniel.gindi Punkte 3357

Wenn Sie sich wegen der abgerundeten corners vs. subviews vs. masksToBounds dann versuchen Sie es mit meiner Funktion:

- (UIView*)putView:(UIView*)view insideShadowWithColor:(UIColor*)color andRadius:(CGFloat)shadowRadius andOffset:(CGSize)shadowOffset andOpacity:(CGFloat)shadowOpacity
{
    CGRect shadowFrame; // Modify this if needed
    shadowFrame.size.width = 0.f;
    shadowFrame.size.height = 0.f;
    shadowFrame.origin.x = 0.f;
    shadowFrame.origin.y = 0.f;
    UIView * shadow = [[UIView alloc] initWithFrame:shadowFrame];
    shadow.userInteractionEnabled = NO; // Modify this if needed
    shadow.layer.shadowColor = color.CGColor;
    shadow.layer.shadowOffset = shadowOffset;
    shadow.layer.shadowRadius = shadowRadius;
    shadow.layer.masksToBounds = NO;
    shadow.clipsToBounds = NO;
    shadow.layer.shadowOpacity = shadowOpacity;
    [view.superview insertSubview:shadow belowSubview:view];
    [shadow addSubview:view];
    return shadow;
}

Egal, ob Ihre Ansicht abgerundete Ecken hat, egal, wie groß sie ist, egal, wie sie aussieht - es wird ein schöner Schatten gezeichnet.

Behalten Sie einfach den Rückgabewert der Funktion, damit Sie darauf verweisen können, wenn Sie die Tabelle entfernen wollen (oder verwenden Sie zum Beispiel insertSubview:aboveView: )

15voto

rbaldwin Punkte 3935

Swift 4 und Xcode 9 verwenden ist dies ein funktionierendes Beispiel für die Rundung einer ImageView mit einem Schlagschatten und einem Rahmen.

    //set dimensions and position of image (in this case, centered)
    let imageHeight: CGFloat = 150, imageWidth: CGFloat = 150
    let xPosition = (self.view.frame.width / 2) - (imageWidth / 2)
    let yPosition = (self.view.frame.height / 2) - (imageHeight / 2)

    //set desired corner radius
    let cornerRadius: CGFloat = 20

    //create container for the image
    let imageContainer = UIView(frame: CGRect(x: xPosition, y: yPosition, width: imageWidth, height: imageHeight))

    //configure the container
    imageContainer.clipsToBounds = false
    imageContainer.layer.shadowColor = UIColor.black.cgColor
    imageContainer.layer.shadowOpacity = 1
    imageContainer.layer.shadowOffset = CGSize(width: 3.0, height: 3.0)
    imageContainer.layer.shadowRadius = 5
    imageContainer.layer.shadowPath = UIBezierPath(roundedRect: imageContainer.bounds, cornerRadius: cornerRadius).cgPath

    //create imageView
    let imageView = UIImageView(frame: imageContainer.bounds)

    //configure the imageView
    imageView.clipsToBounds = true
    imageView.layer.cornerRadius = cornerRadius
    //add a border (if required)
    imageView.layer.borderColor = UIColor.black.cgColor
    imageView.layer.borderWidth = 1.0
    //set the image
    imageView.image = UIImage(named: "bird")

    //add the views to the superview
    view.addSubview(imageContainer)
    imageContainer.addSubview(imageView)

enter image description here

Wenn Sie möchten, dass das Bild kreisförmig ist: (und ohne Rand angezeigt wird)

let cornerRadius = imageWidth / 2

enter image description here

7voto

onmyway133 Punkte 42296

Sie müssen Folgendes verwenden shadowView y roundView

enter image description here

shadowView

  • Muss eine Hintergrundfarbe haben
  • Sollte dahinter liegen roundView
  • Der Trick ist, das Layout shadowView ein wenig nach innen, und sein Schatten muss nach außen leuchten. Passen Sie die insets so dass shadowView ist völlig unsichtbar hinter roundView

roundView

  • Muss Clips Unteransichten

Der Code

addSubviews(shadowView, roundView)
roundView.addSubviews(titleLabel, subtitleLabel, imageView)

// need inset
shadowView.pinEdges(view: self, inset: UIEdgeInsets(constraintInsets: 2))
roundView.pinEdges(view: self)

do {
  shadowView.backgroundColor = .white // need background
  let layer = shadowView.layer
  layer.shadowColor = UIColor.black.cgColor
  layer.shadowRadius = 3
  layer.shadowOffset = CGSize(width: 3, height: 3)
  layer.shadowOpacity = 0.7
  layer.shouldRasterize = true
}

do {
  roundView.backgroundColor = .white
  let layer = roundView.layer
  layer.masksToBounds = true
  layer.cornerRadius = 5
}

Oder Sie können einfach unten ohne Angabe von clipToBounds/maskToBounds

layer.shadowColor = UIColor.gray.cgColor
layer.shadowOffset = CGSize(width: 3, height: 3)
layer.shadowOpacity = 0.8

6voto

Zayin Krige Punkte 3091

Ich habe ein Hilfsmittel für UIView erstellt

@interface UIView (Helper)

- (void)roundCornerswithRadius:(float)cornerRadius
               andShadowOffset:(float)shadowOffset;
@end

können Sie folgendermaßen aufrufen

[self.view roundCornerswithRadius:5 andShadowOffset:5];

Hier ist die Umsetzung

- (void)roundCornerswithRadius:(float)cornerRadius
               andShadowOffset:(float)shadowOffset
{
    const float CORNER_RADIUS = cornerRadius;
    const float SHADOW_OFFSET = shadowOffset;
    const float SHADOW_OPACITY = 0.5;
    const float SHADOW_RADIUS = 3.0;

    UIView *superView = self.superview;

    CGRect oldBackgroundFrame = self.frame;
    [self removeFromSuperview];

    CGRect frameForShadowView = CGRectMake(0, 0, oldBackgroundFrame.size.width, oldBackgroundFrame.size.height);
    UIView *shadowView = [[UIView alloc] initWithFrame:frameForShadowView];
    [shadowView.layer setShadowOpacity:SHADOW_OPACITY];
    [shadowView.layer setShadowRadius:SHADOW_RADIUS];
    [shadowView.layer setShadowOffset:CGSizeMake(SHADOW_OFFSET, SHADOW_OFFSET)];

    [self.layer setCornerRadius:CORNER_RADIUS];
    [self.layer setMasksToBounds:YES];

    [shadowView addSubview:self];
    [superView addSubview:shadowView];

}

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