UIButton的标题标签Word与尾巴截断

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

我已经search过,还没有find解决scheme。 任何想法?

这是正确的:

 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,所以它不能用作掩码。 欲了解更多信息,请参阅。

在现实中使用| 这些常量的运算符会导致与NSLineBreakByTruncatingTail匹配的掩码:

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

据我所知,截断核心文本中的最后一行,也不能使用简单的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头文件:

 // 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的这个有点模糊的特性出现的唯一问题是,在绘制之前(这对于某些UITableView + UITableViewCelldynamic布局来说是必需的),您无法在不动用修改NSAttributedString的NSParagraphStyle的情况下获取大小。

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

 (NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingTruncatesLastVisibleLine) 

(请注意,NSStringDrawingUsesLineFragmentOrigin是多行string的必要条件。)

更糟糕的是,UILabel的lineBreakMode不会覆盖NSAttributedStrings段落样式,因此您必须修改您的大小计算的归因string的段落样式,稍后将其传递给UILabel以便它可以绘制它。

也就是说,NSLineBreakByWordWrapping for -boundingRectWithSize:options:context和UILabel的NSLineBreakByTruncatingTail(所以它可以,在内部使用NSStringDrawingTruncatesLastVisibleLine,或者不pipe它剪辑最后一行)

唯一的select是,如果你不想改变你的string的段落样式不止一次,那就是做一个简单的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之前,如果你想对一个属性string进行文字换行+尾部截断,你必须使用Core Text来逐行排版。

我解决了这个问题,当我发布这个问题的时候,把UIButton放在一个numberOfLines设置为3的UILabel顶部。我已经离开了这个不被接受,看看是否有人有一个更好的主意,但显然没有其他的解决scheme。

 [self.costomButton.titleLabel setTextAlignment:UITextAlignmentLeft]; [self.costomButton.titleLabel setNumberOfLines:3]; 

确保你应该先设置Alignment ps:这只在系统版本大于5.0时才起作用

尝试设置numberOfLines大于2,并相应地设置高度。

  m_button = [UIButton buttonWithType:UIButtonTypeCustom]; [m_button setFrame:CGRectMake(isLandscape?20:10, 40, isLandscape?300:250, 40)]; m_button.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:17]; [m_btnDiscoverPoint setTitle:@"Title" forState:UIControlStateNormal]; CGRect buttonFrame = [m_button frame]; if ([m_button.titleLabel.text length]>0) { CGSize suggestedSize = [m_button.titleLabel.text sizeWithFont:[UIFont fontWithName:@"HelveticaNeue" size:17] constrainedToSize:CGSizeMake(FLT_MAX,m_button.frame.size.height) lineBreakMode:UILineBreakModeWordWrap]; if (suggestedSize.width >= self.view.frame.size.width) { suggestedSize.width = self.view.frame.size.width-10; suggestedSize.height=suggestedSize.height+20; m_button.titleLabel.numberOfLines=2; } else{ m_button.titleLabel.numberOfLines=1; } buttonFrame.size.width = suggestedSize.width; [m_button setFrame:buttonFrame]; } [m_button setBackgroundColor:[UIColor clearColor]]; [m_button addTarget:self action:@selector(btnClickAction) forControlEvents:UIControlEventTouchUpInside]; 
 button.titleLabel.numberOfLines = 2; button.titleLabel.lineBreakMode = UILineBreakModeWordWrap; UIFont * theFont = [UIFont systemFontOfSize: 14]; // you set CGSize textSize = [titleStr sizeWithAttributes:@{NSFontAttributeName: theFont}]; CGFloat theWidth = kScreenWidth-otherWidthYouSet;// I thought the button's frame is content driving ,and is limited CGFloat ratio = theWidth*heightYouSet/((textSize.width+4)*(textSize.height+6));// 4 , 6 , is made by experience . I think the textSize is taken one line text default by the system NSUInteger validNum = ratio * titleStr.length; if(ratio<1){ [button setTitle: [[titleStr substringToIndex: validNum] stringByAppendingString: @"..."] state: yourState]; } else{ [button setTitle: titleStr state: yourState]; } 

您可以使用按位或运算符在标签上指定多个lineBreakMode。

例如,下面的代码将包装标签的文本,并且在扩展超出标签框架高度的大小时,会在文本的尾部添加省略号。

 lblTemp.lineBreakMode = UILineBreakModeWordWrap | UILineBreakModeTailTruncation; lblTemp.numberOfLines = 0; 

更新:这是不正确的。 它似乎工作,因为在枚举中UILineBreakModeWordWrap是0。 见下面的评论。

所有UI属性在iOS中都被弃用使用NS缩写而不是UI。 如下例所示 – NSLineBreakByTruncatingMiddle