Мне не нравится, что у Three20 были неудачные попытки настроить вещи, исправить предупреждения анализатора и сделать его встроенным в Xcode 4. Никогда больше не буду использовать его в новом проекте.Но он, вероятно, будет делать то, что вы хотите в этом случае.
Однако вы можете сделать свои собственные пузыри довольно просто.Хотелось бы отдать должное автору блога, с которого я это получил, но это было два года назад, и теперь я не могу найти его в Google.В основном вы выбираете цвет, рисуете круглые концевые колпачки, помещаете прямоугольник между ними, а затем помещаете нужный текст поверх.
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;
Поведение кнопки удаления, которое вы описываете, также довольно простое - когда вы выбрали и приняли совпадение, нарисуйте пузырь в точке вставки и измените рамку UITextField, чтобы начать после пузырька.Если вы находитесь в начале фрейма UITextField и получаете другое удаление, удалите всплывающее окно UIImageView, сбросьте фрейм UITextField туда, где раньше использовался UIImageView.
Или вы можете использовать UIWebView в качестве ввода адресаполе, в котором вы отображаете пузырьковые изображения, созданные с кодом, показанным вместе с текстом (см. этот вопрос StackOverflow ) при его редактировании.Вам просто нужно написать обработчик для метода делегата shouldChangeCharactersInRange для обработки удаления добавленного адреса и изображения пузырька, если пузырем является элемент, на который нацелено действие удаления.