回答
你可以計算出一條線上的長度,然後取這個寬度除以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. 非均勻文字縮放
- 2. 傳遞GLfloat作爲均勻失敗(IOS)
- 3. 固定包裝的均勻隔開的div?
- 4. 當它們包裝時均勻分配flex項目
- 5. Twitter Bootstrap佈局「均勻地」包裝「視口大小
- 6. Flexbox的均勻間隔元件和包裝上窄屏幕
- 7. 如何包裝不均勻內容的div
- 8. 在字母上均勻分佈字母
- 9. PRNG均勻分佈
- 10. Haskell均勻函數?
- 11. 非均勻插值
- 12. 非均勻量化
- 13. 減少DIV均勻
- 14. 創建不均勻的聯合查詢與不均勻的數量的字段
- 15. 的Python把非均勻線成字典
- 16. 不均勻的字符行拆分
- 17. 字符串填充均勻調整列
- 18. bash均勻地選擇10個數字
- 19. 生成均勻劃分的數字
- 20. matplotlib - 均勻保持勾號位置,但值不均勻
- 21. 將非均勻分佈轉化爲均勻分佈
- 22. 從非均勻數據創建均勻分佈的示例
- 23. 均勻位置和均勻指數之間的區別?
- 24. 標準均勻分佈到離散均勻[a,b]
- 25. 水平均勻分佈線性佈局的文本視圖幷包裝內容
- 26. 均勻間距按鈕android
- 27. Powerpoint VBA - 均勻分佈列
- 28. GridView拉伸ImageView非均勻
- 29. Flexbox不均勻間距
- 30. VS2013行號不均勻
如果在給定的字體,標籤只需要一行,那就很好。我真正想要避免的是非常重要的標籤,其中除了一個單詞外的所有內容都位於頂部,然後底部有一個小字。基本上,標題不必包裝,但如果要包裝,我希望它更平整一些。 – s73v3r 2012-07-31 21:28:20
是的,這就是我描述的方法。你的初始計算會產生一個高的高度。當它溢出到兩行時,你的循環會退出。您可以使用先前的寬度值,這是可以使內容保持一行的最窄寬度。 – Jim 2012-07-31 21:30:09