回答
你可以计算出一条线上的长度,然后取这个宽度除以2,并将该结果用作2行标签的宽度约束。这可能会让你获得更好的视觉效果,但如果你有很长的单词会导致你的标签为3行(除非有2行以上),你可能必须稍微调整一下。
这种方法的缺点是做了一些额外的工作,但它可能会伎俩。例如:
NSString *text = @"This is my very long title I want evenly on 2 lines"; UILabel *theLabel = [[UILabel alloc] init]; theLabel.text = text; // ...other label setup here, like font, etc [theLabel sizeToFit]; CGSize constraint = CGSizeMake(theLabel.frame.size.width/2.0, 1000); CGSize labelSize = [theLabel.text sizeWithFont:theLabel.font constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap]; theLabel.numberOfLines = 0; theLabel.lineBreakMode = UILineBreakModeWordWrap; CGRect frame = theLabel.frame; frame.size = labelSize; theLabel.frame = frame;
应该这样做。警告:从内存中写入。 :-)
我不相信有这样做的简单方法。 NSString
中增加了UIKit,允许您确定显示具有特定字体的字符串所需的尺寸。你可以做的是使用所有可用的宽度计算所需的高度,然后在循环中运行相同的计算,从而减小宽度直到它需要额外的垂直空间。然后,使用以前的值作为标签的宽度并进行适当的对齐。
对于一个多语言的应用程序,我需要修正以及完全相同的问题。该应用程序可以用9种不同的语言显示其用户界面,并且语言之间的消息长度有很大差异。正因为如此,我结束了对一些多行消息的一些不幸的默认文字换行。例如,有几种情况下,日文翻译最后只有一行文字,后面只有一个或两个字符。
我在我的Layout Utility类中添加了以下两种方法来解决这个问题(请参阅下面的代码)。此解决方案适用于具有任意数量行(1,2,3,更多......)和任何语言的标签。 (更改ECLayoutUtility
到自己的类名。)
的基本思路是这样的:
给出一个UILabel显示文本,检测其当前高度。
做一个二进制搜索的最小宽度为而不是增加那个高度。
在下面我的代码,你可以通过while
循环与granularity
可变控制精度和匝数之间的权衡。此修复程序之前有问题的日本品牌的
例子:
认为修补后同日本标签:
这是两种方法,我加入到我的布局实用程序类。我将它们分割成这样,所以你也可以查询获得新的尺寸,例如你使用Autolayout,并且想要使用尺寸信息来操纵约束条件而不是直接调整标签本身的尺寸:
+ (void)wordWrapEvenlyTextInUILabel:(UILabel *)uiLabel
forMaxWidth:(CGFloat)maxLabelWidth
{
[ECLayoutUtility resizeView:uiLabel
toSize:[self getLabelSizeWithMinimumWidthForLabel:uiLabel
forMaxWidth:maxLabelWidth]];
}
+ (CGSize)getLabelSizeWithMinimumWidthForLabel:(UILabel *)uiLabel
forMaxWidth:(CGFloat)maxLabelWidth
{
NSLog(@"Current size for label \"%@\" is %@", uiLabel.text, NSStringFromCGSize(uiLabel.frame.size));
// Start off by determining what height the label would get for the given maximum width:
CGSize labelSize = [uiLabel.text boundingRectWithSize:CGSizeMake(maxLabelWidth, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{ NSFontAttributeName:uiLabel.font }
context:nil].size;
// Constraining the label to that height, now figure out the mimumum width for
// which this label still shows its text within that given height. We find
// that height with a binary search for the smallest label width that does
// not increment the label height.
CGFloat maxWidth = maxLabelWidth;
CGFloat testWidth = 0.5 * maxWidth;
CGFloat minWidth = 0;
CGFloat granularity = 1;
while (maxWidth > testWidth + granularity)
{
CGFloat newHeight = [uiLabel.text boundingRectWithSize:CGSizeMake(testWidth, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{ NSFontAttributeName:uiLabel.font }
context:nil].size.height;
NSLog(@"H: %.2f, min W: %.2f, mid W: %.2f, max W: %.2f", newHeight, minWidth, testWidth, maxWidth);
if (newHeight > labelSize.height)
{
// Width reduction lead to height increase, so new width is too small.
// Now set the new width to mid-point between what we just tried and
// the last known acceptable width:
minWidth = testWidth; // increase the lower bound
testWidth += 0.5 * (maxWidth - testWidth); // increase width for next test
}
else
{
// Height not affected by the width reduction, so lets try to reduce it even more:
maxWidth = testWidth; // reduce the upper bound
testWidth -= 0.5 * (testWidth - minWidth); // reduce width for next test
}
}
CGSize newSize = CGSizeMake(maxWidth, labelSize.height);
NSLog(@"New size for label \"%@\" is %@", uiLabel.text, NSStringFromCGSize(newSize));
return newSize;
}
我打电话从-viewWillLayoutSubviews
的+wordWrapEvenlyTextInUILabel:forMaxWidth:
方法在我的视图控制器如下:
// Make sure that any text in the promo message that is wrapped over multiple lines
// is wrapped evenly, so we don't get very uneven lines that look ugly:
[ECLayoutUtility wordWrapEvenlyTextInUILabel:_promoMessageLabel
forMaxWidth:_promoMessageLabel.frame.size.width];
我已经在不同的语言测试,这为不同的标签,它看起来是完全做的工作。这里有一个越南例如:
我希望这可以帮助别人以及:-)
感谢,
埃里克
我继续创建了一个名为CocoaPod是EvenlyWrappedLabel受到了Erik van der Neut的回答的启发。它有几个整洁的功能:
防止单个单词孤儿占据整个底线。
实施例:
This sentence has a single orphan.
变成:从顶部向上分组,感觉头重脚轻
This sentence has a single orphan.
防止文本。
例子:
This sentence has a lot of words on the top line.
变为:
This sentence has a lot of words on the top line.
选项在可用每行均匀地分布文本。
实施例:
This only takes up one line.
变为*:
This only takes up one line.
*
numberOfLines = 3
,useEveryLine = true
作品与自动布局约束和方面固有上浆。
极易于集成,只需将
let label = UILabel()
替换为let label = EvenlyWrappedLabel()
即可。一个糟糕的屁股示例应用程序。
如果你不使用的CocoaPods,你可以找到GitHub的源代码。请享用!
这真了不起。谢谢! – 2017-10-11 03:12:08
- 1. 传递GLfloat作为均匀失败(IOS)
- 2. 当它们包装时均匀分配flex项目
- 3. Twitter Bootstrap布局“均匀地”包装“视口大小
- 4. 如何包装不均匀内容的div
- 5. 在字母上均匀分布字母
- 6. Haskell均匀函数?
- 7. PRNG均匀分布
- 8. 减少DIV均匀
- 9. 不均匀的字符行拆分
- 10. 字符串填充均匀调整列
- 11. 均匀位置和均匀指数之间的区别?
- 12. 将非均匀分布转化为均匀分布
- 13. 标准均匀分布到离散均匀[a,b]
- 14. 从非均匀数据创建均匀分布的示例
- 15. 水平均匀分布线性布局的文本视图并包装内容
- 16. 随机均匀分布
- 17. 均匀分布图像库
- 18. Python适合均匀分布
- 19. AFHTTPRequestOperation进度不均匀
- 20. GridView拉伸ImageView非均匀
- 21. 不均匀网格布局
- 22. 分发按钮DIV均匀
- 23. 随机均匀分布
- 24. 按天分配行均匀
- 25. 均匀分布矩形
- 26. libGDX:添加均匀VAR
- 27. 半球均匀采样
- 28. 纹理均匀拉伸
- 29. Powerpoint VBA - 均匀分布列
- 30. 均匀网格分区
如果在给定的字体,标签只需要一行,那就很好。我真正想要避免的是非常重要的标签,其中除了一个单词外的所有内容都位于顶部,然后底部有一个小字。基本上,标题不必包装,但如果要包装,我希望它更平整一些。 – s73v3r 2012-07-31 21:28:20
是的,这就是我描述的方法。你的初始计算会产生一个高的高度。当它溢出到两行时,你的循环会退出。您可以使用先前的宽度值,这是可以使内容保持一行的最窄宽度。 – Jim 2012-07-31 21:30:09