gpt4 book ai didi

ios - 带有尾部截断的 UIButton 的标题标签自动换行

转载 作者:IT王子 更新时间:2023-10-29 08:08:05 32 4
gpt4 key购买 nike

我需要在 UIButtontitleLabel 上同时启用自动换行和尾部截断。将 numberOfLines 设置为大于 0 的值不起作用,文本停留在一行上。

我已经四处搜索,但没有找到解决方案。有什么想法吗?

最佳答案

这是正确的:

lblTemp.lineBreakMode = NSLineBreakByWordWrapping | NSLineBreakByTruncatingTail
lblTemp.numberOfLines = 0;

NSLineBreakMode 在 NSParagraphStyle.h 中定义为:

typedef NS_ENUM(NSInteger, NSLineBreakMode) {       /* What to do with long lines */
NSLineBreakByWordWrapping = 0, /* Wrap at word boundaries, default */
NSLineBreakByCharWrapping, /* Wrap at character boundaries */
NSLineBreakByClipping, /* Simply clip */
NSLineBreakByTruncatingHead, /* Truncate at head of line: "...wxyz" */
NSLineBreakByTruncatingTail, /* Truncate at tail of line: "abcd..." */
NSLineBreakByTruncatingMiddle /* Truncate middle of line: "ab...yz" */
} NS_ENUM_AVAILABLE_IOS(6_0);

请注意,它是一个 NS_ENUM,而不是一个 NS_OPTION,因此它不能用作掩码。有关详细信息,请参阅 this .

实际上,在这些常量上使用 | 运算符会导致掩码匹配 NSLineBreakByTruncatingTail:

(NSLineBreakByWordWrapping | NSLineBreakByTruncatingTail) == 4
NSLineBreakByTruncatingTail == 4

据我所知,截断 Core Text 中的最后一行并进行自动换行无法通过简单的 CTFramesetterCreateWithAttributedString 和 CTFrameDraw API 完成,但可以通过逐行布局完成, UILabel 必须在做什么。

iOS 6 通过在 NSStringDrawing.h 中公开新的绘图 API 简化了这一点:

typedef NS_ENUM(NSInteger, NSStringDrawingOptions) {
NSStringDrawingTruncatesLastVisibleLine = 1 << 5, // Truncates and adds the ellipsis character to the last visible line if the text doesn't fit into the bounds specified. Ignored if NSStringDrawingUsesLineFragmentOrigin is not also set.
NSStringDrawingUsesLineFragmentOrigin = 1 << 0, // The specified origin is the line fragment origin, not the base line origin
NSStringDrawingUsesFontLeading = 1 << 1, // Uses the font leading for calculating line heights
NSStringDrawingUsesDeviceMetrics = 1 << 3, // Uses image glyph bounds instead of typographic bounds
} NS_ENUM_AVAILABLE_IOS(6_0);

@interface NSAttributedString (NSExtendedStringDrawing)
- (void)drawWithRect:(CGRect)rect options:(NSStringDrawingOptions)options context:(NSStringDrawingContext *)context NS_AVAILABLE_IOS(6_0);
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options context:(NSStringDrawingContext *)context NS_AVAILABLE_IOS(6_0);
@end

因此,如果您使用的是 UILabel,您希望将标签本身上的 NSAttributedString 的 NSParagraphStyle 或 lineBreakMode 设置为:

NSLineBreakByTruncatingTail

并且标签上的 numberOfLines 属性必须设置为 0。

来自 numberOfLines 上的 UILabel header :

// if the height of the text reaches the # of lines or the height of the view is less than the # of lines allowed, the text will be
// truncated using the line break mode.

来自 UILabel 文档:

This property controls the maximum number of lines to use in order to fit the label’s text into its bounding rectangle. The default value for this property is 1. To remove any maximum limit, and use as many lines as needed, set the value of this property to 0.
If you constrain your text using this property, any text that does not fit within the maximum number of lines and inside the bounding rectangle of the label is truncated using the appropriate line break mode.

UILabel 这个有点晦涩的特性带来的唯一问题是,如果不即时修改 NSAttributedString 的 NSParagraphStyle,就无法在绘制之前获取尺寸(这对于某些 UITableView + UITableViewCell 动态布局来说是必需的)。

从 iOS 6.1.4 开始,使用具有 NSLineBreakByTruncatingTail 换行模式(对于 UILabel)的 NSAttributedString 调用 -boundingRectWithSize:options:context,返回不正确的单行高度,即使以下选项传入:

(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine)

(请注意 NSStringDrawingUsesLineFragmentOrigin 是多行字符串的必要条件。)

更糟糕的是,UILabel 的 lineBreakMode 不会覆盖 NSAttributedStrings 段落样式,因此您必须修改属性字符串的段落样式以进行大小计算,然后再将其传递给 UILabel,这样它可以画出来。

也就是说,NSLineBreakByWordWrapping 用于 -boundingRectWithSize:options:context 和 NSLineBreakByTruncatingTail 用于 UILabel(所以它可以在内部使用 NSStringDrawingTruncatesLastVisibleLine,或者它所做的任何操作来剪辑最后一行)

如果您不想多次改变字符串的段落样式,唯一的选择是做一个简单的 UIView 子类,它覆盖 -drawRect:(将适当的 contentMode 设置为重绘),并使用 iOS 6新的绘图 API:

- (void)drawWithRect:(CGRect)rect options:(NSStringDrawingOptions)options context:(NSStringDrawingContext *)context NS_AVAILABLE_IOS(6_0);

记住使用 NSLineBreakByWordWrapping 并传入 (NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine) 作为选项。

最后,在 iOS 6 之前,如果你想对属性字符串进行自动换行 + 尾部截断,你必须自己使用 Core Text 逐行布局。

关于ios - 带有尾部截断的 UIButton 的标题标签自动换行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7378308/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com