2011-03-09 80 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