2012-10-25 210 views
32
[self.Review sizeToFit]; 

結果:如何通過更改高度而不是寬度來調整UILabel的大小? sizeToFit前

NSStringFromCGRect(self.Review.frame): {{90, 20}, {198, 63}} 

結果sizeToFit後:

NSStringFromCGRect(self.Review.frame): {{90, 20}, {181, 45}} 

我想要的寬度保持不變。我只是想改變身高。該自動模板是

(lldb) po self.Review 
(UILabel *) $1 = 0x08bb0fe0 <UILabel: 0x8bb0fe0; frame = (90 20; 181 45); text = 'I'm at Mal Taman Anggrek ...'; clipsToBounds = YES; opaque = NO; autoresize = LM+RM+H; userInteractionEnabled = NO; layer = <CALayer: 0x8bb68b0>> 

我知道,有一種方法有這樣做的: How to adjust and make the width of a UILabel to fit the text size?

的答案要麼是怪(我們需要補給的字體信息)。還是不清楚。

您還需要定義最大寬度,並告訴程序 如果sizeToFit給出的寬度大於最大值,該怎麼做。

我將使用使用sizeWithFont的奇怪解決方案。這很奇怪,因爲UILabel已經知道標籤中的字體。

其實sizeToFit究竟如何表現?它如何決定我們是否需要更薄或更高的UILabel?

+0

sizeWithFont是不是NSString的的UILable –

回答

38

這是如何完成的。因爲標籤已經包含了字體信息,包括它在這個方法中調用是微不足道的。

let maxHeight = CGFloat.infinity 
let rect = label.attributedText?.boundingRectWithSize(CGSizeMake(maxWidth, maxHeight), 
     options: .UsesLineFragmentOrigin, context: nil) 
var frame = label.frame 
frame.size.height = rect.size.height 
label.frame = frame 
+0

和maxWidth的方法只會是label.frame.size.width? –

+0

沒錯。我以爲你可能想指定其他地方。但是如果標籤已經有了合適的尺寸,'label.frame.size.width'將會保持原樣。 – Mundi

+0

我結束了使用這段代碼。 –

38

可以實現與sizeThatFits相同的結果:使用更先進的最新boundingRectWithSize

CGSize size = [label.text sizeWithFont:label.font 
        constrainedToSize:CGSizeMake(maxWidth, MAXFLOAT) 
         lineBreakMode:UILineBreakModeWordWrap]; 
CGRect labelFrame = label.frame; 
labelFrame.size.height = size.height; 
label.frame = labelFrame; 

斯威夫特版本。

CGSize size = [label sizeThatFits:CGSizeMake(label.frame.size.width, CGFLOAT_MAX)]; 
CGRect frame = label.frame; 
frame.size.height = size.height; 
label.frame = frame; 

或者可以用sizeToFit。

CGRect frame = label.frame; 
[label sizeToFit]; 
frame.size.height = label.frame.size.height; 
label.frame = frame; 
+1

使用您的解決方案結束!但只是一個更正...他想保持HEIGTH和你的第二個選擇(我使用的那個)你保持寬度。 – Thpramos

+0

使用iOS 7(或8)時,由於sizeWithFont:已棄用iOS 7及更高版本,因此這是最佳工作答案 – BrFreek

17

sizeToFit很棒。唯一的問題是它基於控件的當前大小。

例如,如果您正在使用標籤回收表格視圖單元格,則標籤在前一個單元格中的寬度可能會減小,因此對sizeToFit的調用可能看起來不可靠。

在發送sizeToFit消息之前,請重置您的控件的原始寬度。

+3

這是價值不足的無價信息 – ChuckKelly

+0

@ChuckKelly,我完全同意。 – smozgur

+0

非常感謝,讓一切變得如此簡單! – LinusGeffarth

2

我認爲你不應該使用NSStringsize...方法,UILabel已經有隻是一個API,如@vatrif指出(其中內部可能只使用NSString的方法)。我想UILabel的API可以改進。這就是爲什麼我認爲一個類別將是最完美的解決方案:

// UILabel+Resize.h 
@interface UILabel (Resize) 
- (void)sizeToFitHeight; 
@end 

// UILabel+Resize.m 
@implementation UILabel (Resize) 
- (void)sizeToFitHeight { 
    CGSize size = [self sizeThatFits:CGSizeMake(self.frame.size.width, CGFLOAT_MAX)]; 
    CGRect frame = self.frame; 
    frame.size.height = size.height; 
    self.frame = frame; 
} 
@end 

只有一兩件事:我不知道適當的名稱爲該方法:

  • sizeToFitHeight?
  • heightToFit?

評論非常感謝,謝謝!

1

商定的API將受益於此增加。讓您的生活更輕鬆,延長在斯威夫特添加到UILabel類如下:

extension UILabel { 

    func sizeToFitHeight() { 
     let size:CGSize = self.sizeThatFits(CGSizeMake(self.frame.size.width, CGFloat.max)) 
     var frame:CGRect = self.frame 
     frame.size.height = size.height 
     self.frame = frame 
    } 
} 
0

斯威夫特3版本Mundi的答案:

let maxHeight: CGFloat = 10000 
let rect = label.attributedText!.boundingRect(with: CGSize(width: maxWidth, height: maxHeight), 
                  options: .usesLineFragmentOrigin, 
                  context: nil) 
var frame = labe.frame 
frame.size.height = rect.size.height 
label.frame = frame 
1

固定解爲SWIFT 3

maxHeight使用CGFloat.greatestFiniteMagnitude

let size = CGSize.init(width: yourLabel.frame.size.width, 
         height: CGFloat.greatestFiniteMagnitude) 
let rect = errorLabel.attributedText?.boundingRect(with: size, options: .usesLineFragmentOrigin, context: nil) 
var frame = errorLabel.frame 
frame.size.height = (rect?.size.height)! 
errorLabel.frame = frame 


或創建UIlabel延伸,並且呼叫的方法yourLabel. sizeToFitHeight()

extension UILabel { 

    func sizeToFitHeight() { 
     let maxHeight : CGFloat = CGFloat.greatestFiniteMagnitude 
     let size = CGSize.init(width: self.frame.size.width, height: maxHeight) 
     let rect = self.attributedText?.boundingRect(with: size, options: .usesLineFragmentOrigin, context: nil) 
     var frame = self.frame 
     frame.size.height = (rect?.size.height)! 
     self.frame = frame 
    } 

} 
2

回答爲2017 ...

C = CGSize(寬度:yourWidth,高度:CGFloat的.greatestFiniteMagnitude)
result = sizeThatFits(c).he飛行

所以......

let t = .... your UITextView 
let w = .... your known width of the item 

let trueHeight = t.sizeThatFits(
        CGSize(width: t, height: CGFloat.greatestFiniteMagnitude)).height 

就是這樣。


很多時候,你想知道相比於「正常」的單行條目的高度差異

特別是如果你正在製造某種與UTableView無關的單元格(比如某種自定義堆棧視圖)。您必須在某個時候手動設置高度。在你的故事板上,根據需要使用任何短字符串(例如「A」)的示例文本來構建它,這在任何正常情況下當然將只有一行。然後,你做這樣的事......

func setTextWithSizeCorrection() { // an affaire iOS 

    let t = .... your UITextView 
    let w = .... your known width of the item 

    let oneLineExample = "A" 
    let actualText = yourDataSource[row].description.whatever 

    // get the height as if with only one line... 

    experimental.text = oneLineExample 
    let oneLineHeight = t.sizeThatFits(
       CGSize(width: w, height: CGFloat.greatestFiniteMagnitude)).height 

    // get the height with the actual long text... 
    // (note that usually, you do not want a one-line minimum) 

    experimental.text = (actualText == "") ? oneLineExample : actualText 
    let neededHeight = t.sizeThatFits(
       CGSize(width: w, height: CGFloat.greatestFiniteMagnitude)).height 

    experimental.text = actualText 

    let delta = neededHeight - oneLineHeight 

    set the height of your cell, or whatever it is(standardHeight + delta) 
} 

最後一點:在iOS的真正愚蠢的事情之一是,UITextView的有一個奇怪的排序裏面保證金。這意味着你不能只在UITextViews和標籤之間交換;並導致許多其他問題。截至撰寫時,蘋果公司尚未解決這個問題。要解決這個問題很難:下面的辦法通常是好的:

@IBDesignable class UITextViewFixed: UITextView { 
    override func layoutSubviews() { 
     super.layoutSubviews() 
     setup() 
    } 
    func setup() { 
     textContainerInset = UIEdgeInsets.zero; 
     textContainer.lineFragmentPadding = 0; 
    } 
} 

破碎,蘋果無法使用的UITextView ...

enter image description here

UITextViewFixed是,在大多數情況下,可接受的修復:

enter image description here

(黃色添加清晰度。)

0

一個簡單的擴展這個問題斯威夫特3.

extension UILabel { 
    func sizeToFitHeight() { 
     let size: CGSize = self.sizeThatFits(CGSize.init(width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude)) 
     var frame:CGRect = self.frame 
     frame.size.height = size.height 
     self.frame = frame 
    } 
} 
相關問題