更新:我为UIButton的约束高度创建了一个IBOutlet,以便根据@NSNood的建议更改高度。然后我需要在标题文本中使用\n来分割行。但我不知道应该在哪里放置\n?
这是我想要的纵向按钮。 Here is the Button that I want in landscape
![enter image description here](https://istack.dev59.com/8XCjj.webp)
请指导我如何使用 AutoLayout 实现。任何帮助将不胜感激。
很抱歉我最近没有遵循这篇帖子,因此现在提供一个很晚的解决方案。我仍会写出答案作为参考,如果未来有人发现它有用。
首先让我们展示按钮的故事板配置,如下图所示:
图片显示,我只添加了按钮的左、上和右侧约束,没有其他约束。这允许按钮具有一些intrinsicContentSize高度,但其宽度仍由其左右约束确定。
下一步是编写一些ViewController类,其中包含该按钮。在我的VC中,我通过名称button
创建了一个按钮的outlet:
@property(nonatomic,weak) IBOutlet UIButton* button;
并将其附加到Storyboard按钮上。现在我已经覆盖了两种方法,即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
方法来掌控布局过程。基本思想是确定按钮的宽度,一旦它被布置。然后将宽度设置为其子标签titleLabel
(保存按钮文本的标签)的preferredMaxLayoutWidth
(布局引擎应占用的多行标签的最大宽度)。最后,根据其titleLabel
的大小为按钮返回一个intrinsicContentSize
,以使按钮完全包裹其titleLabel
。
layoutSubviews
。在第一步中,将按钮的渲染宽度设置为按钮的titleLabel
的preferredMaxLayoutWidth
。[super layoutSubviews]
重新调用布局引擎,从而基于其titleLabel
的preferredMaxLayoutWidth
(现在已设置为按钮的渲染宽度),重新确定按钮的intrinsicContentSize
。intrinsicContentSize
方法中,我们返回完全包裹其titleLabel
的按钮的最小适合尺寸,并设置preferredMaxLayoutWidth
。我们在按钮的titleLabel
上使用sizeThatFits
方法,它简单地作为titleLabel
不遵循任何基于约束的布局。结果应该类似于您所要求的内容。
如有任何其他澄清/关注事项,请随时让我知道。
谢谢。
UIButton
的子类是一个好的解决方案。如果您不想创建UIButton
的子类,您仍然可以创建包装器视图。 - Timur BernikovichcontentEdgeInsets
和titleEdgeInsets
来计算正确的宽度,以便正确地使用preferredMaxLayoutWidth
。 - Claus JørgensenimageEdgeInsets
。但我只是不想让我的答案变得复杂,并且只提供基本思路。考虑到其他参数留给任何感兴趣的人作为练习;但这根据定义并不是一个错误。 - Ayan SenguptaAyan Sengupta提供的Swift解决方案,支持contentEdgeInsets(感谢Claus Jørgensen):
(如果需要,您还可以进一步自定义代码以考虑titleEdgeInsets)
Subclass your UIButton to take the ownership of the layout process:
/// https://dev59.com/BFsW5IYBdhLWcg3wyJt3#50575588
class AutoLayoutButton: UIButton {
override var intrinsicContentSize: CGSize {
var size = titleLabel!.sizeThatFits(CGSize(width: titleLabel!.preferredMaxLayoutWidth - contentEdgeInsets.left - contentEdgeInsets.right, height: .greatestFiniteMagnitude))
size.height += contentEdgeInsets.left + contentEdgeInsets.right
return size
}
override func layoutSubviews() {
titleLabel?.preferredMaxLayoutWidth = frame.size.width
super.layoutSubviews()
}
}
Use this class in your storyboard, and set constraints for Leading, Trailing, Top, Bottom. But don't set any Height constraint.
如果不想使用子类化的替代方法是添加一个包装视图,正如Bartłomiej Semańczyk回答和Timur Bernikowich评论所建议的。
preferredMaxLayoutWidth
需要考虑 contentEdgeInsets
和 titleEdgeInsets
来计算正确的宽度。 - Claus JørgensencontentEdgeInsets
的支持。关于 titleEdgeInsets
,它的文档中写道“按钮不使用此属性来确定 intrinsicContentSize”,所以我会在我的回答中忽略它,但是您可以根据自己的需求自定义代码。 - CœursizeToFit
属性,那么文本将始终在一行中,并且按钮的宽度将增加,除非您放置一个换行符\n
来明确表示您希望它成为多行。"line \n line"
这样在第一行的末尾放置'\n'来表示。line
line
\n
位置不同)来表示纵向和横向,您可以使用UIDeviceOrientation
(UIDevice.currentDevice.orientation
)在此处描述检查方向条件,并根据设备的方向设置字符串值。sizeToFit
并不适用于自动布局。 - Ayan SenguptasizeToFit
,因为他最初尝试使用它。 - tmac_balla我一直使用的方法如下:
完成。:)
PS1.此方法可用于滚动视图中的按钮和参考标签。
PS2.在某些情况下,由于在滚动视图中无法获得正确的frame.width,特别是当我们使用trailling约束时,因此无法正确地获得ref-label的正确高度。在sizeTofit之前,我们可以考虑为ref-label定义固定宽度,以获得用于目标按钮的正确高度。
btnHeightConstraint.constant = 30
。 - NSNoob\n
的属性字符串作为标题。 - NSNoobUIButton
约束,请查看。 - Linh