32 votos

Cómo dibujar una "burbuja" en un iPhone?

Estoy tratando de conseguir una "burbuja" efecto similar a la de Mac OS X cuando se haga clic derecho sobre algo en el dock. He aquí lo que tengo ahora:

alt text

Necesito conseguir el "triángulo" de la parte inferior. Es allí cualquier manera de la que puedo sacar algo como eso, y obtener un borde a su alrededor? Este será un iPhone app.

Gracias de antemano!

EDIT: Muchas gracias a Brad Larson, he aquí lo que se ve ahora: alt text

44voto

Brad Larson Puntos 122629

De hecho, he sacado esta forma exacta antes (rectángulo redondeado con un triángulo en la parte inferior). El Cuarzo dibujo código que he utilizado es el siguiente:

CGRect currentFrame = self.bounds;

CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetLineWidth(context, strokeWidth);
CGContextSetStrokeColorWithColor(context, [MyPopupLayer popupBorderColor]); 
CGContextSetFillColorWithColor(context, [MyPopupLayer popupBackgroundColor]);

// 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);

// Draw a clipping path for the fill
CGContextBeginPath(context);
CGContextMoveToPoint(context, borderRadius + strokeWidth + 0.5f, round((currentFrame.size.height + HEIGHTOFPOPUPTRIANGLE) * 0.50f) + 0.5f);
CGContextAddArcToPoint(context, currentFrame.size.width - strokeWidth - 0.5f, round((currentFrame.size.height + HEIGHTOFPOPUPTRIANGLE) * 0.50f) + 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, round((currentFrame.size.height + HEIGHTOFPOPUPTRIANGLE) * 0.50f) + 0.5f, currentFrame.size.width - strokeWidth - 0.5f, round((currentFrame.size.height + HEIGHTOFPOPUPTRIANGLE) * 0.50f) + 0.5f, borderRadius - strokeWidth);
CGContextClosePath(context);
CGContextClip(context);     

El trazado de recorte al final puede quedar fuera si no vas a usar un degradado o algunos otros más relleno que es más complejo que un simple color.

12voto

Dave DeLong Puntos 156978

Tal vez una simple pregunta es "¿hay código que hace esto para mí ya", a la cual la respuesta es "Sí".

He aquí MAAttachedWindow:

alt text

Por supuesto, usted no puede desear toda la "Adjunta" ventana de comportamiento, pero al menos el código de dibujo ya está ahí. (Y Matt Gemmell del código es de alta calidad, material)

5voto

Tim Puntos 33042

Hay dos maneras que usted puede ser capaz de lograr esto:

  1. Añadir un UIImageView con un triángulo de la imagen en el lugar correcto. Asegúrese de que el resto de la imagen es transparente a fin de no bloquear el fondo.
  2. Reemplazar el drawRect: método en el UIView a la costumbre-dibujar la vista. A continuación, puede agregar lineal de los componentes de la trayectoria de su triángulo, llenado y bordeando la ruta de acceso según sea necesario.

Para dibujar un triángulo usando drawRect:, usted podría hacer algo como esto. Este fragmento nos dibuja un triángulo apuntando hacia abajo en la parte inferior de la vista.

// Get the context
CGContextRef context = UIGraphicsGetCurrentContext();

// Pick colors
CGContextSetStrokeColorWithColor(context, [[UIColor blackColor] CGColor]);
CGContextSetFillColorWithColor(context, [[UIColor redColor] CGColor]);

// Define triangle dimensions
CGFloat baseWidth = 30.0;
CGFloat height = 20.0;

// Define path
CGContextMoveToPoint(context, self.bounds.size.width / 2.0 - baseWidth / 2.0, 
                              self.bounds.size.height - height);
CGContextAddLineToPoint(context, self.bounds.size.width / 2.0 + baseWidth / 2.0, 
                                 self.bounds.size.height - height);
CGContextAddLineToPoint(context, self.bounds.size.width / 2.0, 
                                 self.bounds.size.height);

// Finalize and draw using path
CGContextClosePath(context);
CGContextStrokePath(context);

Para obtener más información, consulte la CGContext de referencia.

1voto

ExitToShell Puntos 435

Ver el triángulo en el menú emergente en la imagen de abajo, eso es dibujado con Núcleo de Gráficos funcs y es totalmente escalable.

alt text

Hecho como este para hacer un triángulo equilátero (de la vieja escuela de los nombres de función, lo siento):

#define triH(v) (v * 0.866)    

func(CGContextRef inContext, CGRect arrowRect, CustomPushButtonData* controlData) {
// Draw the triangle
float   arrowXstart, arrowYstart;
float   arrowXpos, arrowYpos, arrowHpos; 

if (controlData->controlEnabled && controlData->controlActive) {

    CGContextSetRGBFillColor(inContext, 0., 0., 0., 1.);

} else {

    CGContextSetRGBFillColor(inContext, 0., 0., 0., 0.5);

}

arrowHpos = triH(arrowRect.size.height);

// Point C

CGContextBeginPath(inContext);

arrowXstart = arrowXpos = (arrowRect.origin.x + ((float)(arrowRect.size.width / 2.) - (arrowSize / 2.)));

arrowYstart = arrowYpos = (arrowRect.origin.y + (float)((arrowRect.size.height / 2.) - (float)(arrowHpos / 2.)));

CGContextMoveToPoint(inContext, arrowXpos, arrowYpos);

// Point A

arrowXpos += arrowSize;

CGContextAddLineToPoint(inContext, arrowXpos, arrowYpos);

// Point B

arrowYpos += arrowHpos;

arrowXpos -= (float)(arrowSize / 2.0);

CGContextAddLineToPoint(inContext, arrowXpos, arrowYpos);

// Point C
CGContextAddLineToPoint(inContext, arrowXstart, arrowYstart);

CGContextClosePath(inContext);

CGContextFillPath(inContext);

}

Tenga en cuenta que el triH(x) func es una optimizado fórmula para calcular la altura de un equitlateral triángulo por ejemplo, h = 1/2 * sqrt(3) * x . Desde 1/2 * sqrt(3) nunca cambia, yo optimizado en que definir.

-1voto

Linuxmint Puntos 1503

Probablemente voy a hacer toda la imagen (incluyendo el triángulo) en Photoshop, y luego mostrarla en la pantalla en el momento adecuado el uso de la:

CGRect myRect = CGRectMake(10.0f, 0.0f, 300.0f, 420.0f);
UIImageView *myImage = [[UIImageView alloc] initWithFrame:myRect];
[myImage setImage:[UIImage imageNamed:@"ThisIsMyImageName.png"]];
myImage.opaque = YES;
[self.view addSubview:myImage];
[myImage release];

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X