Ios 如何将三角形添加到UILabel以使其看起来像工具提示?

Ios 如何将三角形添加到UILabel以使其看起来像工具提示?,ios,objective-c,uilabel,core-graphics,Ios,Objective C,Uilabel,Core Graphics,我想用一些自定义代码制作一个类似UILabel的工具提示。我设法在UILabel中添加了一个三角形,但因为它超出了UILabel本身的界限(或框架)。屏幕上没有画 以下是我的方法: - (void) addTriangleTipToLayer: (CALayer *) targetLayer{ [targetLayer setBackgroundColor: [UIColor whiteColor].CGColor]; CGPoint startPoint = CGPointMake(0, t

我想用一些自定义代码制作一个类似UILabel的工具提示。我设法在UILabel中添加了一个三角形,但因为它超出了UILabel本身的界限(或框架)。屏幕上没有画

以下是我的方法:

- (void) addTriangleTipToLayer: (CALayer *) targetLayer{
[targetLayer setBackgroundColor: [UIColor whiteColor].CGColor];

CGPoint startPoint = CGPointMake(0, targetLayer.frame.size.height);
CGPoint endPoint = CGPointMake(15, targetLayer.frame.size.height);
UIBezierPath *trianglePath = [UIBezierPath bezierPath];

CGFloat middleX = (startPoint.x + endPoint.x) / 2;
CGFloat middleY = 7.5 * tan(M_PI / 3);

CGPoint middlePoint = CGPointMake(middleX, -middleY);

[trianglePath moveToPoint:startPoint];
[trianglePath addLineToPoint:middlePoint];
[trianglePath addLineToPoint:endPoint];
[trianglePath closePath];
CGAffineTransform rotate = CGAffineTransformMakeRotation(180);
[trianglePath applyTransform:rotate];

CAShapeLayer *triangleLayer = [CAShapeLayer layer];
[triangleLayer setFillColor: [UIColor whiteColor].CGColor];
[triangleLayer setPath:trianglePath.CGPath];
[targetLayer addSublayer:triangleLayer];
}

我还将标签转换为图像内容,用作谷歌地图标记图标。这是我对这个UILabel做的其他事情

UILabel *klabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 20)];
[klabel setFont: [UIFont fontWithName:@"Roboto-Light" size:9]];
[klabel setText: @"Tower"];
// here I apply the add triangle function to the uilabel.layer
[self addTriangleTipToLayer:klabel.layer];
//set the label to fit text content before rendered as a image
[klabel sizeToFit];
//convert the uilabel to image content
UIGraphicsBeginImageContextWithOptions(klabel.bounds.size, NO, [[UIScreen mainScreen] scale]);
[klabel.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * kicon = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// the rest of code is just use the image content as marker icon on google map.
kaliaMarker = [[GMSMarker alloc] init];
kaliaMarker.tappable = NO;
kaliaMarker.position = CLLocationCoordinate2DMake(21.283652, -157.836971);
kaliaMarker.infoWindowAnchor = CGPointMake(0.5, 0.5);
kaliaMarker.icon = kicon;
kaliaMarker.map = self.mapView;
targetLayer
myLabel.layer
,我将三角形添加到该层。问题是计算出来的
middleY
-12.4
,我猜它从我的UILabel的可见边界/框架中掉了出来,你就是看不到它

我想知道我应该怎么做,或者什么是适当的方法来增加我的UILabel的可见部分来显示这个小三角形

谢谢你们的帮助

另外,应该是这样的

但看起来是这样的。如果我把路径旋转90度,我可以看到半个三角形,当然在那里。因此,对于180度,整个三角形超出了无法看到的范围。。

实际上你的箭头在那里,你的背景是白色的,所以你看不到。为图层设置填充颜色

[triangleLayer setFillColor:[[UIColor redColor] CGColor]];

这段稍加修改的代码运行良好。我将该方法的参数更改为UIView,以便访问其背景颜色以使三角形具有相同的颜色,并使三角形点的y值与视图的高度成比例

- (void) addTriangleTipToLayer: (UIView *) view{
    CALayer *targetLayer = view.layer;
    [targetLayer setBackgroundColor: [UIColor whiteColor].CGColor];

    CGPoint startPoint = CGPointMake(0, targetLayer.frame.size.height);
    CGPoint endPoint = CGPointMake(15, targetLayer.frame.size.height);
    UIBezierPath *trianglePath = [UIBezierPath bezierPath];

    CGFloat middleX = (startPoint.x + endPoint.x) / 2;
    CGFloat middleY = targetLayer.frame.size.height * 1.8;

    CGPoint middlePoint = CGPointMake(middleX, middleY);

    [trianglePath moveToPoint:startPoint];
    [trianglePath addLineToPoint:middlePoint];
    [trianglePath addLineToPoint:endPoint];
    [trianglePath closePath];

    CAShapeLayer *triangleLayer = [CAShapeLayer layer];
    [triangleLayer setFillColor: view.backgroundColor.CGColor];
    [triangleLayer setPath:trianglePath.CGPath];
    [targetLayer addSublayer:triangleLayer];
}

我发现我的代码有问题

//convert the uilabel to image content
UIGraphicsBeginImageContextWithOptions(klabel.bounds.size, NO, [[UIScreen mainScreen] scale]);
没有为添加到uilabel的箭头层提供足够的空间。 我还用错误的方法添加了三角形。正确的代码应为:

[targetLayer setBackgroundColor: [UIColor whiteColor].CGColor];

CGFloat side = targetLayer.frame.size.height;

CGPoint startPoint = CGPointMake(targetLayer.frame.size.width / 2 - side / 2, side);
CGPoint endPoint = CGPointMake(targetLayer.frame.size.width / 2 + side / 2, side);
UIBezierPath *trianglePath = [UIBezierPath bezierPath];

CGFloat middleX = targetLayer.frame.size.width / 2;
CGFloat middleY = (side / 2) * tan(M_PI / 3) + side;
CGPoint middlePoint = CGPointMake(middleX, middleY);

[trianglePath moveToPoint:startPoint];
[trianglePath addLineToPoint:middlePoint];
[trianglePath addLineToPoint:endPoint];
[trianglePath closePath];

CAShapeLayer *triangleLayer = [CAShapeLayer layer];
[triangleLayer setFillColor: [UIColor whiteColor].CGColor];
[triangleLayer setPath:trianglePath.CGPath];
[targetLayer addSublayer:triangleLayer];
    //convert the uilabel to image content
UIGraphicsBeginImageContextWithOptions(CGRectMake(self.klabel.bounds.size.width, 2 * self.klabel.bounds.size.height), NO, [[UIScreen mainScreen] scale]);
这将为标签本身添加等边三角形中心。然后,绘制转换为图像的代码应为:

[targetLayer setBackgroundColor: [UIColor whiteColor].CGColor];

CGFloat side = targetLayer.frame.size.height;

CGPoint startPoint = CGPointMake(targetLayer.frame.size.width / 2 - side / 2, side);
CGPoint endPoint = CGPointMake(targetLayer.frame.size.width / 2 + side / 2, side);
UIBezierPath *trianglePath = [UIBezierPath bezierPath];

CGFloat middleX = targetLayer.frame.size.width / 2;
CGFloat middleY = (side / 2) * tan(M_PI / 3) + side;
CGPoint middlePoint = CGPointMake(middleX, middleY);

[trianglePath moveToPoint:startPoint];
[trianglePath addLineToPoint:middlePoint];
[trianglePath addLineToPoint:endPoint];
[trianglePath closePath];

CAShapeLayer *triangleLayer = [CAShapeLayer layer];
[triangleLayer setFillColor: [UIColor whiteColor].CGColor];
[triangleLayer setPath:trianglePath.CGPath];
[targetLayer addSublayer:triangleLayer];
    //convert the uilabel to image content
UIGraphicsBeginImageContextWithOptions(CGRectMake(self.klabel.bounds.size.width, 2 * self.klabel.bounds.size.height), NO, [[UIScreen mainScreen] scale]);

谢谢你们的帮助

我试过了,它不起作用,这很令人沮丧。什么时候调用
setClipsToBounds
,有关系吗?clipsToBounds默认为否,所以这不太可能起作用。@IanZhao:我试过你的代码,它对我有效,我唯一看到的是它被添加到了标签的左上角。不在底部left@rdelmar:是的,你是对的。我找到了真正的原因并更新了我的answer@MidhunMP太糟糕了,它仍然消失了,我已经更新了我的问题,以显示我对这个UILabel所做的其他事情,看看是否有帮助,但感谢你们确认我的箭的存在。