2016-08-10 3 views
2

Я пытаюсь создать изменяемую версию следующего изображения (40x28, маленького треугольник в нижнюю части должны быть сосредоточены горизонтально):комплексов изображений (пузырчатый/штырь) и [UIImage resizableImageWithCapInsets:]

enter image description here

UIEdgeInsets imageInsets = UIEdgeInsetsMake(4.0f, 4.0f, 8.0f, 4.0f); 
UIImage *pinImage = [[UIImage imageNamed:@"map_pin"] resizableImageWithCapInsets:imageInsets];                  

согласно documentation, этот простой подход не будет работать, так как мой треугольник попадает в перезначительном области (фиксированная высота, но масштабируемую ширина):

enter image description here

Это вызовет такую ​​же проблему, как описано в this, очень похожие SO-дублированные (черепичные) треугольники. Но, к сожалению, их решение не работает для моего конкретного случая, поскольку исключение треугольника из масштабируемой области вызывает его неправильное использование, и по очевидным причинам оно не будет центрироваться по горизонтали.

Так что интересно ... возможно ли достичь моей цели, используя метод [UIImage resizableImageWithCapInsets:]? Или может быть, я должен попробовать что-то еще, например, рисовать все в коде?

В принципе, я хотел бы реализовать что-то вроде информационных окон из Google Maps SDK:

enter image description here

+1

ли у попытаться рисовать изображения с помощью bezierPAth, и пусть Безье путь изменения размера на основе просмотра кадра> –

+0

Пока нет, но похоже, мне придется идти в этом направлении. – fraggjkee

+1

Если вы все еще хотите UIImage, вы можете разрезать его на кусочки. Один для стрелки, другой для прямоугольника. и вычислить их. Пользовательский UIView (или UIImageView) с ограничениями, границы с ведущими/конечными/верхними для супервизора и внизу на расстоянии, равном высоте для наблюдения, и фиксированной шириной стрелки, центрированной, фиксированной высотой и дном для наблюдения? – Larme

ответ

1

можно достичь, используя UIBezierPath .the следующий код быстры, но вы должны быть в состоянии достичь То же самое в Objective-C

Вместо запуска кода с прямой:

path.moveToPoint(CGPoint(x: 300, y: 0)) 

я вместо того, чтобы начать с дугой (справа вверху):

path.addArcWithCenter(CGPoint(x: 300-10, y: 50), radius: 10 , startAngle: 0 , endAngle: CGFloat(M_PI/2) , clockwise: true) //1st rounded corner 

и, делая это, у меня есть четыре скругленных углов и мне просто нужно, чтобы добавить прямую линию в конце коды прямо перед:

path.closePath() 

Вот код и скриншот:

let path = UIBezierPath() 
path.addArcWithCenter(CGPoint(x: 300-10, y: 50), radius: 10 , startAngle: 0 , endAngle: CGFloat(M_PI/2) , clockwise: true) //1st rounded corner 
path.addArcWithCenter(CGPoint(x: 200, y: 50), radius:10, startAngle: CGFloat(2 * M_PI/3), endAngle:CGFloat(M_PI) , clockwise: true)// 2rd rounded corner 
path.addArcWithCenter(CGPoint(x: 200, y: 10), radius:10, startAngle: CGFloat(M_PI), endAngle:CGFloat(3 * M_PI/2), clockwise: true)// 3rd rounded corner 
// little triangle 
path.addLineToPoint(CGPoint(x:240 , y:0)) 
path.addLineToPoint(CGPoint(x: 245, y: -10)) 
path.addLineToPoint(CGPoint(x:250, y: 0)) 
path.addArcWithCenter(CGPoint(x: 290, y: 10), radius: 10, startAngle: CGFloat(3 * M_PI/2), endAngle: CGFloat(2 * M_PI), clockwise: true) 
path.addLineToPoint(CGPoint(x:300 , y:50)) 
path.closePath() 

enter image description here

1

I декабрь чтобы пойти с UIBezierPath, как Предлагается Assam Al-Zookery. Вот полный код в Objective-C (должен быть многоразовым и достаточно гибкой):

@implementation TestView 

- (instancetype)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame]; 
    if (self) { 
     self.clipsToBounds = YES; 
     self.opaque = NO; 
    } 
    return self; 
} 

- (void)drawRect:(CGRect)rect { 
    UIBezierPath *path = [UIBezierPath bezierPath]; 
    path.lineWidth = 2.0f; 
    path.lineJoinStyle = kCGLineJoinRound; 

    [[UIColor blackColor] setStroke]; 
    [[UIColor redColor] setFill]; 

    CGFloat arcRadius = 5.0f; 
    CGFloat padding = 5.0f; 
    CGFloat triangleSide = 20.0f; 
    CGFloat triangleHeight = ((triangleSide * sqrtf(3.0f))/2); 
    CGFloat rectHeight = CGRectGetHeight(rect) - triangleHeight - padding - (arcRadius * 2); 

    // Top left corner 
    [path addArcWithCenter:CGPointMake(arcRadius + padding, arcRadius + padding) 
        radius:arcRadius 
       startAngle:DEGREES_TO_RADIANS(180) 
        endAngle:DEGREES_TO_RADIANS(270) 
       clockwise:YES]; 

    // Top edge 
    [path addLineToPoint:CGPointMake(CGRectGetWidth(rect) - arcRadius - padding, path.currentPoint.y)]; 

    // Top right corner 
    [path addArcWithCenter:CGPointMake(path.currentPoint.x, path.currentPoint.y + arcRadius) 
        radius:arcRadius 
       startAngle:DEGREES_TO_RADIANS(270) 
        endAngle:DEGREES_TO_RADIANS(0) 
       clockwise:YES]; 

    // Right edge 
    [path addLineToPoint:CGPointMake(CGRectGetWidth(rect) - padding, rectHeight + padding)]; 

    // Bottom right corner 
    [path addArcWithCenter:CGPointMake(path.currentPoint.x - arcRadius, path.currentPoint.y) 
        radius:arcRadius 
       startAngle:DEGREES_TO_RADIANS(0) 
        endAngle:DEGREES_TO_RADIANS(90) 
       clockwise:YES]; 

    // Bottom edge (right part) 
    [path addLineToPoint:CGPointMake((CGRectGetWidth(rect)/2) + (triangleSide/2), path.currentPoint.y)]; 

    // Triangle 
    [path addLineToPoint:CGPointMake(path.currentPoint.x - (triangleSide/2), path.currentPoint.y + triangleHeight)]; 
    [path addLineToPoint:CGPointMake(path.currentPoint.x - (triangleSide/2), path.currentPoint.y - triangleHeight)]; 

    // Bottom edge (left part) 
    [path addLineToPoint:CGPointMake(padding + arcRadius, path.currentPoint.y)]; 

    // Bottom left corner 
    [path addArcWithCenter:CGPointMake(path.currentPoint.x, path.currentPoint.y - arcRadius) 
        radius:arcRadius 
       startAngle:DEGREES_TO_RADIANS(90) 
        endAngle:DEGREES_TO_RADIANS(180) 
       clockwise:YES]; 

    [path closePath]; 
    [path stroke]; 
    [path fill]; 
} 

@end 

enter image description here

+0

Отличная работа;) @fraggjkee –

Смежные вопросы