2011-03-09 10 views
14

Krumelurasked this question acerca de cómo crear una burbuja de destinatario similar a la de mail.app. Por favor, ver capturas de pantalla de lo que quiero decir:Recrear el comportamiento de burbuja del destinatario en Mail.app/Three20

Mail.app picker bubble picture

Selected contact

que puede crear la apariencia de este elemento (incluyendo el aspecto cuando se ha seleccionado), pero estoy luchando con conseguir el comportamiento cuando es parte de un UITextField. ¿Cómo se consigue que la burbuja actúe como parte del texto UITextField? Por ejemplo, cuando presiona el botón de retroceso lo suficiente, la burbuja se resalta y después de una pulsación más se eliminará como si fuera parte del texto. También tuve dificultades para mover el cursor también.

Preferiblemente la respuesta sería genial en Monotouch, pero las respuestas de Objective-C también son más que apreciadas. No estoy pidiendo el código exacto (aunque si está dispuesto a desprenderse de él, ¡no voy a decir que no!: D) sino a cómo lograrlo.

Conozco el proyecto Three20 que tiene un elemento similar pero no puedo encontrar en qué lugar del código se realiza realmente. Disculpa si esto no tiene mucho sentido. He luchado un poco para plantear esta pregunta de forma electiva. Por favor, siéntanse libres de hacerme cualquier aclaración sobre la pregunta.

+0

Disculpa por hacer realidad esta vieja pregunta. Pero, ¿puede mostrar el código de cómo lo implementó? ¿También tienes los archivos de imagen para la píldora azul? –

Respuesta

18

No me gusta Three20 haber tenido malas experiencias tratando de personalizar cosas, corregir las advertencias del analizador y hacerlo construir en Xcode 4. Nunca volveré a usarlo en un nuevo proyecto. Pero probablemente hará lo que quieras en este caso.

Sin embargo, puede hacer sus propias burbujas con bastante sencillez. Me gustaría poder darle crédito al autor del blog del que obtuve esto, pero fue hace dos años y ahora no puedo encontrarlo con Google. Básicamente, estás eligiendo un color, dibujando las tapas redondas, poniendo un rectángulo entre ellas y luego colocando el texto requerido sobre la parte superior.

UIGraphicsBeginImageContext(CGSizeMake(SIDELENGTH, SIDELENGTH)); 

CGContextRef context = UIGraphicsGetCurrentContext(); 

// the image should have a white background 
[[UIColor clearColor] set]; 
CGRect myRect = CGRectMake(0.0f, 0.0f, SIDELENGTH, SIDELENGTH); 
UIRectFill(myRect); 

[self.color set]; 

// Drawing code 
CGSize textSize = [self.text sizeWithFont:[UIFont boldSystemFontOfSize:[UIFont systemFontSize]]]; 

double capDiameter = textSize.height; 
double capRadius = capDiameter/2.0; 
double capPadding = capDiameter/4.0; 
double textWidth = MAX(capDiameter, textSize.width) ; 

CGRect textBounds = CGRectMake(capPadding, 0.0, textWidth, textSize.height); 

CGRect badgeBounds = CGRectMake(0.0, 0.0, textWidth + (2.0 * capPadding), textSize.height); 

double offsetX = (CGRectGetMaxX(myRect) - CGRectGetMaxX(badgeBounds))/2.0; 
double offsetY = (CGRectGetMaxY(myRect) - CGRectGetMaxY(badgeBounds))/2.0; 
badgeBounds = CGRectOffset(badgeBounds, offsetX, offsetY); 
textBounds = CGRectOffset(textBounds, offsetX, offsetY); 

CGContextFillEllipseInRect(context, 
          CGRectMake(badgeBounds.origin.x, badgeBounds.origin.y, capDiameter, capDiameter)); 

CGContextFillEllipseInRect(context, 
          CGRectMake(badgeBounds.origin.x + badgeBounds.size.width - capDiameter, badgeBounds.origin.y, 
             capDiameter, capDiameter)); 

CGContextFillRect(context, CGRectMake(badgeBounds.origin.x + capRadius, badgeBounds.origin.y, 
             badgeBounds.size.width - capDiameter, capDiameter)); 

if(self.textColor != nil) { 
    const CGFloat* colors = CGColorGetComponents(self.textColor.CGColor); 
    CGColorSpaceRef space = CGColorGetColorSpace(self.textColor.CGColor); 
    CGColorSpaceModel model = CGColorSpaceGetModel(space); 

    if(model == kCGColorSpaceModelMonochrome) 
     // monochrome color space has one grayscale value and one alpha 
     CGContextSetRGBFillColor(context, *(colors + 0), *(colors + 0), *(colors + 0), *(colors + 1)); 
    else 
     // else a R,G,B,A scheme is assumed. 
     CGContextSetRGBFillColor(context, *(colors + 0), *(colors + 1), *(colors + 2), *(colors + 3)); 
} else 
    // else use plain white 
    CGContextSetRGBFillColor(context, 1.0f, 1.0f, 1.0f, 1.0f); 

[self.text drawInRect:textBounds 
withFont:[UIFont boldSystemFontOfSize:[UIFont systemFontSize]] 
lineBreakMode:UILineBreakModeClip alignment:UITextAlignmentCenter]; 

UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

return image; 

El comportamiento botón de borrar usted describe es bastante simple también - una vez que haya un partido que está seleccionada y aceptada dibujar la burbuja en el punto de inserción y cambiar el marco de la UITextField para comenzar después de la burbuja.Si está al principio del cuadro UITextField y obtiene otra eliminación, elimine el UIImageView burbuja, restablezca el marco UITextField al lugar donde comenzó el UIImageView.

O podría utilizar un UIWebView como el campo de entrada de dirección en el que visualiza imágenes de burbujas creadas con el código que se muestra junto con el texto (consulte this StackOverflow question) a medida que lo edita. Solo necesitaría escribir un controlador para el método de delegado shouldChangeCharactersInRange para gestionar la eliminación de la dirección agregada, y la imagen de burbuja, si una burbuja es el elemento al que apunta la acción de eliminación.

+5

+1 por odiar Three20 ^^ –

+0

¿Podría explicar cómo implementaría esto? –

+0

El resultado del código es un UIImage, y lo más fácil es colocarlo en un UIImageView y luego colocarlo en su jerarquía de vistas como lo haría con cualquier otro UIView. –

4
+0

Gracias. He rebuscado en estos enlaces antes y realmente no he tenido mucha suerte en encontrar el código real que realiza el comportamiento que describí. Además, utilizo el marco de la IU de mensajes cuando la aplicación envía un correo electrónico; sin embargo, la aplicación también necesita la posibilidad de enviar un mensaje a través de nuestro propio sistema de mensajería, que estoy seguro de que el 'Marco de la interfaz de usuario de mensajería' no es compatible. . ¿Por favor corrígeme si estoy equivocado? – Luke

+0

Además, parece que el archivo que quiero es: https://github.com/facebook/three20/blob/development/src/Three20UI/Sources/TTPickerTextField.m – Luke

Cuestiones relacionadas