iOS:UIButton 根据文本长度调整大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4135032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:03:14  来源:igfitidea点击:

iOS: UIButton resize according to text length

iosuibutton

提问by Oh Danny Boy

In interface builder, holding Command+ =will resize a button to fit its text. I was wondering if this was possible to do programmatically before the button was added to the view.

在界面构建器中,按住Command+=将调整按钮的大小以适合其文本。我想知道是否可以在将按钮添加到视图之前以编程方式执行此操作。

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button.titleLabel setFont:[UIFont fontWithName:@"Arial-BoldMT" size:12]];
[button addTarget:self action:@selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
// I need to know the width needed to accomodate NSStringVariable
[button setTitle:NSStringVariable forState:UIControlStateNormal]; 
// So that I can set the width property of the button before addSubview
[button setFrame:CGRectMake(10, 0, width, fixedHeight)];
[subNavigation addSubview:button];

采纳答案by codeburn

In Xcode 4.5 and above, this can now be done by using 'Auto-layouting / Constraints'.

在 Xcode 4.5 及更高版本中,现在可以通过使用“自动布局/约束”来完成。

Major advantages are that:

主要优点是:

  1. You don't need to programmatically set frames at all!
  2. If done right, you don't need to bother about resetting frames for orientation changes.
  3. Also, device changes needn't bother you (read, no need to code separately for different screen sizes).
  1. 您根本不需要以编程方式设置帧!
  2. 如果做得正确,你不必理会重置帧的方向变化。
  3. 此外,设备更改不需要打扰您(阅读,无需为不同的屏幕尺寸分别编码)。

A few disadvantages:

几个缺点:

  1. Not backward compatible - works only for iOS 6 and above.
  2. Need to get familiarised (but will save time later on).
  1. 不向后兼容 - 仅适用于 iOS 6 及更高版本。
  2. 需要熟悉(但稍后会节省时间)。

Coolest thing is we get to focus on declaring an intent such as:

最酷的事情是我们可以专注于声明一个意图,例如:

  • I want these two buttons to be of the same width; or
  • I need this view to be vertically centered and extend to a max entent of 10 pts from the superview's edge; or even,
  • I want this button/label to resize according to the label it is displaying!
  • 我希望这两个按钮的宽度相同;或者
  • 我需要这个视图垂直居中并从超级视图的边缘扩展到最大 10 pts;甚至,
  • 我希望这个按钮/标签根据它显示的标签调整大小!

Hereis a simple tutorial to get introduced to auto-layouting.

是一个介绍自动布局的简单教程。

For a more details.

欲了解更多详情

It takes some time at first, but it sure looks like it will be well worth the effort.

一开始需要一些时间,但看起来确实值得付出努力。

回答by Dan Ray

In UIKit, there are additions to the NSString class to get from a given NSString object the size it'll take up when rendered in a certain font.

在 UIKit 中,对 NSString 类进行了添加,以从给定的 NSString 对象获取以特定字体呈现时将占用的大小。

Docs was here. Now it's hereunder Deprecated.

文档在这里。现在,这里已过时之下。

In short, if you go:

简而言之,如果你去:

CGSize stringsize = [myString sizeWithFont:[UIFont systemFontOfSize:14]]; 
//or whatever font you're using
[button setFrame:CGRectMake(10,0,stringsize.width, stringsize.height)];

...you'll have set the button's frame to the height and width of the string you're rendering.

...您将按钮的框架设置为您正在渲染的字符串的高度和宽度。

You'll probably want to experiment with some buffer space around that CGSize, but you'll be starting in the right place.

您可能想在该 CGSize 周围尝试一些缓冲区空间,但您将从正确的位置开始。

回答by Daniel Wood

The way to do this in code is:

在代码中执行此操作的方法是:

[button sizeToFit];

If you are subclassing and want to add extra rules you can override:

如果您是子类化并想要添加额外的规则,您可以覆盖:

- (CGSize)sizeThatFits:(CGSize)size;

回答by guptron

If your button was made with Interface Builder, and you're changing the title in code, you can do this:

如果您的按钮是使用 Interface Builder 制作的,并且您正在更改代码中的标题,则可以执行以下操作:

[self.button setTitle:@"Button Title" forState:UIControlStateNormal];
[self.button sizeToFit];

回答by Juan Boero

Swift:

迅速:

The important thing here is whenwill you call the .sizeToFit(), it should be after setting the text to display so it can read the size needed, if you later update text, then call it again.

这里最重要的是,当你将调用.sizeToFit(),它应该是文本设置为显示器,因此它可以读取所需的大小,如果以后更新文本,然后再调用它之后。

var button = UIButton()
button.setTitle("Length of this text determines size", forState: UIControlState.Normal)
button.sizeToFit()
self.view.addSubview(button)

回答by Tad

To accomplish this using autolayout, try setting a variable width constraint:

要使用自动布局完成此操作,请尝试设置可变宽度约束:

Width Constraint

宽度约束

You may also need to adjust your Content Hugging Priorityand Content Compression Resistance Priorityto get the results you need.

您可能还需要调整您的Content Hugging PriorityContent Compression Resistance Priority获得您需要的结果。



UILabel is completely automatically self-sizing:

UILabel 是完全自动调整大小的

This UILabel is simply set to be centered on the screen (two constraints only, horizontal/vertical):

这个 UILabel 被简单地设置为在屏幕上居中(只有两个约束,水平/垂直):

It changes widths totally automatically:

它完全自动改变宽度:

You do not need to set anywidth or height - it's totally automatic.

您不需要设置任何宽度或高度 - 它是完全自动的。

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

Notice the small yellow squares are simply attached ("spacing" of zero). They automatically move as the UILabel resizes.

注意黄色的小方块只是简单地附加(“间距”为零)。当 UILabel 调整大小时,它们会自动移动。

Adding a ">=" constraint sets a minimum width for the UILabel:

添加 ">=" 约束设置 UILabel 的最小宽度:

enter image description here

在此处输入图片说明

回答by Logan

If you want to resize the text as opposed to the button, you can use ...

如果要调整文本而不是按钮的大小,可以使用 ...

button.titleLabel.adjustsFontSizeToFitWidth = YES;
button.titleLabel.minimumScaleFactor = .5;
// The .5 value means that I will let it go down to half the original font size 
// before the texts gets truncated

// note, if using anything pre ios6, you would use I think
button.titleLabel.minimumFontSize = 8;

回答by Hashem Aboonajmi

sizeToFit doesn't work correctly. instead:

sizeToFit 不能正常工作。反而:

myButton.size = myButton.sizeThatFits(CGSize.zero)

you also can add contentInsetto the button:

您还可以添加contentInset到按钮:

myButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 4, 8)

myButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 4, 8)

回答by Bart?omiej Semańczyk

Simply:

简单地:

  1. Create UIViewas wrapper with auto layout to views around.
  2. Put UILabelinside that wrapper. Add constraints that will stick tyour label to edges of wrapper.
  3. Put UIButtoninside your wrapper, then simple add the same constraints as you did for UILabel.
  4. Enjoy your autosized button along with text.
  1. 创建UIView为具有自动布局的包装器以查看周围的视图。
  2. 放在UILabel那个包装纸里面。添加将您的标签粘贴到包装边缘的约束。
  3. 放入UIButton您的包装器中,然后简单地添加与您对UILabel.
  4. 享受您的自动调整按钮和文本。

回答by nator333

Swift 4.2

斯威夫特 4.2

Thank god, this solved. After setting a text to the button, you can retrieve intrinsicContentSize which is the natural size from an UIView (the official document is here). For UIButton, you can use it like below.

感谢上帝,这解决了。为按钮设置文本后,您可以从 UIView(官方文档在这里)中检索自然大小的内在内容大小。对于 UIButton,您可以像下面那样使用它。

button.intrinsicContentSize.width

For your information, I adjusted the width to make it look properly.

为了您的信息,我调整了宽度以使其看起来正确。

button.frame = CGRect(fx: xOffset, y: 0.0, width: button.intrinsicContentSize.width + 18, height: 40)

Simulator

模拟器

UIButtons with intrinsicContentSize

具有内在内容大小的 UIButtons

Source: https://riptutorial.com/ios/example/16418/get-uibutton-s-size-strictly-based-on-its-text-and-font

来源:https: //riptutorial.com/ios/example/16418/get-uibutton-s-size-strictly-based-on-its-text-and-font

回答by raider33

I have some additional needs related to this post that sizeToFitdoes not solve. I needed to keep the button centered in it's original location, regardless of the text. I also never want the button to be larger than its original size.

我有一些与这篇文章相关的额外需求sizeToFit没有解决。无论文本如何,我都需要将按钮保持在其原始位置的中心。我也从不希望按钮大于其原始大小。

So, I layout the button for its maximum size, save that size in the Controller and use the following method to size the button when the text changes:

因此,我将按钮布局为其最大尺寸,将该尺寸保存在控制器中,并在文本更改时使用以下方法来调整按钮的尺寸:

+ (void) sizeButtonToText:(UIButton *)button availableSize:(CGSize)availableSize padding:(UIEdgeInsets)padding {    

     CGRect boundsForText = button.frame;

    // Measures string
    CGSize stringSize = [button.titleLabel.text sizeWithFont:button.titleLabel.font];
    stringSize.width = MIN(stringSize.width + padding.left + padding.right, availableSize.width);

    // Center's location of button
    boundsForText.origin.x += (boundsForText.size.width - stringSize.width) / 2;
    boundsForText.size.width = stringSize.width;
    [button setFrame:boundsForText];
 }