在界面构建器中,按住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];
在Xcode 4.5及更高版本中,现在可以使用“自动布局/约束”来完成。
主要优点是:
一些缺点:
最酷的是我们专注于声明一个意图,例如:
Here是一个简单的教程,介绍自动布局。
对于more details。
一开始需要一些时间,但看起来确实值得付出努力。
我有一些与sizeToFit
无法解决的帖子相关的额外需求。无论文本如何,我都需要将按钮保持在原始位置的中心位置。我也从不希望按钮大于原始尺寸。
因此,我将按钮布局为最大尺寸,在Controller中保存该尺寸,并在文本更改时使用以下方法调整按钮的大小:
+ (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];
}
此按钮类具有高度自动化文本(对于Xamarin但可以为其他语言重写)
[Register(nameof(ResizableButton))]
public class ResizableButton : UIButton
{
NSLayoutConstraint _heightConstraint;
public bool NeedsUpdateHeightConstraint { get; private set; } = true;
public ResizableButton(){}
public ResizableButton(UIButtonType type) : base(type){}
public ResizableButton(NSCoder coder) : base(coder){}
public ResizableButton(CGRect frame) : base(frame){}
protected ResizableButton(NSObjectFlag t) : base(t){}
protected internal ResizableButton(IntPtr handle) : base(handle){}
public override void LayoutSubviews()
{
base.LayoutSubviews();
UpdateHeightConstraint();
InvalidateIntrinsicContentSize();
}
public override void SetTitle(string title, UIControlState forState)
{
NeedsUpdateHeightConstraint = true;
base.SetTitle(title, forState);
}
private void UpdateHeightConstraint()
{
if (!NeedsUpdateHeightConstraint)
return;
NeedsUpdateHeightConstraint = false;
var labelSize = TitleLabel.SizeThatFits(new CGSize(Frame.Width - TitleEdgeInsets.Left - TitleEdgeInsets.Right, float.MaxValue));
var rect = new CGRect(Frame.X, Frame.Y, Frame.Width, labelSize.Height + TitleEdgeInsets.Top + TitleEdgeInsets.Bottom);
if (_heightConstraint != null)
RemoveConstraint(_heightConstraint);
_heightConstraint = NSLayoutConstraint.Create(this, NSLayoutAttribute.Height, NSLayoutRelation.Equal, 1, rect.Height);
AddConstraint(_heightConstraint);
}
public override CGSize IntrinsicContentSize
{
get
{
var labelSize = TitleLabel.SizeThatFits(new CGSize(Frame.Width - TitleEdgeInsets.Left - TitleEdgeInsets.Right, float.MaxValue));
return new CGSize(Frame.Width, labelSize.Height + TitleEdgeInsets.Top + TitleEdgeInsets.Bottom);
}
}
}
Swift 4.2
感谢上帝,这解决了。在为按钮设置文本后,您可以从UIView(官方文档是here)中检索intrinsicContentSize,这是自然大小。对于UIButton,您可以像下面一样使用它。
button.intrinsicContentSize.width
为了您的信息,我调整了宽度,使其看起来正确。
button.frame = CGRect(fx: xOffset, y: 0.0, width: button.intrinsicContentSize.width + 18, height: 40)
模拟器
UIButtons with intrinsicContentSize
资料来源:https://riptutorial.com/ios/example/16418/get-uibutton-s-size-strictly-based-on-its-text-and-font
在UIKit中,NSString类中还有一些内容可以从给定的NSString对象中获取它在以某种字体呈现时所占用的大小。
简而言之,如果你去:
CGSize stringsize = [myString sizeWithFont:[UIFont systemFontOfSize:14]];
//or whatever font you're using
[button setFrame:CGRectMake(10,0,stringsize.width, stringsize.height)];
...您将按钮的框架设置为您正在渲染的字符串的高度和宽度。
您可能想要在CGSize周围尝试一些缓冲区空间,但您将在正确的位置开始。
在代码中执行此操作的方法是:
[button sizeToFit];
如果您是子类并希望添加额外规则,则可以覆盖:
- (CGSize)sizeThatFits:(CGSize)size;
如果您的按钮是使用Interface Builder制作的,并且您要在代码中更改标题,则可以执行以下操作:
[self.button setTitle:@"Button Title" forState:UIControlStateNormal];
[self.button sizeToFit];
迅速:
这里重要的是你何时会调用.sizeToFit()
,它应该是在设置文本后显示所以它可以读取所需的大小,如果你以后更新文本,然后再次调用它。
var button = UIButton()
button.setTitle("Length of this text determines size", forState: UIControlState.Normal)
button.sizeToFit()
self.view.addSubview(button)
如果要调整文本大小而不是按钮,可以使用...
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;
sizeToFit无法正常工作。代替:
myButton.size = myButton.sizeThatFits(CGSize.zero)
你也可以添加contentInset
按钮:
myButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 4, 8)
只是:
UIView
作为包装,自动布局到周围的视图。UILabel
放在那个包装器里面。添加将tyour标签粘贴到包装器边缘的约束。UIButton
放入包装器中,然后简单地添加与UILabel
相同的约束。