我有一个UIButton
,它可以在运行时更改标题。因此,我希望使用UIButton
增加AutoLayout
高度,具体取决于标题文字以显示全文。
我可以通过将UILabel
设置为"大于或等于"来增加height constraint
高度但它不适用于UIButton
我使用了[myButton sizeToFit]
,但它只增加UIButon
宽度(不增加高度)。
我现在的UIButton
属性现在是
- 约束高度:30
- 领先:15
- 尾随:15
- 前5
- fontsize:12
更新
我创建了一个约束高度为UIButton
的IBOutlet,用于更改@NSNood
所说的高度
然后我需要在标题文本中使用\n
来分割线
但我不知道我应该把\n
放在哪里?
以下是我想要的Button
如何确定放置\n
的位置?
请指导我如何使用AutoLayout
来实现它。任何帮助,将不胜感激。
答案 0 :(得分:8)
很抱歉,我最近没有关注这个帖子,因此我想出了一个真正的后期解决方案。如果有人可能在将来发现它有用,我仍然可以将答案作为参考。
首先让我们展示按钮的故事板配置。这些描述如下:
图片显示我只为按钮添加了左,上,右约束,没有别的。这允许按钮的高度为intrinsicContentSize
,但它的宽度仍由其左右约束决定。
下一阶段是编写一些包含按钮的ViewController类。在我的VC中,我已经按名称button
:
@property(nonatomic,weak) IBOutlet UIButton* button;
并将其附加到故事板按钮。现在我已经覆盖了两个方法,即viewDidLoad
和viewWillLayoutSubviews
,如下所示:
-(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];
}
viewDidLoad
方法可确保titleLabel
(标签)
保持按钮文本)是多行的,如果有一些大文本来到它,
它通过包装文字来包装文本。viewWillLayoutSubviews
方法确保按钮布局过程
每当主视图的边界改变时发生,例如,因为
改变界面方向。最后也是最有效的部分是手动处理按钮的布局过程。为此,我们需要继承UIButton
。我编写了一个名为MyButton
的子类,它继承自UIButton
,您可以使用您喜欢的任何名称。将其设置为Identity Inspector中按钮的自定义类。
子类重写了两个方法,即intrinsicContentSize
和layoutSubviews
。类主体看起来如下所示:
#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
UIButon
子类通过覆盖layoutSubviews
方法获取布局过程的所有权。这里的基本思想是确定按钮宽度,一旦布局。然后将宽度设置为preferredMaxLayoutWidth
(布局引擎的最大宽度,多线标签应占用的最大宽度)的子titleLabel
(包含按钮文本的标签)。最后,根据按钮intrinsicContentSize
的大小返回titleLabel
按钮,以便按钮完全包裹它titleLabel
。
layoutSubviews
布局并确定它的框架尺寸。在它的第一步,
按钮的渲染宽度设置为preferredMaxLayoutWidth
按钮' titleLabel
。[super
layoutSubviews]
重新调用布局引擎,以便按钮intrinsicContentSize
为
根据它titleLabel
重新确定
preferredMaxLayoutWidth
,设置为按钮渲染宽度,
到现在为止。intrinsicContentSize
方法中,我们返回
完全包裹它的按钮的最小装配尺寸
设置titleLabel
的{{1}}。我们用
preferredMaxLayoutWidth
符合按钮sizeThatFits
的方法
只是作为titleLabel
没有遵循任何基于约束的工作
布局。结果应该类似于您可能需要的结果。
请随时告诉我任何其他澄清/关注事项。
感谢。
答案 1 :(得分:1)
关键是,如果您设置了sizeToFit
属性,那么文本将始终在一行中,并且按钮的宽度将会增加,除非您将下一行符号\n
明确说出你希望它是几行。
你将'\ n'放在第一行的末尾,如"line \n line"
代表
line
line
如果您希望人像和风景有两个不同的字符串值(\n
位置不同),您可以使用{{1}检查方向条件(UIDeviceOrientation
)described here并根据设备的方向设置字符串值
答案 2 :(得分:1)
对您的UIButton进行子类化以获取布局过程的所有权:
/// https://stackoverflow.com/a/50575588/1033581
class AutoLayoutButton: UIButton {
override var intrinsicContentSize: CGSize {
return titleLabel!.sizeThatFits(CGSize(width: titleLabel!.preferredMaxLayoutWidth, height: .greatestFiniteMagnitude))
}
override func layoutSubviews() {
titleLabel?.preferredMaxLayoutWidth = frame.size.width
super.layoutSubviews()
}
}
在故事板中使用此类,并为“前导”,“尾随”,“上”,“下”设置约束。但是不要设置任何高度限制。
没有子类化的替代方法是按照Bartłomiej Semańczyk answer和Timur Bernikowich comment的建议添加包装器视图。
答案 3 :(得分:0)
我一直使用一种方法:
完成。 :)
PS1。这种方法可用于滚动视图中的按钮和参考标签。
PS2。在某些情况下,我们无法获得正确的ref标签高度,因为它无法在滚动视图中获得正确的frame.width,特别是当我们使用尾随约束时。我们可以考虑在sizeTofit之前为ref标签定义一个固定宽度,并为目标按钮使用获取正确的高度。