2010-09-20 16 views
5

Finalmente obtuve el lanzamiento de mi aplicación principal (Tap Play MMO, compruébalo ;-)) y ahora estoy trabajando para ampliarlo.Manera simple de usar botones con formas irregulares

Para hacer esto necesito tener un círculo que tenga cuatro botones separados, estos botones serán esencialmente cuartos. He llegado a la conclusión de que la imagen circular tendrá que estar construida con cuatro imágenes, una para cada trimestre, pero debido a la necesidad de formas de imagen rectangulares voy a terminar con una superposición, aunque la superposición será transparente.

¿Cuál es la mejor manera de hacer que esto funcione? Necesito algo realmente simple, he visto esto http://iphonedevelopment.blogspot.com/2010/03/irregularly-shaped-uibuttons.html

Antes pero todavía no lo había logrado. ¿Alguien capaz de ofrecer algún consejo?

En caso de que haga alguna diferencia Voy a desplegar en un marco iOS 3.x (habrá 4,2 abajo de la línea cuando sale 4.2 para el iPad)

Respuesta

5

no puedo ver, ¿por qué se necesita superposición .
Solo crea 4 botones y dale a cada uno una porción de tu imagen.

edición después comentario

ver este great project. Un ejemplo es exactamente lo que quieres hacer.

Funciona mediante la incorporación de la alfa-valor de un píxel en el sobrescrito

pointInside:withEvent: y una categoría de UIImage, que añade este método

- (UIColor *)colorAtPixel:(CGPoint)point { 
    // Cancel if point is outside image coordinates 
    if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, self.size.width, self.size.height), point)) { 
     return nil; 
    } 


    // Create a 1x1 pixel byte array and bitmap context to draw the pixel into. 
    // Reference: http://stackoverflow.com/questions/1042830/retrieving-a-pixel-alpha-value-for-a-uiimage 
    NSInteger pointX = trunc(point.x); 
    NSInteger pointY = trunc(point.y); 
    CGImageRef cgImage = self.CGImage; 
    NSUInteger width = self.size.width; 
    NSUInteger height = self.size.height; 
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    int bytesPerPixel = 4; 
    int bytesPerRow = bytesPerPixel * 1; 
    NSUInteger bitsPerComponent = 8; 
    unsigned char pixelData[4] = { 0, 0, 0, 0 }; 
    CGContextRef context = CGBitmapContextCreate(pixelData, 
               1, 
               1, 
               bitsPerComponent, 
               bytesPerRow, 
               colorSpace, 
               kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
    CGColorSpaceRelease(colorSpace); 
    CGContextSetBlendMode(context, kCGBlendModeCopy); 

    // Draw the pixel we are interested in onto the bitmap context 
    CGContextTranslateCTM(context, -pointX, pointY-(CGFloat)height); 
    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage); 
    CGContextRelease(context); 

    // Convert color values [0..255] to floats [0.0..1.0] 
    CGFloat red = (CGFloat)pixelData[0]/255.0f; 
    CGFloat green = (CGFloat)pixelData[1]/255.0f; 
    CGFloat blue = (CGFloat)pixelData[2]/255.0f; 
    CGFloat alpha = (CGFloat)pixelData[3]/255.0f; 
    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; 
} 
+0

Si fuera tan sencillo. Mi necesidad es una rotación de 45 grados, así que desafortunadamente no es tan simple. – David26th

+0

Ahora veo el problema – vikingosegundo

+0

@ David26th Vea mi edición – vikingosegundo

7

Saltar los botones y simplemente responder a toques en su vista que contiene el círculo.

Cree un CGPath para cada área que desee capturar toques, cuando su UIview recibe un toque, verifique la membresía dentro de las rutas.

[respuesta Editado para mostrar los detalles de implementación esqueleto - TomH]

Así es como me gustaría abordar el problema: (no he probado este código y la sintaxis puede que no sea del todo bien, pero esto es la idea general)

1) Utilizando PS o su aplicación de creación de imagen favorita, cree una png de los cuartos de círculos. Agrégalo a tu proyecto XCode.

2) Agregue una UIView a la IU. Establezca el contenido de la capa de UIView en png.

self.myView = [[UIView alloc] initWithRect:CGRectMake(10.0, 10.0, 100.0, 100,0)]; 
[myView.layer setContents:(id)[UIImage loadImageNamed:@"my.png"]]; 

3) Cree CGPaths que describan la región en la UIView que le interesa.

self.quadrantOnePath = CGPathCreateMutable(); 
CGPathMoveToPoint(self.quadrantOnePath, NULL, 50.0, 50.0); 
CGPathAddLineToPoint(self.quadrantOnePath, NULL, 100.0, 50.0); 
CGPathAddArc(self.quadrantOnePath, NULL, 50.0, 50.0, 50.0, 0.0, M_PI2, 1); 
CGPathCloseSubpath(self.quadrantOnePath); 

// create paths for the other 3 circle quadrants too! 

4) Añadir un UIGestureRecognizer y escuchar/observar por los grifos en la vista

UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)]; 
[tapRecognizer setNumberOfTapsRequired:2]; // default is 1 

5) Cuando tapRecognizer invoca su selector de destino

- (void)handleGesture:(UIGestureRecognizer *) recognizer { 

    CGPoint touchPoint = [recognizer locationOfTouch:0 inView:self.myView]; 
    bool processTouch = CGPathContainsPoint(self.quadrantOnePath, NULL, touchPoint, true); 

    if(processTouch) { 
    // call your method to process the touch 
    } 
} 

No se olvide de liberar todo cuando corresponda, use CGPathRelease para liberar rutas.

Otro pensamiento: Si el gráfico que está utilizando para representar los cuadrantes del círculo es simplemente un color relleno (es decir, sin gráficos extravagantes, efectos de capa, etc.), también podría usar las rutas que creó en el método drawRect de UIView dibujar los cuadrantes también Esto resolvería uno de los fallos del enfoque anterior: no hay una integración ajustada entre el gráfico y las rutas utilizadas para verificar los toques. Es decir, si intercambia el gráfico por algo diferente, cambia el tamaño del gráfico, etc., las rutas utilizadas para verificar los toques estarán desincronizadas. Potencialmente una pieza de código de alto mantenimiento.

+0

. Esta sería la solución ideal y menos complicada. ¿Puede dar más detalles sobre cómo hacer esto? – David26th

+0

Se editó la respuesta anterior para ilustrar un enfoque para hacerlo. – TomH

4

Aquí es un proyecto impresionante que resuelve el problema de los botones de forma irregular tan fácilmente: http://christinemorris.com/2011/06/ios-irregular-shaped-buttons/

+1

Otro enlace a la técnica a la que se hace referencia: [http://oleb.net/blog/2009/10/obshapedbutton-non-rectangular-buttons-on-the-iphone/](http://oleb.net/blog/2009/10/obshapedbutton-non-rectangular-buttons-on-the-iphone /) –

+0

Existe una increíble cantidad de funcionalidad en el proyecto vinculado por muy poco esfuerzo. Realmente vale la pena mirar! –

+0

esto es genial! esta debería ser la respuesta correcta! –

Cuestiones relacionadas