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

问题描述 投票:121回答:12

在界面构建器中,按住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];
ios uibutton
12个回答
5
投票

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

主要优点是:

  1. 您根本不需要以编程方式设置框架!
  2. 如果操作正确,则无需为了更改方向而重置帧。
  3. 此外,设备更改无需打扰您(阅读,不需要为不同的屏幕尺寸单独编码)。

一些缺点:

  1. 不向后兼容 - 仅适用于iOS 6及更高版本。
  2. 需要熟悉(但以后会节省时间)。

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

  • 我希望这两个按钮具有相同的宽度;要么
  • 我需要这个视图垂直居中,并从超视图的边缘延伸到最多10个点;甚至,
  • 我希望这个按钮/标签根据它显示的标签调整大小!

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

对于more details

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


3
投票

我有一些与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];
 }

1
投票

此按钮类具有高度自动化文本(对于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);
         }
     }
}

0
投票

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


126
投票

在UIKit中,NSString类中还有一些内容可以从给定的NSString对象中获取它在以某种字体呈现时所占用的大小。

文件是here。现在它是在贬值的here

简而言之,如果你去:

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

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

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


98
投票

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

[button sizeToFit];

如果您是子类并希望添加额外规则,则可以覆盖:

- (CGSize)sizeThatFits:(CGSize)size;

31
投票

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

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

19
投票

迅速:

这里重要的是你何时会调用.sizeToFit(),它应该是在设置文本后显示所以它可以读取所需的大小,如果你以后更新文本,然后再次调用它。

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

16
投票

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

Width Constraint

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


UILabel完全自动调整大小:

这个UILabel只是设置在屏幕中心(仅限两个约束,水平/垂直):

它会自动更改宽度:

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

enter image description here

enter image description here

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

添加“> =”约束可设置UILabel的最小宽度:

enter image description here


14
投票

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

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;

6
投票

sizeToFit无法正常工作。代替:

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

你也可以添加contentInset按钮:

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


5
投票

只是:

  1. 创建UIView作为包装,自动布局到周围的视图。
  2. UILabel放在那个包装器里面。添加将tyour标签粘贴到包装器边缘的约束。
  3. UIButton放入包装器中,然后简单地添加与UILabel相同的约束。
  4. 享受自动调整按钮和文本。
© www.soinside.com 2019 - 2024. All rights reserved.