IOS:使用Autolayout调整UIButton高度取决于标题文本?

Pha*_*inh 6 iphone objective-c uibutton ios autolayout

我有一个UIButton它可以在运行时更改标题.因此,我想通过使用增加UIButton高度取决于标题文本以显示全文AutoLayout.

我可以UILabel通过设置height constraint为"大于或等于" 来增加高度,但它不起作用UIButton.
我用过[myButton sizeToFit]但它只增加UIButon宽度(不增加高度).

我现在的UIButton属性是
- 约束高度:30 - 领先:15 - 尾随:15 - 顶部:5 - fontsize:12

更新
我为约束高度创建了一个IBOutlet,UIButton用于更改高度@NSNood.
然后我需要\n在标题文本中使用分割线.
但我不知道我应该把它放在哪里\n

这是Button我想要的肖像

在此输入图像描述

这是Button我想要的景观 在此输入图像描述

我该如何确定放置的位置\n

请指导我如何实现它AutoLayout.任何帮助,将不胜感激.

Aya*_*pta 8

对不起,我最近没有关注这个帖子,因此我想出了一个真正的后期解决方案.如果有人可能在将来发现它有用的话,我仍然会将答案作为参考.

首先让我们展示按钮的故事板配置.这些如下图所示:

约束配置

图片显示我只为按钮添加了左,上,右约束,没有别的.这允许按钮有一些intrinsicContentSize高度,但它的宽度仍由它的左右约束决定.

下一阶段是编写一些包含按钮的ViewController类.在我的VC中,我按名称为按钮创建了一个插座button:

@property(nonatomic,weak) IBOutlet UIButton* button;
Run Code Online (Sandbox Code Playgroud)

并将其附加到故事板按钮.现在我已经重写两种方法,即,viewDidLoadviewWillLayoutSubviews象下面这样:

-(void)viewDidLoad {
    [super viewDidLoad];

    self.button.titleLabel.numberOfLines = 0;
    self.button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
}
-(void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    [self.button setTitle:@"Chapter One\n "
     "A Stop on the Salt Route\n "
     "1000 B.C.\n "
     "As they rounded a bend in the path that ran beside the river, Lara recognized the silhouette of a fig tree atop a nearby hill. The weather was hot and the days were long. The fig tree was in full leaf, but not yet bearing fruit." forState:UIControlStateNormal];
}
Run Code Online (Sandbox Code Playgroud)
  1. viewDidLoad方法确保titleLabel(包含按钮文本的标签)是多行的,如果有一些大文本,它会通过包装单词来包装文本.
  2. viewWillLayoutSubviews方法确保在主视图的边界改变时发生按钮布局过程,例如由于界面方向的改变.

最后和最有效的部分是手动处理按钮的布局过程.为此,我们需要子类UIButton.我编写了一个名为MyButton继承自的子类UIButton,您可以使用您喜欢的任何名称.将其设置为Identity Inspector中按钮的自定义类.

子类重写两个方法,即intrinsicContentSizelayoutSubviews.类主体看起来如下所示:

#import "MyButton.h"

@implementation MyButton

-(CGSize)intrinsicContentSize {
    return [self.titleLabel sizeThatFits:CGSizeMake(self.titleLabel.preferredMaxLayoutWidth, CGFLOAT_MAX)];;
}
-(void)layoutSubviews {
    self.titleLabel.preferredMaxLayoutWidth = self.frame.size.width;
    [super layoutSubviews];
}
@end
Run Code Online (Sandbox Code Playgroud)

UIButon子类取布局处理的通过重写所有权layoutSubviews方法.这里的基本思想是确定按钮宽度,一旦布局.然后将其宽度设置为preferredMaxLayoutWidth(布局引擎的最大宽度,多行标签应占用的宽度)其子项titleLabel(包含按钮文本的标签).最后,intrinsicContentSize根据按钮titleLabel的大小返回按钮,以便按钮完全包裹它titleLabel.

  1. layoutSubviews当按钮已经布局并且确定了帧的大小时,将调用被覆盖的内容.在它的第一步骤中,按钮的呈现宽度被设定为preferredMaxLayoutWidth按钮的的titleLabel.
  2. 通过调用第二步骤重新调用布点引擎[super layoutSubviews],从而使按钮intrinsicContentSize是基于它的重新确定titleLabelpreferredMaxLayoutWidth,其被设置为呈现宽度,由现在的按钮.
  3. 在重写intrinsicContentSize方法中,我们返回完全titleLabelpreferredMaxLayoutWidthset集合的按钮的最小拟合大小 .我们sizeThatFits在按钮上使用 拟合方法,titleLabel并且只是titleLabel不遵循任何基于约束的布局.

结果应该类似于您可能需要的结果.

肖像 景观

请随时告诉我任何其他澄清/关注.

谢谢.


tma*_*lla 1

要点是,如果您设置sizeToFit属性,那么文本将始终在一行中,并且按钮的宽度将增加,除非您放置下一行符号\n来明确表示您希望它是多行。

你把 '\n' 放在第一行的末尾,就像"line \n line"它代表

line
line
Run Code Online (Sandbox Code Playgroud)

如果您希望纵向横向\n有两个不同的字符串值(位置不同),您可以使用此处描述的( )检查方向条件,并根据设备的方向设置字符串值UIDeviceOrientationUIDevice.currentDevice.orientation