ios – 垂直對齊UILabel文字與約束,無換行(自動佈局,單行)
所以我在IB中設定我的檢視,使得這個文字標籤通過約束與縮圖的頂部對齊.
但是,我們知道,您不能在UILabel中垂直對齊文字.我的文字根據內容的長度來更新字型大小.全尺寸文字看起來不錯,而小文字在檢視上顯著更低.
ofollow,noindex" target="_blank">existing solution 涉及呼叫sizeToFit或更新uilabel的框架以匹配文字的高度.不幸的是,後者(雖然醜的)解決方案不適合你不應該更新框架的約束.當您需要使文字自動收縮直到截斷時,前一個解決方案基本上不起作用. (所以它不適用於有限數量的行和自動收縮).
現在,為什麼uilabel的內在大小(高度)不會像寬度那樣更新,當它被設定為通過“大小適合內容”的自然大小超出了我.似乎肯定應該,但它不.
所以我找不到替代解決方案.據我所見,您可能必須在標籤上設定高度約束,並在計算文字的高度後調整高度.任何人都有很好的解決方案?
這個問題是一個真正的PITA來解決.這並不意味著API的工作在iOS7中已被淘汰,或者iOS7更換API被破壞.胡說!
您的解決方案很好,但是它使用了不推薦的API(sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode :),並且封裝不是很好 – 您需要將此程式碼複製到您想要此行為的任何單元格或檢視.在正面上它是相當有效率!一個錯誤可能是,當您進行計算時,標籤尚未佈局,但您可以根據其寬度進行計算.
我建議您將此行為封裝在UILabel子類中.通過將尺寸計算放在被覆蓋的intrinsicContentSize方法中,標籤將自動調整大小.我寫了以下內容,其中包含將在iOS6上執行的程式碼,我的版本使用不被棄用的API用於iOS7或更高版本:
@implementation TSAutoHeightLabel - (CGSize) intrinsicContentSize { NSAssert( self.baselineAdjustment == UIBaselineAdjustmentAlignCenters, @"Please ensure you are using UIBaselineAdjustmentAlignCenters!" ); NSAssert( self.numberOfLines == 1, @"This is only for single-line labels!" ); CGSize intrinsicContentSize; if ( [self.text respondsToSelector: @selector( boundingRectWithSize:options:attributes:context: )] ) { NSStringDrawingContext* context = [NSStringDrawingContext new]; context.minimumScaleFactor = self.minimumScaleFactor; CGSize inaccurateSize = [self.text boundingRectWithSize: CGSizeMake( self.bounds.size.width, CGFLOAT_MAX ) options: NSStringDrawingUsesLineFragmentOrigin attributes: @{ NSFontAttributeName : self.font } context: context].size; CGSize accurateSize = [self.text sizeWithAttributes: @{ NSFontAttributeName : [UIFont fontWithName: self.font.fontName size: 12.0] } ]; CGFloat accurateHeight = accurateSize.height * inaccurateSize.width / accurateSize.width; intrinsicContentSize = CGSizeMake( inaccurateSize.width, accurateHeight); } else { CGFloat actualFontSize; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" [self.text sizeWithFont: self.font minFontSize: self.minimumFontSize actualFontSize: &actualFontSize forWidth: self.frame.size.width lineBreakMode: NSLineBreakByTruncatingTail]; #pragma GCC diagnostic pop CGRect lineBox = CTFontGetBoundingBox((__bridge CTFontRef)([UIFont fontWithName: self.font.fontName size: actualFontSize])); intrinsicContentSize = lineBox.size; } return intrinsicContentSize; } @end
這個實現並不完美.我必須確保使用baselineAdjustment == UIBaselineAdjustmentAlignCenters,我不知道為什麼100%肯定.我不滿意我不得不跳過的籃球,以獲得準確的文字高度.我的計算產生和您的資料之間也有一些畫素差異.隨意玩,隨意調整:)
boundingRectWithSize:options:attributes:context API對我來說好像很壞.雖然(主要是)正確地將文字約束到輸入大小,但它不會計算正確的高度!它返回的高度是基於所提供的字型的行高,即使是縮放比例.我的猜測是,這是為什麼UILabel預設情況下沒有這種行為?我的解決方法是計算高度和寬度都準確的無約束尺寸,然後使用受約束寬度和無約束寬度之間的比率來計算約束尺寸的準確高度.什麼是PITA在Apple開發論壇中有很多投訴,而在這裡,SO指出,這個API有一些這樣的問題.
http://stackoverflow.com/questions/15510875/vertically-align-uilabel-text-with-constraints-and-no-wrap-auto-layout-single