我有以下代码...
UILabel *buttonLabel = [[UILabel alloc] initWithFrame:targetButton.bounds];
buttonLabel.text = @"Long text string";
[targetButton addSubview:buttonLabel];
[targetButton bringSubviewToFront:buttonLabel];
...我的想法是我可以为按钮设置多行文本,但文本总是被 UIButton 的 backgroundImage 遮挡。显示按钮子视图的日志调用显示已添加 UILabel,但无法看到文本本身。这是 UIButton 中的错误还是我做错了什么?
button.titleLabel?.numberOfLines = 0
对于 iOS 6 及更高版本,使用以下命令允许多行:
button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
// you probably want to center it
button.titleLabel.textAlignment = NSTextAlignmentCenter; // if you want to
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];
对于 iOS 5 及更低版本,请使用以下命令来允许多行:
button.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
// you probably want to center it
button.titleLabel.textAlignment = UITextAlignmentCenter;
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];
2017 年,对于 iOS9 前进,
通常,只需执行以下两件事:
在“换行符”弹出窗口中选择“属性文本”选择“自动换行”
选择的答案是正确的,但如果您更喜欢在 Interface Builder 中执行此类操作,您可以执行以下操作:
https://i.stack.imgur.com/Qk9Bg.png
User Defined Runtime Attributed
中将具有 Number
值的 titleLabel.textAlignment
设置为 1
以使文本居中
如果要添加标题居中的多行按钮,请设置 Interface Builder 的按钮设置:
https://i.stack.imgur.com/xZaOC.png
对于 IOS 6:
button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;
作为
UILineBreakModeWordWrap and UITextAlignmentCenter
从 IOS 6 起已弃用..
Foundation
中的 NSText.h
内没有添加已弃用的内容。它从 6.0 开始可用,但未弃用。
button.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
button.titleLabel?.textAlignment = NSTextAlignment.Center
重申 Roger Nolan 的建议,但使用明确的代码,这是一般解决方案:
button.titleLabel?.numberOfLines = 0
斯威夫特 3
button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.textAlignment = .center
button.setTitle("Button\nTitle",for: .normal)
https://i.stack.imgur.com/AdaOn.png
extension UIButton {
func makeMultiLineSupport() {
guard let titleLabel = titleLabel else {
return
}
titleLabel.numberOfLines = 0
titleLabel.setContentHuggingPriority(.required, for: .vertical)
titleLabel.setContentHuggingPriority(.required, for: .horizontal)
addConstraints([
.init(item: titleLabel,
attribute: .top,
relatedBy: .greaterThanOrEqual,
toItem: self,
attribute: .top,
multiplier: 1.0,
constant: contentEdgeInsets.top),
.init(item: titleLabel,
attribute: .bottom,
relatedBy: .greaterThanOrEqual,
toItem: self,
attribute: .bottom,
multiplier: 1.0,
constant: contentEdgeInsets.bottom),
.init(item: titleLabel,
attribute: .left,
relatedBy: .greaterThanOrEqual,
toItem: self,
attribute: .left,
multiplier: 1.0,
constant: contentEdgeInsets.left),
.init(item: titleLabel,
attribute: .right,
relatedBy: .greaterThanOrEqual,
toItem: self,
attribute: .right,
multiplier: 1.0,
constant: contentEdgeInsets.right)
])
}
}
relatedBy: .lessThanOrEqual
并翻转常量负 constant: -contentEdgeInsets.{bottom|right}
...
,所以我添加了 .lineBreakMode = .byClipping
在 Xcode 9.3 中,您可以使用下面的情节提要来做到这一点,
https://i.stack.imgur.com/ZRdnx.png
您需要将按钮标题 textAlignment 设置为居中
button.titleLabel?.textAlignment = .center
您不需要像下面那样使用换行符 (\n) 设置标题文本,
button.setTitle("Good\nAnswer",for: .normal)
只需设置标题,
button.setTitle("Good Answer",for: .normal)
这是结果,
https://i.stack.imgur.com/U0Uly.png
myButton.titleLabel.textAlignment = NSTextAlignmentCenter
语句也是必需的。
有一个更简单的方法:
someButton.lineBreakMode = UILineBreakModeWordWrap;
(针对 iOS 3 及更高版本进行编辑:)
someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
在 iOS7 上使用自动布局左对齐:
button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentLeft;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
首先,你应该知道 UIButton 里面已经有一个 UILabel 。您可以使用 –setTitle:forState:
进行设置。
您的示例的问题是您需要将 UILabel 的 numberOfLines
属性设置为默认值 1 以外的值。您还应该查看 lineBreakMode
属性。
Swift 5,用于 UIButton 中的多行文本
let button = UIButton()
button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.textAlignment = .center
button.titleLabel?.numberOfLines = 0 // for Multi line text
要将标题标签的间距固定到按钮,请在 setTitle 之前设置 titleEdgeInsets 和其他属性:
let button = UIButton()
button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.numberOfLines = 0
button.titleEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 20, right: 20)
button.setTitle("Dummy button with long long long long long long long long title", for: .normal)
PS 我测试了设置 titleLabel?.textAlignment 不是必需的,并且标题在 .natural
中对齐。
对于那些使用 Xcode 4 的故事板的人,您可以单击按钮,然后在右侧的实用程序窗格中的属性检查器下,您将看到换行符选项。选择自动换行,你应该很高兴。
这里的答案告诉你如何以编程方式实现多行按钮标题。
我只是想补充一点,如果您使用情节提要,您可以键入 [Ctrl+Enter] 以在按钮标题字段上强制换行。
高温高压
将 lineBreakMode 设置为 NSLineBreakByWordWrapping(在 IB 或代码中)使按钮标签变为多行,但不影响按钮的框架。
如果按钮具有动态标题,则有一个技巧:将隐藏的 UILabel 放入相同的字体并将其高度与布局的按钮高度联系起来;当将文本设置为按钮和标签时,自动布局将完成所有工作。
笔记
单行按钮的固有尺寸高度大于标签的,所以为了防止标签的高度缩小,它的垂直内容拥抱优先级必须大于按钮的垂直内容压缩阻力。
您必须添加以下代码:
buttonLabel.titleLabel.numberOfLines = 0;
至于 Brent 将标题 UILabel 作为同级视图的想法,在我看来这不是一个好主意。我一直在思考与 UILabel 的交互问题,因为它的触摸事件没有通过 UIButton 的视图。
另一方面,使用 UILabel 作为 UIButton 的子视图,我很高兴知道触摸事件将始终传播到 UILabel 的超级视图。
我确实采用了这种方法,并没有注意到 backgroundImage 报告的任何问题。我在 UIButton 子类的 -titleRectForContentRect: 中添加了这段代码,但代码也可以放在 UIButton 父视图的绘图例程中,在这种情况下,您应该用 UIButton 的变量替换所有对 self 的引用。
#define TITLE_LABEL_TAG 1234
- (CGRect)titleRectForContentRect:(CGRect)rect
{
// define the desired title inset margins based on the whole rect and its padding
UIEdgeInsets padding = [self titleEdgeInsets];
CGRect titleRect = CGRectMake(rect.origin.x + padding.left,
rect.origin.x + padding.top,
rect.size.width - (padding.right + padding.left),
rect.size.height - (padding.bottom + padding].top));
// save the current title view appearance
NSString *title = [self currentTitle];
UIColor *titleColor = [self currentTitleColor];
UIColor *titleShadowColor = [self currentTitleShadowColor];
// we only want to add our custom label once; only 1st pass shall return nil
UILabel *titleLabel = (UILabel*)[self viewWithTag:TITLE_LABEL_TAG];
if (!titleLabel)
{
// no custom label found (1st pass), we will be creating & adding it as subview
titleLabel = [[UILabel alloc] initWithFrame:titleRect];
[titleLabel setTag:TITLE_LABEL_TAG];
// make it multi-line
[titleLabel setNumberOfLines:0];
[titleLabel setLineBreakMode:UILineBreakModeWordWrap];
// title appearance setup; be at will to modify
[titleLabel setBackgroundColor:[UIColor clearColor]];
[titleLabel setFont:[self font]];
[titleLabel setShadowOffset:CGSizeMake(0, 1)];
[titleLabel setTextAlignment:UITextAlignmentCenter];
[self addSubview:titleLabel];
[titleLabel release];
}
// finally, put our label in original title view's state
[titleLabel setText:title];
[titleLabel setTextColor:titleColor];
[titleLabel setShadowColor:titleShadowColor];
// and return empty rect so that the original title view is hidden
return CGRectZero;
}
我确实花时间写了更多关于这个 here 的内容。在那里,我还指出了一个较短的解决方案,尽管它并不完全适合所有场景并且涉及一些私人视图黑客攻击。此外,您还可以下载一个可供使用的 UIButton 子类。
如果您在 iOS 6 上使用自动布局,您可能还需要设置 preferredMaxLayoutWidth
属性:
button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;
button.titleLabel.preferredMaxLayoutWidth = button.frame.size.width;
如今,如果您真的需要在界面构建器中逐个访问这种东西,您可以使用如下简单的扩展来实现:
extension UIButton {
@IBInspectable var numberOfLines: Int {
get { return titleLabel?.numberOfLines ?? 1 }
set { titleLabel?.numberOfLines = newValue }
}
}
然后,您可以简单地将 numberOfLines 设置为任何 UIButton 或 UIButton 子类的属性,就好像它是一个标签一样。对于其他许多通常无法访问的值也是如此,例如视图层的角半径,或者它投射的阴影的属性。
在 Swift 5.0 和 Xcode 10.2 中
//UIButton extension
extension UIButton {
//UIButton properties
func btnMultipleLines() {
titleLabel?.numberOfLines = 0
titleLabel?.lineBreakMode = .byWordWrapping
titleLabel?.textAlignment = .center
}
}
在像这样的 ViewController 调用中
button.btnMultipleLines()//This is your button
它完美地工作。
添加与 Plist 等配置文件一起使用,您需要使用 CDATA 编写多行标题,如下所示:
<string><![CDATA[Line1
Line2]]></string>
如果您使用自动布局。
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.numberOfLines = 2
迅捷4.0
btn.titleLabel?.lineBreakMode = .byWordWrapping
btn.titleLabel?.textAlignment = .center
btn.setTitle( "Line1\nLine2", for: .normal)
滚动你自己的按钮类。从长远来看,这是迄今为止最好的解决方案。 UIButton 和其他 UIKit 类在如何自定义它们方面非常严格。
在 2021 年的 iOS 15 中,Apple 首次通过 UIButton.Configuration API 正式支持多行 UIButtons。
UIButton.Configuration 一种配置,用于指定按钮及其内容的外观和行为。
https://i.stack.imgur.com/KW92R.png
这个新的 API 在 What's new in UIKit 以及会话中进行了探索:
认识 UIKit 按钮系统 每个应用程序都使用按钮。在 iOS 15 中,您可以采用更新的样式来创建精美的按钮,轻松融入您的界面。我们将探索可以更轻松地创建不同类型按钮的功能,了解如何提供更丰富的交互,并了解如何在使用 Mac Catalyst 时获得出色的按钮。 https://developer.apple.com/videos/play/wwdc2021/10064/
UIButtton.Configuration
实现多行功能?
self.btnError.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
self.btnError.titleLabel?.textAlignment = .center
self.btnError.setTitle("Title", for: .normal)
我将 jessecurry's answer 合并到 STAButton 中,它是我的 STAControls 开源库的一部分。我目前在我正在开发的一个应用程序中使用它,它可以满足我的需求。随意打开有关如何改进它的问题或向我发送拉取请求。
添加按钮约束和子视图。这就是我在我的项目中的做法,让我们说这样更容易。我实际上 99% 的时间都以编程方式制作所有内容。因为这对我来说更容易。情节提要有时可能确实有问题 [1]:https://i.stack.imgur.com/5ZSwl.png
尽管可以将子视图添加到控件中,但不能保证它会真正起作用,因为控件可能不希望它在那里,因此可能表现不佳。如果你能摆脱它,只需将标签添加为按钮的兄弟视图并设置其框架,使其与按钮重叠;只要它被设置为出现在按钮的顶部,按钮就无法做任何事情来掩盖它。
换句话说:
[button.superview addSubview:myLabel];
myLabel.center = button.center;
addSubview:
将其添加到 button
的超级视图中,从而使其成为按钮的兄弟,因此匹配它们的中心是正确的。
button.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
NSLineBreakMode
,例如:button.titleLabel?.lineBreakMode = .ByWordWrapping
。