【问题标题】:Recreate recipient bubble behaviour in Mail.app / Three20在 Mail.app / Three20 中重新创建收件人气泡行为
【发布时间】:2011-03-09 14:18:37
【问题描述】:

Krumelurasked this question 关于如何创建类似于 mail.app 的收件人气泡。请看下面我的意思的截图:

我可以创建这个元素的外观(包括它被选中时的外观),但是当它是UITextField 的一部分时,我很难获得这种行为。如何让气泡充当 UITextField 文本的一部分?例如,当您按足够的退格按钮时,气泡会突出显示,再按一次后将被删除,就好像它是文本的一部分一样。我也很难移动光标。

最好是 Monotouch 中的答案很好,但 Objective-C 的答案也很受欢迎。我不是要求确切的代码(尽管如果您愿意放弃它,那么我不会拒绝!:D)而是如何实现这一点。

我知道 Three20 项目具有类似的元素,但我无法在代码中找到实际执行的位置。 很抱歉,如果这没有多大意义,我有点难以优雅地提出这个问题,请随时问我任何澄清问题的问题!

【问题讨论】:

  • 很抱歉让这个老问题栩栩如生。但是您能否展示一下您是如何实现这一点的代码。你还有蓝色药丸的图片文件吗?

标签: iphone ipad ios xamarin.ios three20


【解决方案1】:

我不喜欢 Three20 在尝试自定义事物、修复分析器警告并将其构建在 Xcode 4 中的糟糕经历。永远不会在新项目中再次使用它。但在这种情况下,它可能会做你想做的事。

但是,您可以相当简单地制作自己的气泡。我希望我能感谢我从中得到这个博客的作者,但那是两年前的事了,现在我在谷歌上找不到它。基本上,您选择一种颜色,绘制圆形端盖,在它们之间放置一个矩形,然后将所需的文本放在顶部。

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 编写一个处理程序来处理删除添加的地址和气泡图像,如果气泡是删除操作的目标项。

【讨论】:

  • 你能解释一下你将如何实现这个吗?
  • 代码的结果是一个 UIImage,最简单的方法是把它放在一个 UIImageView 中,然后像其他 UIView 一样把它放在你的视图层次结构中。
  • 所以文本从未在 UITextField 中?
  • 它可能是,或者不是 - 没关系。在上面的代码中,文本是使用 drawInRect 绘制的,虽然我没有显示它,但我将字符串作为参数传递。它可能来自 UITextField 或其他任何地方。
【解决方案2】:

当然,既然 Apple 发布了 Message UI framework,您就应该使用它。

【讨论】:

  • 谢谢 - 我之前浏览过这些链接,但并没有很幸运地找到执行我描述的行为的实际代码。此外,当应用程序发送电子邮件时,我确实使用消息 UI 框架 - 但是应用程序还需要能够通过我们自己的专有消息传递系统发送消息 - 我确信 Messaging UI Framework 不支持。如果我错了,请纠正我?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-20
  • 1970-01-01
  • 2019-04-04
  • 2012-01-01
  • 2018-06-28
  • 2015-04-23
  • 1970-01-01
相关资源
最近更新 更多