首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何创建支持具有图像背景的动态多行文本的UIButton?

如何创建支持具有图像背景的动态多行文本的UIButton?
EN

Stack Overflow用户
提问于 2015-04-06 23:19:07
回答 2查看 1K关注 0票数 0

我试图在iOS上创建一个UI元素,它扩展或收缩以适应动态的,通常是多行文本。我需要在文字下面放一张图片,看起来很像一个信息泡泡。然而,我只需要在我的整个UI中的其中一个,所以一个表视图似乎过分-除非合理的必要。

为此,我尝试使用UILabel,但它对背景图像的支持似乎非常有限。我只能用它来平铺图像,这不是我想要的。

UIButton似乎是最简单的构造,应该合理地满足我的要求,但我无法让它工作。下面是在一个空的单视图应用程序中提取的代码形式。

代码语言:javascript
运行
复制
- (void)viewDidLoad {
  [super viewDidLoad];

  NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
  UIImage *image = [[UIImage imageNamed:@"speak_bubble_solid"] resizableImageWithCapInsets:UIEdgeInsetsMake(16, 24, 30, 12)];

  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  [button setBackgroundImage:image forState:UIControlStateNormal];
  [button setTitle:text forState:UIControlStateNormal];
  button.titleLabel.textColor = [UIColor whiteColor];
  button.titleLabel.textAlignment = NSTextAlignmentLeft;
  button.titleLabel.numberOfLines = 0;
  button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
  button.contentEdgeInsets = UIEdgeInsetsMake(16, 10, 30, 10);
  button.translatesAutoresizingMaskIntoConstraints = NO;

  [self.view addSubview:button];
  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[button]-|"
                                                                    options:NSLayoutFormatAlignAllTop
                                                                    metrics:0
                                                                      views:NSDictionaryOfVariableBindings(button)]];

}

这就是我运行这个应用程序时的样子:

显然,我正在寻找的是按钮来展开,以包含其内容。因此,即使最初的呈现也是错误的,但我也需要在以后动态更改文本时正确调整它的大小。

我怎么能创造这个呢?我需要在代码中看到答案,因为我在iOS开发方面还是很新的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-07 01:15:19

实际上,我要用的是标签和图像。不是背景图像:图像,在图像视图中。

  • 使标签包装,并垂直增长或缩小取决于其内容的大小。这很简单,而且是一个现成的、以前已经解决的问题。
  • 把标签的背景弄清楚。
  • 将图像视图限制到与标签后面的位置和大小相同。
  • 确保图像视图的内容模式是按比例填充的,这样图像的大小总是与图像视图的大小完全一致。
  • 给图像视图提供一个“可伸缩”的图像,这样不管图像视图的大小如何,它看起来都是正确的。

以下是我尝试使用不同长度的自包装标签文本时得到的一些屏幕截图:

这似乎很接近你想要的那种东西。在我的实现中,棘手的部分是调整图像视图的大小/位置,以响应标签大小的变化,并根据其内容更改其高度。我处理它的方法是设置从图像视图到标签的约束,使图像视图比标签更大,这样气球就会出现在标签的外部;然后,我将此代码添加到视图控制器中,以便根据标签(lab)的布局实时地进一步调整图像视图(lab):

代码语言:javascript
运行
复制
override func viewDidLayoutSubviews() {
    iv.bounds.size.height = lab.bounds.size.height + 60
    iv.frame.origin.y = lab.frame.origin.y - 20
}

编辑:但实际上不需要代码;它完全可以通过约束来完成,如我在github示例中所演示的:https://github.com/mattneub/MessageBubble

票数 3
EN

Stack Overflow用户

发布于 2015-04-07 18:39:29

另一种可能的方法是使用绘制的形状而不是图像作为背景。这需要比Matt的方法更多的代码,但如果您想要更改颜色或点的形状,则可能会提供更多的灵活性。我创建了一个名为UIView的RDLabelView类,它绘制背景形状,并将标签添加为子视图。它有一个text属性,所以您可以像设置标签一样设置它的文本。

代码语言:javascript
运行
复制
#import "RDLabelView.h"

@interface RDLabelView ()
@property (strong,nonatomic) UILabel *label;
@property (strong,nonatomic) CAShapeLayer *bubble;
@end

@implementation RDLabelView

-(void)awakeFromNib {

    self.tapper = [UITapGestureRecognizer new];
    [self addGestureRecognizer:self.tapper];
    self.bubble = [CAShapeLayer layer];
    self.bubble.fillColor = [UIColor colorWithRed:.5 green:1 blue:1 alpha:1].CGColor;
    [self.layer addSublayer:self.bubble];
    self.label = [UILabel new];
    self.label.numberOfLines = 0;
    self.label.translatesAutoresizingMaskIntoConstraints = NO;
    [self addSubview:self.label];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[label]-10-|" options:0 metrics:nil views:@{@"label":self.label}]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[label]-10-|" options:0 metrics:nil views:@{@"label":self.label}]];
}

-(void)setColor:(UIColor *)color { // The color property is declared in the .h file to allow color changes to the bubble
    _color = color;
    self.bubble.fillColor = _color.CGColor;
}

-(void)setText:(NSString *)text { // The text property is declared in the .h file to allow you to set the text as you would for a UILabel
    _text = text;
    self.label.text = text;
}

-(UIBezierPath *)appendShapeToRoundedRect:(UIBezierPath *) shape {
    CGPoint lowerLeftCorner = CGPointMake(0, shape.bounds.size.height);
    CGPoint pointToStart = CGPointMake(lowerLeftCorner.x + 30, lowerLeftCorner.y);
    UIBezierPath * arrow = [UIBezierPath bezierPath];
    [arrow moveToPoint:pointToStart];
    [arrow addLineToPoint:CGPointMake(pointToStart.x, pointToStart.y + 20)];
    [arrow addLineToPoint:CGPointMake(pointToStart.x + 10, pointToStart.y)];
    [shape appendPath:arrow];
    return shape;
}


-(void)layoutSubviews {
    [super layoutSubviews];
    UIBezierPath *shape = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:16];
    shape = [self appendShapeToRoundedRect:shape];
    self.bubble.path = shape.CGPath;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29481236

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档