圆形特定角并仅在特定边上显示阴影

时间:2016-05-14 00:13:10

标签: ios objective-c uiview uibezierpath

我有以下代码只围绕视图的特定角落:

- (void)roundOnlySpecifiedCornersInView:(UIView *)view corners:(UIRectCorner)corners
{
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:(corners) cornerRadii:CGSizeMake(4.0, 4.0)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];

    maskLayer.path  = maskPath.CGPath;
    view.layer.mask = maskLayer;
}

这完全孤立地运作。现在我在想法中也想要阴影,但我特别想在不同的情况下应用阴影:

  • 各方面
  • 除了底部的所有方面
  • 除了顶部
  • 之外的所有方面
  • 仅左/右侧

我遇到的所有技术都是通过创建视图的插图来实现的。这个的问题是,假设你只想在左/右侧保持阴影,你偏移底部和顶部。由于Rect现在不太高,左右的阴影不会覆盖视图的整个高度。此外,用于圆角的遮罩层会导致阴影不再出现。

此示例代码:

    innerView.layer.shadowColor = [[UIColor colorWithWhite:0.0f alpha:0.1f] CGColor];
    innerView.layer.shadowOpacity = 1.0f;
    innerView.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);
    innerView.layer.shadowRadius = 6.0f;

    CGRect shadowFrame = UIEdgeInsetsInsetRect(innerView.bounds, UIEdgeInsetsMake(9, 0, 9, 0));
    CGPathRef shadowPath = [UIBezierPath bezierPathWithRect:shadowFrame].CGPath;

    innerView.layer.shadowPath = shadowPath;

如何在视图中对特定角进行圆角处理,同时仅在指定边显示阴影?

Swift中的答案也很受欢迎!

我想要的截图(这个很简单,因为所有角都需要四舍五入所以我可以使用.layer.cornerRadius并且它在所有边都有阴影): enter image description here

现在我只想围绕其中的两个角(左上角和右上角,左下角和右下角)并仅在某些边上添加阴影。

3 个答案:

答案 0 :(得分:3)

我不确定它是否符合您的要求。代码创建一个带有顶部和底部阴影的图像,并且所有的圆角,您可以修改代码以实现您所需的。您可以将图像用作单元格的背景(似乎它是UITableViewCell

如果它不适合你,请告诉我。

图片:

enter image description here

// create a shadow image
CGSize size = CGSizeMake(ScreenWidth, ScreenWidth);
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();

UIColor *backgroundColor = [UIColor colorWithRed:246.0/255.0 green:246.0/255.0 blue:246.0/255.0 alpha:1.0];
UIColor *fillColor = [UIColor whiteColor];
CGRect rect = CGRectMake(10, 10, 100, 44);

// re-draw the background
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height));

// set top and bottom shadow
CGRect rectTop = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, 5);
CGContextSaveGState(context);
CGContextSetShadowWithColor(context, CGSizeMake(0, -5), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, rectTop);
CGContextRestoreGState(context);

CGRect rectBottom = CGRectMake(rect.origin.x, rect.origin.y+rect.size.height-5, rect.size.width, 5);
CGContextSaveGState(context);
CGContextSetShadowWithColor(context, CGSizeMake(0, 5), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, rectBottom);
CGContextRestoreGState(context);

// re-draw the background
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
CGContextFillRect(context, rect);

CGContextSaveGState(context);
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(4.0, 4.0)];
[maskPath addClip];
CGContextSetFillColorWithColor(context, fillColor.CGColor);
CGContextFillRect(context, rect);
CGContextRestoreGState(context);

您可以修改代码以获得左上角阴影:

enter image description here

// create a shadow image
CGSize size = CGSizeMake(ScreenWidth, ScreenWidth);
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();

UIColor *backgroundColor = [UIColor colorWithRed:246.0/255.0 green:246.0/255.0 blue:246.0/255.0 alpha:1.0];
UIColor *fillColor = [UIColor whiteColor];
CGRect rect = CGRectMake(10, 10, 100, 44);

// re-draw the background
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height));

// set top and left shadow
CGRect rectTop = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, 5);
CGContextSaveGState(context);
CGContextSetShadowWithColor(context, CGSizeMake(0, -5), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, rectTop);
CGContextRestoreGState(context);

CGRect rectLeft = CGRectMake(rect.origin.x, rect.origin.y, 5, rect.size.height);
CGContextSaveGState(context);
CGContextSetShadowWithColor(context, CGSizeMake(-5, 0), 5, [UIColor colorWithRed:0 green:0 blue:0 alpha:0.1].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, rectLeft);
CGContextRestoreGState(context);

// re-draw the background
CGContextSetFillColorWithColor(context, backgroundColor.CGColor);
CGContextFillRect(context, rect);

CGContextSaveGState(context);
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(4.0, 4.0)];
[maskPath addClip];
CGContextSetFillColorWithColor(context, fillColor.CGColor);
CGContextFillRect(context, rect);
CGContextRestoreGState(context);

HTH

答案 1 :(得分:1)

在许多情况下,你需要通过绘制阴影来实现这一点,当然。但是,您可以考虑以下方法:使用可伸展图像,并在您需要的边上使用阴影,例如:类似的东西(这个虽然各方都有影子):

enter image description here

就在您说:“ Ewwwww!他正在使用图像制作一个简单的阴影!”让我强调一点,这在性能方面会更好。例如,如果UICollectionView中有很多单元格并且每个单元格都重新绘制它的阴影,那么在滚动期间它可能会显着减慢您的应用程序,而对于基于图像的阴影,它将基本上是相同的

我会更进一步,并建议您实际上可以使用可伸缩的图像来用圆角掩盖视图!现在,这可能看起来有点太过分了,但如果你注意到性能急剧下降,我会试一试。您基本上需要做的是准备另一个可伸缩的图像,其中包含透明的“中间”部分和与背景颜色相同的圆角。类似的东西:

enter image description here

再一次,在你投入这种奇怪的方式做一些可以通过两行代码轻松实现的事情之前......

view.layer.cornerRadius = 20
view.layer.masksToBounds = true

...让我指出,当你必须同时显示一堆这些蒙面视图时,这会更快地荒谬:例如,屏蔽UICollectionViewCell s。基本上,如果你在UIView的图层上设置一个遮罩,这个遮罩将被重新计算并实时应用,这会在频繁重绘{{{{{{{ 1}}内容 - 滚动UIViewUITableView时,例如。

显然,如果你的背景不是纯色,并且例如有渐变,这将不起作用。但是,在许多其他情况下,这可能有助于您实现更顺畅的UI性能。在您的特定情况下,另一个优点是您可以轻松控制要遮盖的角落以及阴影应该落在哪里。

同样,我并不是说这是每个案例的方法。我所说的是,在很多情况下,这有助于显着提高性能:例如,如果您屏蔽了同时在屏幕上呈现的太多视图,并且预期布局经常重新绘制。

答案 2 :(得分:-1)

表示特定角落角半径

参考:how to set cornerRadius for only top-left and top-right corner of a UIView?

UIBezierPath *maskPath;
maskPath = [UIBezierPathbezierPathWithRoundedRect:_backgroundImageView.bounds 
                             byRoundingCorners:(UIRectCornerBottomLeft|UIRectCornerBottomRight) 
                                   cornerRadii:CGSizeMake(3.0, 3.0)];

CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = self.bounds;
maskLayer.path = maskPath.CGPath;
_imageView.layer.mask = maskLayer;
[maskLayer release];