2011-03-09 83 views
14

Krumelurasked this question关于如何创建类似于mail.app的收件人气泡。请看下面的截图我的意思:在Mail.app/Three20中重新创建收件人气泡行为

Mail.app picker bubble picture

Selected contact

我可以创建这个元素的外观(包括已经超出了它的模样),但我刚刚接到行为时,挣扎它是UITextField的一部分。你如何让泡泡充当UITextField文本的一部分?例如,当您按下退格按钮时,气泡会突出显示,并且在再次按下后,它将被删除,就好像它是文本的一部分。移动光标也遇到了困难。

最好在Monotouch中答案会很好,但是Objective-C的答案也不胜枚举。我并没有要求确切的代码(尽管如果你愿意与它分离,那么我不会说不!),而是如何实现这一点。

我知道Three20项目有一个类似的元素,但我无法找到代码中实际执行的地方。 对不起,如果这没有多大意义,我有点挣扎着摆出这个问题,请随时问我任何问题澄清问题!

+0

对不起提出这个老问题的生活。但是,你能告诉我们你的代码是如何实现的吗?你也有蓝色药丸的图像文件? – 2012-01-25 00:56:55

回答

18

我不喜欢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作为地址输入字段,在该地址输入字段中显示使用随文本显示的代码(请参阅this StackOverflow question)创建的气泡图像。您只需为委托方法shouldChangeCharactersInRange编写处理程序来处理删除添加的地址以及气泡图像(如果气泡是删除操作所针对的项目)。

+5

+1恨Three20 ^^ – 2011-03-20 13:34:04

+0

你能解释一下你怎么会执行这个? – 2012-07-19 02:23:17

+0

代码的结果是一个UIImage,并做是把它放在一个UIImageView,然后把它放在你的视图层次,你会任何tother UIView的最简单的事情。 – 2012-07-22 22:58:47

4
+0

谢谢 - 我已经通过这些链接scourered之前,并没有真正有很多运气找到执行我描述的行为的实际代码。另外,当应用程序发送电子邮件时,我确实使用了消息UI框架 - 但是该应用程序还需要能够通过我们自己的领域消息传递系统发送消息 - 我确定“消息传递UI框架”不支持。如果我错了,请纠正我? – Luke 2011-03-09 14:47:36

+0

另外,它似乎我想要的文件是:https://github.com/facebook/three20/blob/development/src/Three20UI/Sources/TTPickerTextField.m – Luke 2011-03-09 15:23:14