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
iOS: UIButton resize according to text length
提问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:
主要优点是:
- You don't need to programmatically set frames at all!
- If done right, you don't need to bother about resetting frames for orientation changes.
- Also, device changes needn't bother you (read, no need to code separately for different screen sizes).
- 您根本不需要以编程方式设置帧!
- 如果做得正确,你不必理会重置帧的方向变化。
- 此外,设备更改不需要打扰您(阅读,无需为不同的屏幕尺寸分别编码)。
A few disadvantages:
几个缺点:
- Not backward compatible - works only for iOS 6 and above.
- Need to get familiarised (but will save time later on).
- 不向后兼容 - 仅适用于 iOS 6 及更高版本。
- 需要熟悉(但稍后会节省时间)。
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:
要使用自动布局完成此操作,请尝试设置可变宽度约束:
You may also need to adjust your Content Hugging Priority
and Content Compression Resistance Priority
to get the results you need.
您可能还需要调整您的Content Hugging Priority
并Content 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.
您不需要设置任何宽度或高度 - 它是完全自动的。
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 的最小宽度:
回答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 contentInset
to the button:
您还可以添加contentInset
到按钮:
myButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 4, 8)
myButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 4, 8)
回答by Bart?omiej Semańczyk
Simply:
简单地:
- Create
UIView
as wrapper with auto layout to views around. - Put
UILabel
inside that wrapper. Add constraints that will stick tyour label to edges of wrapper. - Put
UIButton
inside your wrapper, then simple add the same constraints as you did forUILabel
. - Enjoy your autosized button along with text.
- 创建
UIView
为具有自动布局的包装器以查看周围的视图。 - 放在
UILabel
那个包装纸里面。添加将您的标签粘贴到包装边缘的约束。 - 放入
UIButton
您的包装器中,然后简单地添加与您对UILabel
. - 享受您的自动调整按钮和文本。
回答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
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 sizeToFit
does 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];
}