2009-06-23 12 views
39

Muchas aplicaciones muestran una vista transparente con esquinas redondeadas y un indicador de actividad cuando se ejecuta una operación que consume mucho tiempo.¿Cómo se hace una vista recta redondeada con transparencia en el iPhone?

¿Cómo se realiza este redondeo? ¿Es posible hacerlo simplemente usando Interface Builder (ya que hay muchos lugares en los que me gustaría utilizar algo así)? O, ¿debería usar una vista de imagen con una imagen redondeada o estirable? ¿Necesito dibujar el fondo yo mismo?

Hasta ahora, he logrado obtener una vista básica con una transparencia similar configurando alphaValue en Interface Builder, sin embargo, no tiene esquinas redondeadas, y también la transparencia parece aplicarse a todas las subvistas (no quiero el texto y el indicador de actividad son transparentes; sin embargo, aunque configuré alphaValue en aquellos en IB, parece que se ignora).

Respuesta

47
view.layer.cornerRadius = radius; 

La forma más dura (que solía ser necesario en el primer iPhone SDK) es la creación de su propio UIView subclase con drawRect: método:

CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextSetRGBFillColor(context, 0,0,0,0.75); 

CGContextMoveToPoint(context, rect.origin.x, rect.origin.y + radius); 
CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y + rect.size.height - radius); 
CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + rect.size.height - radius, 
       radius, M_PI, M_PI/2, 1); //STS fixed 
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width - radius, 
         rect.origin.y + rect.size.height); 
CGContextAddArc(context, rect.origin.x + rect.size.width - radius, 
       rect.origin.y + rect.size.height - radius, radius, M_PI/2, 0.0f, 1); 
CGContextAddLineToPoint(context, rect.origin.x + rect.size.width, rect.origin.y + radius); 
CGContextAddArc(context, rect.origin.x + rect.size.width - radius, rect.origin.y + radius, 
       radius, 0.0f, -M_PI/2, 1); 
CGContextAddLineToPoint(context, rect.origin.x + radius, rect.origin.y); 
CGContextAddArc(context, rect.origin.x + radius, rect.origin.y + radius, radius, 
       -M_PI/2, M_PI, 1); 

CGContextFillPath(context); 

Nota: rect en este código debe tomarse a partir [self bounds] (o en cualquier ubicación donde lo desee), no tendrá sentido con rect pasado al método drawRect:.

+0

gracias! intentaré eso. – frankodwyer

+0

¿Todavía configuro la transparencia y el color, etc., a través de IB y cómo detengo la aplicación de alfa a las subvistas (texto/indicador de actividad)? Al menos creo que eso es lo que sucede, tanto el texto como la flecha parecen muy anemáticos/grises, como que el fondo viene a través del texto blanco. – frankodwyer

+0

Establezca el fondo transparente en IB y use un color de relleno semitransparente en el código. He actualizado la respuesta. – Kornel

7

En su opinión hacer esto en el método drawRect

float radius = 5.0f; 

CGRect rect = self.bounds; 
CGContextRef context = UIGraphicsGetCurrentContext(); 
rect = CGRectInset(rect, 1.0f, 1.0f); 

CGContextBeginPath(context); 
CGContextSetGrayFillColor(context, 0.5, 0.7); 
CGContextMoveToPoint(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect)); 
CGContextAddArc(context, CGRectGetMaxX(rect) - radius, CGRectGetMinY(rect) + radius, radius, 3 * M_PI/2, 0, 0); 
CGContextAddArc(context, CGRectGetMaxX(rect) - radius, CGRectGetMaxY(rect) - radius, radius, 0, M_PI/2, 0); 
CGContextAddArc(context, CGRectGetMinX(rect) + radius, CGRectGetMaxY(rect) - radius, radius, M_PI/2, M_PI, 0); 
CGContextAddArc(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect) + radius, radius, M_PI, 3 * M_PI/2, 0); 

CGContextClosePath(context); 
CGContextFillPath(context); 

Esto hará que su rectángulo redondeado para su vista. Puede encontrar un ejemplo completo en la muestra HeadsUpUI proporcionada con el SDK. HTH

79

A partir del iPhone SDK 3.0, puede simplemente usar la propiedad de la capa cornerRadius. Por ejemplo:

view.layer.cornerRadius = 10.0; 

En la misma línea, se puede cambiar la vista de color de borde y ancho:

view.layer.borderColor = [[UIColor grayColor] CGColor]; 
view.layer.borderWidth = 1; 
+0

¿Alguna idea de cómo puedo obtener un margen entre el borde y el contenido en el UILabel? – dlinsin

+0

No tengo conocimiento de ninguna forma de hacerlo. Con un UIButton, debería poder usar la propiedad contentEdgeInsets, pero UILabel no parece tener nada de eso. Tal vez simplemente cree un UIView con borde y esquinas redondeadas, luego agregue su UILabel como una subvista, ligeramente insertada. –

+0

Eso funciona como un encanto, ¡gracias! – dlinsin

8

I abstraje a cabo la respuesta de @ lostInTransit en esta función:

static void ContextAddRoundedRect(CGContextRef c, CGRect rect, CGFloat radius) { 
    CGFloat minX = CGRectGetMinX(rect); 
    CGFloat maxX = CGRectGetMaxX(rect); 
    CGFloat minY = CGRectGetMinY(rect); 
    CGFloat maxY = CGRectGetMaxY(rect); 

    CGContextMoveToPoint(c, minX + radius, minY); 
    CGContextAddArcToPoint(c, maxX, minY, maxX, minY + radius, radius); 
    CGContextAddArcToPoint(c, maxX, maxY, maxX - radius, maxY, radius); 
    CGContextAddArcToPoint(c, minX, maxY, minX, maxY - radius, radius); 
    CGContextAddArcToPoint(c, minX, minY, minX + radius, minY, radius); 
} 

lo que sitúa el camino hacia el contexto para que hagas con él lo que puede

CoreGraphics llamadas ligeramente diferentes y no cerrar el trazado, en caso de que desee añadir que

CGContextFillPath(c); 
+0

+1. Solo para mis notas, cierre la ruta usando 'CGContextFillPath (c);' o 'CGContextStrokePath (c)'. Puede ponerlos en una función de llamada y luego llamar a 'ContextAddRoundedRect' dos veces para obtener el contorno y el relleno. Algo como esto 'static void ContextAddRoundedRectWithOutline (CGContextRef c, CGRect rect, CGFloat radius, UIColor * outline, UIColor * fill)' –

Cuestiones relacionadas