Odtworzyć zachowanie bańki odbiorcy w poczcie.app / Three20

Krumelur zadał to pytanie o tym, jak utworzyć bańkę odbiorcy podobną do poczty.app. Zobacz zrzuty ekranu poniżej tego, co mam na myśli:

Poczta.picker aplikacji bubble picture

Wybrany kontakt

Mogę stworzyć wygląd tego elementu (włącznie z wyglądem, gdy został wybrany), ale zmagam się z uzyskaniem zachowania, gdy jest częścią UITextField. Jak sprawić, by bańka działała jako część tekstu UITextField? Na przykład, gdy naciśniesz wystarczająco przycisk backspace, bańka zostanie podświetlona i po jednym naciśnięciu zostanie usunięta tak, jakby była częścią tekstu. Miałem również trudności z poruszaniem kursorem.

Najlepiej, aby odpowiedź była świetna w MonoTouch, ale odpowiedzi Objective-C są bardziej niż doceniane. Nie proszę o dokładny kod (choć jeśli chcesz się z nim rozstać, to nie powiem nie! : D) ale raczej jak to osiągnąć.

Znam projekt Three20, który ma podobny element, ale nie mogę znaleźć gdzie abouts w kodzie to jest rzeczywiście wykonywane. Przepraszam, jeśli to nie ma większego sensu, trochę starałem się postawić to pytanie, proszę o zadawanie pytań wyjaśniających pytanie!

Author: Community, 2011-03-09

2 answers

Nie podoba mi się, że Three20 miał złe doświadczenia próbując dostosować rzeczy, naprawić Ostrzeżenia analizatora i zbudować go w Xcode 4. Nigdy nie użyje go ponownie w nowym projekcie. Ale prawdopodobnie zrobi to, co chcesz w tym przypadku.

Jednak można zrobić własne pęcherzyki dość prosto. Szkoda, że nie mogę pochwalić autora bloga, od którego to dostałem, ale to było dwa lata temu i teraz nie mogę go znaleźć w Google. Zasadniczo wybierasz kolor, rysujesz okrągłe końcówki, umieszczenie prostokąta między nimi, a następnie umieszczenie wymaganego tekstu na górze.

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;

Zachowanie przycisku delete, które opisujesz, jest dość proste - Po wybraniu i zaakceptowaniu dopasowania narysuj bańkę w punkcie wstawiania i zmień ramkę pola UITextField, aby rozpocząć po bańce. Jeśli znajdujesz się na początku Ramki UITextField i otrzymujesz kolejne usunięcie, Usuń Bubble UIImageView, zresetuj ramkę UITextField do miejsca, w którym została użyta UIImageView zaczynaj.

Lub możesz użyć UIWebView jako pola wprowadzania adresu, w którym wyświetlane są obrazy bąbelkowe utworzone z kodem pokazanym wraz z tekstem (zobacz to pytanie Stoskoverflow ) podczas edycji. Wystarczy napisać obsługę metody delegate shouldChangeCharactersInRange do obsługi usuwania dodanego adresu i obrazu bąbelka, jeśli bąbelek jest elementem, na który skierowana jest akcja delete.

 18
Author: Adam Eberbach,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:29:45
 4
Author: slf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-09 14:36:07