7

I need to add a tip at the centre middle of my UIView. What I am trying to achieve is a custom google maps marker as in the image below programmatically.

My code so far is just drawing a rectangular uiview without the triangular tip.

EDIT

I want my UIView to have a triangular tip at the bottom

UIView *infoView  =  [[UIView alloc] initWithFrame:CGRectMake(10, 85, screenWidth *0.25, 75)];
infoView.backgroundColor = [UIColor blueColor];
CGRect currentFrame = infoView.frame;


float strokeWidth = 3.0;
float HEIGHTOFPOPUPTRIANGLE = 75;
float WIDTHOFPOPUPTRIANGLE = screenWidth*0.25;
float borderRadius = 4;

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetLineWidth(context, strokeWidth);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);

// Draw and fill the bubble
CGContextBeginPath(context);
CGContextMoveToPoint(context, borderRadius + strokeWidth + 0.5f, strokeWidth + HEIGHTOFPOPUPTRIANGLE + 0.5f);
CGContextAddLineToPoint(context, round(currentFrame.size.width / 2.0f - WIDTHOFPOPUPTRIANGLE / 2.0f) + 0.5f, HEIGHTOFPOPUPTRIANGLE + strokeWidth + 0.5f);
CGContextAddLineToPoint(context, round(currentFrame.size.width / 2.0f) + 0.5f, strokeWidth + 0.5f);
CGContextAddLineToPoint(context, round(currentFrame.size.width / 2.0f + WIDTHOFPOPUPTRIANGLE / 2.0f) + 0.5f, HEIGHTOFPOPUPTRIANGLE + strokeWidth + 0.5f);
CGContextAddArcToPoint(context, currentFrame.size.width - strokeWidth - 0.5f, strokeWidth + HEIGHTOFPOPUPTRIANGLE + 0.5f, currentFrame.size.width - strokeWidth - 0.5f, currentFrame.size.height - strokeWidth - 0.5f, borderRadius - strokeWidth);
CGContextAddArcToPoint(context, currentFrame.size.width - strokeWidth - 0.5f, currentFrame.size.height - strokeWidth - 0.5f, round(currentFrame.size.width / 2.0f + WIDTHOFPOPUPTRIANGLE / 2.0f) - strokeWidth + 0.5f, currentFrame.size.height - strokeWidth - 0.5f, borderRadius - strokeWidth);
CGContextAddArcToPoint(context, strokeWidth + 0.5f, currentFrame.size.height - strokeWidth - 0.5f, strokeWidth + 0.5f, HEIGHTOFPOPUPTRIANGLE + strokeWidth + 0.5f, borderRadius - strokeWidth);
CGContextAddArcToPoint(context, strokeWidth + 0.5f, strokeWidth + HEIGHTOFPOPUPTRIANGLE + 0.5f, currentFrame.size.width - strokeWidth - 0.5f, HEIGHTOFPOPUPTRIANGLE + strokeWidth + 0.5f, borderRadius - strokeWidth);
CGContextClosePath(context);
CGContextDrawPath(context, kCGPathFillStroke);

[infoView drawRect:currentFrame];

[self.view addSubview:infoView];

enter image description here

RonoKim
  • 184
  • 1
  • 16
  • Question is not clear enough. Please add additional information. – casillas May 15 '17 at 15:00
  • Basically I want my UIView to have a triangular tip at the bottom – RonoKim May 15 '17 at 15:38
  • http://stackoverflow.com/questions/30650343/triangle-uiview-swift Here is a link that might help. – kps2501 May 15 '17 at 16:52
  • Use an `MKMapView` annotation: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/AnnotatingMaps/AnnotatingMaps.html – koen May 15 '17 at 19:08
  • For the future refference try to use https://www.paintcodeapp.com, it is a great tool to generate code for drawing custom views. – Zuzana Paulis May 17 '17 at 15:18

2 Answers2

10

You can try a UIImageView, then make sure when you import you enable the slicing, so if you change your view the image will scale properly.

Apparently you might be having an issue with UIView.clipsToBounds = true

If you want to use the drawing way, you can try this. I've coded in swift in the playground...

import UIKit

var balloon = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 250))
balloon.backgroundColor = UIColor.clear


let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: 200, y: 0))
path.addLine(to: CGPoint(x: 200, y: 200))

// Draw arrow
path.addLine(to: CGPoint(x: 120, y: 200))
path.addLine(to: CGPoint(x: 100, y: 250))
path.addLine(to: CGPoint(x: 80, y: 200))

path.addLine(to: CGPoint(x: 0, y: 200))
path.close()

let shape = CAShapeLayer()
//shape.backgroundColor = UIColor.blue.cgColor
shape.fillColor = UIColor.blue.cgColor
shape.path = path.cgPath
balloon.layer.addSublayer(shape)

balloon

example

Reference to use bezier path: Ref

Community
  • 1
  • 1
Danilo Gomes
  • 767
  • 5
  • 15
1

Objective c code

UIView *balloonView  =  [[UIView alloc] initWithFrame:CGRectMake(10,  85, 200, 250)];
balloonView.backgroundColor = [UIColor clearColor];

UIBezierPath* trianglePath = [UIBezierPath bezierPath];
[trianglePath moveToPoint:CGPointMake(0, 0)];
[trianglePath addLineToPoint:CGPointMake(200.0f,0.0f)];
[trianglePath addLineToPoint:CGPointMake(200.0f,200.0f)];

//Draw Line
[trianglePath addLineToPoint:CGPointMake(120.0f,200.0f)];
[trianglePath addLineToPoint:CGPointMake(100.0f,250.0f)];
[trianglePath addLineToPoint:CGPointMake(80.0f,200.0f)];

[trianglePath addLineToPoint:CGPointMake(0.0f,200.0f)];

CAShapeLayer *triangleMaskLayer = [CAShapeLayer layer];
triangleMaskLayer.fillColor = [UIColor blueColor].CGColor;
[triangleMaskLayer setPath:trianglePath.CGPath];

[balloonView.layer addSublayer:triangleMaskLayer];

[self.view addSubview:balloonView];
RonoKim
  • 184
  • 1
  • 16