Добавить эффект скоса в UIView - PullRequest
0 голосов
/ 22 ноября 2018

Я хочу, чтобы моя кнопка выглядела так.

enter image description here

Я спросил дизайнера, и он сказал, что использовал эффект скоса, и яуслышав слово скос в первый раз.

Я искал переполнение стека, но не смог найти ничего полезного.

Ответы [ 3 ]

0 голосов
/ 30 ноября 2018

Мое предложение - экспортировать эту кнопку (без текста) в вектор, если это возможно.А ты это просто как имидж.Иногда лучше сэкономить ваше время и использовать изображения в таких случаях.Я предпочитаю рисовать только простые фигуры.Или вы можете добиться этого, заменив эффект скоса комбинацией градиент / граница / тень.

0 голосов
/ 01 декабря 2018

Скос - это «наклонная поверхность по краю куска дерева, стекла и т. Д.».В вычислительном мире мы используем «скос», обычно вокруг кнопки, чтобы создать иллюзию трехмерности.Хотя с iOS7 была определенная тенденция предпочитать более плоский вид.

Когда вы говорите, что хотите применить скос к представлению пользовательского интерфейса, вы имеете в виду градиент вокруг края.Я выделил это красным на изображении ниже.

Highlighted bevel

Когда вы говорите, что хотите, чтобы ваша кнопка выглядела как ваше изображение, скос может быть только частью этой цели.

Как уже было предложено, самый быстрый и простой способ сделать так, чтобы ваша кнопка выглядела так, - это использовать изображение кнопки и применить его к своему виду.Это, вероятно, более эффективный способ сделать это тоже.В качестве альтернативы, можно создать кнопку с помощью кода.Хотя вам понадобится кнопка в векторном формате.

Чтобы сгенерировать кнопку в коде, вам нужно попросить вашего дизайнера кнопку в векторном формате.Формат SVG, вероятно, будет самым простым.Существует ряд сторонних программ, которые могут конвертировать векторные изображения в код Core Graphics.Для этого примера я использовал программу под названием 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 голосов
/ 25 ноября 2018

Я считаю, что дизайнер имел в виду эффект скоса и тиснения.Вот пример расширения для 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)
    }
}

Попросите у дизайнера изображение шейдера и нанесите его на плоское изображение.

Мое личное мнение таково, что лучше получить обработанное изображение от дизайнера и использовать его, а не выполнять всю эту обработку в приложении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...