我正在尝试在 iOS 上创建一个 UI 元素,它可以扩展或收缩以适应动态的、通常是多行的文本.我需要在看起来很像消息气泡的文本下方放置一个图像.但是,我在整个 UI 中只需要其中一个,因此表格视图似乎有点过头了——除非有合理的必要性.
I'm trying to create a UI element on iOS that expands or contracts to fit dynamic, often multiline text. I need to put an image underneath the text that looks a lot like a message bubble. However, I only need one of these in my entire UI, so a table view seems overkill - unless reasonably necessary.
我已尝试为此目的使用 UILabel,但它似乎对背景图像的支持非常有限.我只能让它平铺图像,这不是我想要的.
I've tried to use a UILabel for this purpose, but it seems to have very limited support for background images. I can only get it to tile the image, which is not what I want.
似乎 UIButton 是最简单的构造,应该可以合理地完成我的要求,但我无法让它工作.这是一个在其他方面为空的单一视图应用程序中的代码提炼形式.
It seems that a UIButton is the simplest construct that should reasonably do what I'm asking, but I cannot get it to work. Here's a distilled form of the code in an otherwise empty single view app.
- (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)]];
}
这是我运行应用程序时的样子:
This is how it looks when I run the app:
显然,我正在寻找的是用于展开以包含其内容的按钮.所以即使最初的渲染是错误的,但是当我稍后动态更改文本时,我还需要正确调整它的大小.
Obviously, what I'm looking for is the button to expand to contain its content. So even the initial render is wrong, but I also need it to be sized correctly when I change the text dynamically later.
我怎样才能创建这个?我需要在代码中看到答案,因为我还是 iOS 开发的新手.
How can I create this? I need to see the answer in code, since I'm still very new in iOS development.
其实我会用的是标签和图片.不是背景图像:图像视图中的图像.
Actually what I would use is a label and an image. Not a background image: an image, in an image view.
使标签环绕,并根据其内容的大小垂直放大或缩小.这很简单,而且是一个现成的、以前解决过的问题.
Make the label wrap, and grow or shrink vertically depending on the size of its contents. That's easy and is a ready, previously solved problem.
使标签的背景清晰.
将图像视图限制在与标签相同的位置和大小.
Constrain the image view to the same position and size as the label, behind it.
确保图像视图的内容模式是按比例填充的,这样图像的大小将始终与图像视图的大小完全一致.
Make sure the image view's content mode is scale-to-fill, so that the image will be always be sized exactly to the size of the image view.
给图像视图一个可拉伸"的图像,这样无论图像视图的大小如何,它看起来都正确.
Give the image view an image that is "stretchable" so that it will look right no matter what size the image view is.
以下是我尝试此操作时得到的一些屏幕截图,其中包含不同长度的自包装标签文本:
Here are some screen shots of what I got when I tried this, with different lengths of self-wrapping label text:
这似乎非常接近您所追求的那种东西.在我的实现中,棘手的部分是调整图像视图的大小/位置,以响应标签在包装时的大小变化,并根据其内容改变其高度.我的解决方法是设置从图像视图到标签的约束,使图像视图大于标签,以便气球出现在标签的外部;然后,我将此代码添加到我的视图控制器中,以根据标签的布局(lab
)进一步实时调整图像视图(iv
):
That seems pretty close to the sort of thing you are after. The tricky part, in my implementation, is adjusting the size / position of the image view in response to changes in the size of the label as it wraps and changes its height in response to its content. The way I worked it out was to set constraints from the image view to the label, making the image view bigger than the label so that the balloon appears around the outside of the label; then, I added this code to my view controller to adjust the image view (iv
) further in real time in relation to the layout of the label (lab
):
override func viewDidLayoutSubviews() {
iv.bounds.size.height = lab.bounds.size.height + 60
iv.frame.origin.y = lab.frame.origin.y - 20
}
EDIT:但实际上不需要任何代码;正如我在这个 github 示例中所展示的那样,它可以完全通过约束来完成:https://github.com/mattneub/消息气泡
EDIT: But in fact no code is needed; it can be done entirely with constraints, as I demonstrate in this github example: https://github.com/mattneub/MessageBubble
这篇关于如何创建支持具有图像背景的动态多行文本的 UIButton?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!