我正在尝试创建以下图片的可调整大小的版本(40x28,底部的小三角应该水平居中):
UIEdgeInsets imageInsets = UIEdgeInsetsMake(4.0f, 4.0f, 8.0f, 4.0f);
UIImage *pinImage = [[UIImage imageNamed:@"map_pin"] resizableImageWithCapInsets:imageInsets];
根据documentation,这个简单的方法不起作用,因为我的三角形落入可调整大小的区域(固定高度但可扩展的宽度):
这将导致与this非常相似的SO后复制(平铺)三角形中描述的相同问题。但不幸的是,他们的解决方案对我的特定情况不起作用,因为从可缩放区域中排除三角形会导致其错位,并且由于明显的原因它不会水平居中。
所以我想知道......是否有可能使用[UIImage resizableImageWithCapInsets:]
方法实现我的目标?或者我应该尝试其他一些东西,比如在代码中绘制所有内容?
基本上,我想从Google Maps SDK中实现类似Info Windows的内容:
答案 0 :(得分:1)
您可以使用UIBezierPath
来实现这一点。以下代码在swift中,但您应该能够在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()
答案 1 :(得分:1)
我决定选择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