为UIView添加斜角效果

6

我想让我的按钮看起来像这样。

enter image description here

我问了设计师,他说他在上面使用了斜角效果,而我第一次听到这个词。我在Stack Overflow上搜索,但没有找到任何有用的信息。


了解斜角效果 - http://www.rw-designer.com/bevel-effect-explained - Aakash
仍然找不到如何在iOS中完成此操作的任何信息。 - Drunken Daddy
本教程将解释如何向图像添加斜面/浮雕效果。https://blog.jayway.com/2017/03/12/realistic-text-emboss-effect-in-ios/ - Sateesh Yemireddi
3个回答

3

我认为设计师想使用斜角和浮雕效果。这里是一个针对UIImage的示例扩展,可应用具有着色器图像的凸出效果。

extension UIImage {
    func applyBevelAndEmboss(shadingImage: UIImage) -> UIImage {
        // Create filters
        guard let heightMapFilter = CIFilter(name: "CIHeightFieldFromMask") else { return self }
        guard let shadedMaterialFilter = CIFilter(name: "CIShadedMaterial") else { return self }
        // Filters chain
        heightMapFilter.setValue(CIImage(image: self),
                                 forKey: kCIInputImageKey)
        guard let heightMapFilterOutput = heightMapFilter.outputImage else { return self }
        shadedMaterialFilter.setValue(heightMapFilterOutput,
                                      forKey: kCIInputImageKey)
        shadedMaterialFilter.setValue(CIImage(image: shadingImage),
                                      forKey: "inputShadingImage")
        // Catch output
        guard let filteredImage = shadedMaterialFilter.outputImage else { return self }
        return UIImage(ciImage: filteredImage)
    }
}

请向设计师要求着色图像并应用于平面图像。

我个人的观点是,最好从设计师那里获取处理过的图像并使用它,而不是在应用程序中执行所有处理。


1
一个倾斜面是指“沿着一块木头、玻璃等边缘的倾斜面”。在计算机世界中,我们通常会在按钮周围使用“斜角”,以营造出3D的错觉。尽管自iOS7以来,趋势明显倾向于更平的外观。
当你说你希望将斜角应用于UI视图时,你指的是边缘周围的渐变。我在下面的图片中用红色突出了这一点。

Highlighted bevel

当你说你希望按钮看起来像你的图片时,斜面可能只是其中一部分。如已建议的那样,使您的按钮看起来像那样最快,最简单的方法是使用按钮图像,并将其应用于您的视图。这可能也是更有效的方法。或者,也可以使用代码创建按钮。虽然您需要矢量格式的按钮。
为了在代码中生成按钮,您需要向设计师询问矢量格式的按钮。SVG格式可能是最简单的。有许多第三方程序可以将矢量图像转换为核心图形代码。对于这个例子,我使用了一个叫做Graphic(由Autodesk开发)的程序。尽管我不得不修复它所生成的代码中的一些错误。更新的替代方案可能更好。我没有尝试过使用Graphic在Swift中生成代码。
这是我的一个类似于您设计的按钮的示例。这段代码是概念验证,因此按钮的大小和位置不是很好。我没有花太多时间来匹配我的按钮与您的确切设计。但是,它将产生一个类似的按钮视图。
#import "Button.h"
#import <CoreText/CoreText.h>

@implementation Button

- (void)drawRect:(CGRect)rect {

    // Do any additional setup after loading the view, typically from a nib.

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // enable the following lines for flipped coordinate systems
    //CGContextTranslateCTM(ctx, 0, self.bounds.size.height);
    //CGContextScaleCTM(ctx, 1, -1);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    /*  Shape   */
    CGMutablePathRef pathRef = CGPathCreateMutable();
    CGPathMoveToPoint(pathRef, NULL, 251.424, 272.035);
    CGPathAddCurveToPoint(pathRef, NULL, 251.424, 288.189, 238.328, 301.285, 222.174, 301.285);
    CGPathAddCurveToPoint(pathRef, NULL, 206.02, 301.285, 192.924, 288.189, 192.924, 272.035);
    CGPathAddCurveToPoint(pathRef, NULL, 192.924, 255.881, 206.02, 242.785, 222.174, 242.785);
    CGPathAddCurveToPoint(pathRef, NULL, 238.328, 242.785, 251.424, 255.881, 251.424, 272.035);
    CGPathCloseSubpath(pathRef);

    /*  Gradient Fill  */
    CGContextSaveGState(ctx);
    CGContextAddPath(ctx, pathRef);
    CGContextClip(ctx);

    CGFloat gradientColors[] = {
        0.549, 0.557, 0.565, 1,
        0, 0, 0, 1 };
    CGFloat gradientLocations[] = { 0, 0.973 };

    CGGradientRef gradientRef = CGGradientCreateWithColorComponents(colorSpace, gradientColors, gradientLocations, 2);
    CGContextDrawLinearGradient(ctx, gradientRef, CGPointMake(201.492, 251.353), CGPointMake(242.857, 292.719), (kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation));
    CGGradientRelease(gradientRef);
    CGContextRestoreGState(ctx);

    CGPathRelease(pathRef);

    /*  Shape 2  */
    CGMutablePathRef pathRef2 = CGPathCreateMutable();
    CGPathMoveToPoint(pathRef2, NULL, 247.069, 272.035);
    CGPathAddCurveToPoint(pathRef2, NULL, 247.069, 285.784, 235.923, 296.93, 222.174, 296.93);
    CGPathAddCurveToPoint(pathRef2, NULL, 208.425, 296.93, 197.279, 285.784, 197.279, 272.035);
    CGPathAddCurveToPoint(pathRef2, NULL, 197.279, 258.286, 208.425, 247.14, 222.174, 247.14);
    CGPathAddCurveToPoint(pathRef2, NULL, 235.923, 247.14, 247.069, 258.286, 247.069, 272.035);
    CGPathCloseSubpath(pathRef2);

    /*  Gradient Fill  */
    CGContextSaveGState(ctx);
    CGContextAddPath(ctx, pathRef2);
    CGContextClip(ctx);

    CGFloat gradientColors2[] = {
        0.165, 0.153, 0.153, 1,
        0, 0, 0, 0.651 };
    CGFloat gradientLocations2[] = { 0.897, 0.991 };

    CGGradientRef gradientRef2 = CGGradientCreateWithColorComponents(colorSpace, gradientColors2, gradientLocations2, 2);
    CGContextDrawRadialGradient(ctx, gradientRef2, CGPointMake(222.174, 272.035), 0, CGPointMake(222.174, 272.035), 24.895, (kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation));
    CGGradientRelease(gradientRef2);
    CGContextRestoreGState(ctx);

    CGPathRelease(pathRef2);

    /*  Text   */
    UIColor *colour = [UIColor colorWithRed:1 green:1 blue:1 alpha:1];
    NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:@"STOP"];
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.alignment = NSTextAlignmentLeft;
    NSDictionary *textAttribs = @{
                                  NSFontAttributeName: [UIFont fontWithName:@"Helvetica" size:10],
                                  NSForegroundColorAttributeName: colour,
                                  NSParagraphStyleAttributeName: paragraphStyle
                                  };
    [attributedStr setAttributes:textAttribs range:NSMakeRange(0, 4)];


    CGRect textBox = CGRectMake(208.736, 270.375, 28.051, 14);
    CGPathRef textBoxPath = CGPathCreateWithRect(CGRectMake(0, 0, textBox.size.width, textBox.size.height), NULL);
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attributedStr);
    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), textBoxPath, NULL);
    CGContextSaveGState(ctx);
    CGContextTranslateCTM(ctx, textBox.origin.x, textBox.origin.y);

    CGContextSetTextMatrix(ctx, CGAffineTransformIdentity);
    CGContextTranslateCTM(ctx, 0.0, textBox.size.height);
    CGContextScaleCTM(ctx, 1.0, -1.0);
    CTFrameDraw(frameRef, ctx);

    CGContextRestoreGState(ctx);
    CGPathRelease(textBoxPath);
    CFRelease(framesetter);
    CFRelease(frameRef);

    /*  Shape 3  */
    CGMutablePathRef pathRef3 = CGPathCreateMutable();
    CGPathMoveToPoint(pathRef3, NULL, 229.861, 260.812);
    CGPathAddCurveToPoint(pathRef3, NULL, 229.861, 262.987, 228.098, 264.75, 225.923, 264.75);
    CGPathAddLineToPoint(pathRef3, NULL, 218.423, 264.75);
    CGPathAddCurveToPoint(pathRef3, NULL, 216.248, 264.75, 214.485, 262.987, 214.485, 260.812);
    CGPathAddLineToPoint(pathRef3, NULL, 214.485, 260.812);
    CGPathAddCurveToPoint(pathRef3, NULL, 214.485, 258.637, 216.248, 256.874, 218.423, 256.874);
    CGPathAddLineToPoint(pathRef3, NULL, 225.923, 256.874);
    CGPathAddCurveToPoint(pathRef3, NULL, 228.099, 256.875, 229.861, 258.638, 229.861, 260.812);
    CGPathAddLineToPoint(pathRef3, NULL, 229.861, 260.812);
    CGPathCloseSubpath(pathRef3);

    CGContextSetRGBFillColor(ctx, 0.514, 0.773, 0.357, 1);
    CGContextAddPath(ctx, pathRef3);
    CGContextFillPath(ctx);

    CGPathRelease(pathRef3);
    CGColorSpaceRelease(colorSpace);

}


@end

Screenshot of the result in the iOS simulator


0
我的建议是尽可能以矢量形式导出此按钮(无文字),并将其简单地用作图像。在某些情况下,使用图像可以节省时间更为高效。我更喜欢绘制简单的形状。或者,您可以通过将斜面效果替换为渐变/边框/阴影的组合来实现这一点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接