【问题标题】:How to create Box-Shadow in IOS如何在 IOS 中创建 Box-Shadow
【发布时间】:2014-09-19 16:50:10
【问题描述】:

我想设计一个这样的登录页面

在此页面中使用 ios 中的框阴影我尝试了图层阴影 like this 但是这个没有像上面的图像PLZ指南那样显示。

我试过了

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

但它显示

提前致谢

更新

使用以下代码:

UIImageView *imag = (UIImageView*)[self.view viewWithTag:1];
    imag = [[UIImageView alloc] initWithFrame:CGRectMake((screenWidth/100)*12, (screenHeight/100)*10, (screenWidth/100)*75, (screenHeight/100)*61)];
    [imag setBackgroundColor:[UIColor whiteColor]];
    [imag.layer setOpacity:0.4];
    [imag.layer setShadowOpacity:1.0];
    [imag.layer setShadowColor:[[UIColor blackColor] CGColor]];
    [imag.layer setShadowOffset:CGSizeMake(0.0, 0.0)];
    [imag.layer setShadowRadius:8.0];
    [imag setClipsToBounds:FALSE];
    [imag.layer setMasksToBounds:FALSE];
    [self.view addSubview:imag];

ios 6 它显示如下图,但它适用于 ios 7

【问题讨论】:

  • 阴影有何不同?
  • 搜索 shadowPath

标签: ios objective-c


【解决方案1】:

我的屏幕上有这个:

使用此代码 sn-p:

[_backgroundBoxWithShadow.layer setOpacity:0.4];
[_backgroundBoxWithShadow setBackgroundColor:[UIColor whiteColor]];
[_backgroundBoxWithShadow.layer setShadowOpacity:1.0];
[_backgroundBoxWithShadow.layer setShadowColor:[[UIColor blackColor] CGColor]];
[_backgroundBoxWithShadow.layer setShadowOffset:CGSizeMake(0.0, 0.0)];
[_backgroundBoxWithShadow.layer setShadowRadius:8.0];

[_imaginaryTextBoxWithShadow.layer setShadowColor:[[UIColor blackColor] CGColor]];
[_imaginaryTextBoxWithShadow.layer setShadowOffset:CGSizeMake(-4.0, 4.0)];
[_imaginaryTextBoxWithShadow.layer setShadowRadius:4.75];
[_imaginaryTextBoxWithShadow.layer setShadowOpacity:0.4];

注意:没有一个视图包含另一个视图,它们是同一个superview 中的兄弟姐妹。但是,在我看来,结果看起来与原始屏幕截图相同 - 您仍然可以使用这些值来优化结果以满足您的最终愿望。


更新

你根据我的回答发布了你的代码片段 “不工作”

CGFloat screenWidth = self.view.bounds.size.width;
CGFloat screenHeight = self.view.bounds.size.height;

// BEGIN - your code
UIImageView *imag = (UIImageView *)[self.view viewWithTag:1]; // the line is pointless here, anyway...
imag = [[UIImageView alloc] initWithFrame:CGRectMake((screenWidth/100)*12, (screenHeight/100)*10, (screenWidth/100)*75, (screenHeight/100)*61)];
[imag setBackgroundColor:[UIColor whiteColor]];
[imag.layer setOpacity:0.4];
[imag.layer setShadowOpacity:1.0];
[imag.layer setShadowColor:[[UIColor blackColor] CGColor]];
[imag.layer setShadowOffset:CGSizeMake(0.0, 0.0)];
[imag.layer setShadowRadius:8.0];
// END - your code

[self.view addSubview:imag];

这就是它在我身边的 真实 iPhone5 上的样子,它看起来工作得很好:

如果您对此有所不同,请发布有关它的屏幕截图(!)。


注意:必须同时保留视图的clipsToBounds 和图层的masksToBounds FALSE,否则阴影将被切断。


Interface Builder中看起来是正确的:

或者您可以将其显式添加到您的代码中:

[imag setClipsToBounds:FALSE];
[imag.layer setMasksToBounds:FALSE];

iOS6.1 更新

最终证明,您需要一个适用于 iOS6 的解决方案,我发现该解决方案在我的 iOS6.1 设备上也能正常工作:

[_backgroundBoxWithShadow.layer setOpacity:0.4];
[_backgroundBoxWithShadow setBackgroundColor:[UIColor whiteColor]];
[_backgroundBoxWithShadow.layer setShouldRasterize:TRUE];
[_backgroundBoxWithShadow.layer setRasterizationScale:[[UIScreen mainScreen] scale]];
[_backgroundBoxWithShadow.layer setShadowOpacity:1.0];
[_backgroundBoxWithShadow.layer setShadowColor:[[UIColor blackColor] CGColor]];
[_backgroundBoxWithShadow.layer setShadowOffset:CGSizeMake(0.0, 0.0)];
[_backgroundBoxWithShadow.layer setShadowRadius:8.0];

您也可能看到,iOS6.1 上的最终结果如下所示:

【讨论】:

    【解决方案2】:

    由于 iOS 6 合成不透明度的方式,您将很难使用 CALayer 的阴影属性使其工作。

    iOS 6 并没有像 iOS 7 那样合成整个事物并在最后应用不透明度,而是似乎将其应用于所有底层视图,这意味着您可以透过半透明的白色前景视图看到阴影在它下面。

    如果您确实需要 iOS 6 支持,我建议使用预先合成的 9 补丁图像,该图像经过拉伸以构成带有阴影的半透明背景。

    UIImage* image = [self resizableBackgroundImageWithShadowRadius:20
                                                        shadowColor:[UIColor blackColor]
                                                          fillColor:[UIColor colorWithWhite:1 alpha:0.5]];
    
    UIImageView* imageView = [[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 100, 200)];
    [imageView setImage:image];
    [self.window addSubview:imageView];
    

    .

    - (UIImage*) resizableBackgroundImageWithShadowRadius:(CGFloat) shadowRadius shadowColor:(UIColor*) shadowColor fillColor:(UIColor*) fillColor
    {
        const CGFloat stretchExcess = shadowRadius / 2.0;
        const CGFloat stretchDimension = shadowRadius + stretchExcess;
        const CGFloat shadowDimension = shadowRadius * 2.0;
        const CGFloat imageDimension = shadowDimension + stretchDimension;
        const CGSize imageSize = CGSizeMake(imageDimension, imageDimension);
    
        UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
    
        CGContextRef ctx = UIGraphicsGetCurrentContext();
    
        //  Inner fill path
        UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(shadowRadius, shadowRadius, imageSize.width - shadowDimension, imageSize.height - shadowDimension)];
    
        //  Draw the shadow
        CGContextSaveGState(ctx);
        CGContextSetShadowWithColor(ctx, CGSizeZero, shadowRadius / 2.0, shadowColor.CGColor);
        [[fillColor colorWithAlphaComponent:1] set];
        [path fill];
        CGContextRestoreGState(ctx);
    
        //  Clear the middle
        [path fillWithBlendMode:kCGBlendModeClear alpha:0];
    
        //  Draw our fill color
        [fillColor set];
        [path fill];
    
        const CGFloat inset = shadowRadius + stretchExcess;
        UIImage* image = [UIGraphicsGetImageFromCurrentImageContext() resizableImageWithCapInsets:UIEdgeInsetsMake(inset, inset, inset, inset)];
    
        UIGraphicsEndImageContext();
    
        return image;
    }
    

    结果(iOS 6):

    【讨论】:

    • @S.P 您可以在运行时使用图像上下文渲染 9 个补丁图像,这样它仍然是动态的,您不需要包含任何资源。如果您对此感兴趣,请告诉我,我可以研究实施。
    • 这并不是一个真正的最佳解决方案,因为不是每个开发人员都有 PhotoShop;即使他们有,当他们想要更改阴影或背景的任何微小细节时,他们都需要重新创建图像。看起来有点痛苦的想法。
    • @holex 不,这实际上不是真的。我的第一个示例使用 Photoshop 导出的资源来证明它是如何工作的。我已将答案更新为不需要任何 Photoshop 并且在您的应用程序中不需要任何图像资源。您可以使用动态变量在运行时动态创建 9 补丁图像。与您的答案相比,这实际上渲染速度要快得多,因为您的答案必须首先进行屏幕外渲染以找到 Alpha 通道,然后再使用阴影进行另一次渲染。我的答案只需要一次通过,直接呈现在屏幕上。
    【解决方案3】:

    为什么不显示?您链接到的代码应该可以正常工作:

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

    仔细检查您的插座连接(如果您使用的是 Interface Builder)并确保 imageView 在您调用此方法时不为零(您可以在此方法的某处放置断点)。另外,请确保导入 #import "QuartzCore/CALayer.h" 并将 clipsToBounds 属性设置为 NO(否则,它不会只显示)。

    另一个警告可能是不正确的帧大小 - 它实际上可能与看起来不同,因此这可能是阴影没有出现在您认为应该出现的位置的原因之一。

    您可能需要调整阴影偏移、不透明度和其他选项以达到所需的效果。

    UPD:您似乎正在尝试向视图添加阴影。查看此StackOverflow question 中描述的另一种方法。

    【讨论】:

      猜你喜欢
      • 2012-03-03
      • 1970-01-01
      • 2018-10-12
      • 2012-06-01
      • 2021-11-19
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 2011-08-26
      相关资源
      最近更新 更多