【IOS】將字型大小不同的文字底部對齊,ios字型大小對齊

來源:互聯網
上載者:User

【IOS】將字型大小不同的文字底部對齊,ios字型大小對齊

從WP轉IOS了,還是放不下......

 

在項目中,要實現多個不同大小的文字   底部對齊的效果   像下面這樣:

(想要的效果)

以為用三個UIFont不同的UILabel  之後讓他們底部對齊就可以了,但是效果是下面這樣的:

 (不想要的效果)

底部完全不對齊呀,為什麼"1314"比兩邊高出了那麼多呀!!!!強迫症不能忍呀!!!

--------------------------------------------------------------------------------

對比:

1.在Windows Phone中 控制項是相對布局

Windows Phone裡面TextBlock需要設定一個固定的 寬度  和 高度 (至少我是這樣做的)

TextBlock不但可以將文字設定為水平置中、偏左、偏右,還可以通過屬性 

text.VerticalContentAlignment=Top/Center/Bottom將文字置於頂部/置中/底部。

2.在IOS中 控制項是絕對布局: 對於一個控制項  需要設定它的frame(包括起始位置、高和寬)

可以通過以下方法直接擷取一個字串的自適應的高度和寬度:(這點覺得比WindowsPhone好)

CGSize labelSize = [@"1314" sizeWithAttributes:@{NSFontAttributeName:kLabelFont}];

而原生的UIlabel只能設定textAlignment文字的水平位移屬性,而無法直接更改豎直方向的位移。

 

WindowsPhone中要實現上面的效果,只需將三個TextBlock置底,TextBlock內容居下,即可對齊。

(這一點我突然的不確定了,好像很多時候我都是直接設定margin來手動對齊的,有空回WindowsPhone看看再修改。)

 

彎路:

所以在IOS處理這個問題的時候,我想著既然三個控制項的底部都是對齊了的,只是高度不一樣,能否仿照著WindowsPhone那樣,

將較高UILabel的內容("1314")豎直位移到最底下呢?

經過查閱  UILabel找到了這些:  

不能直接調用  只能通過繼承來重寫

// override points. can adjust rect before calling super. (在調用父類前  可以調整常值內容的位置TextRect)

// label has default content mode of UIViewContentModeRedraw

- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines;  //重寫來重繪文字地區

- (void)drawTextInRect:(CGRect)rect;  //重寫來重繪文本  重寫時調用super可以按預設圖形屬性繪製

所以為了改變text的位置, 我們只需要改變textRectForBounds的傳回值rect,並且根據這個rect重繪文本就可以了

1、關於contentMode,該模式為視圖提供了多種模式用以適用架構矩形。如果對除UIVewContentModeRedraw之外的模式(如UIViewContentModeScaleToFill)都不滿足需求,或者說有特定需要自訂繪製視圖,可以設定為此值。那麼將在視圖適應架構矩形變化時預設自動調用setNeedsDispllay或setNeedsDisplayInRect:,從而重繪視圖。
2、而向視圖發送setNeedsDisplay(或setNeedsDisplayInRect:)訊息時,無論此時contentMode為何種模式,都將強制調用drawRect:  

主要代碼:(這個代碼網上一大把,自己找去) 

- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines{          //方法裡的形參bounds指的是UILabel的bounds       CGRect rc = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];  //text的bounds    switch (_verticalAlignment) {        case VerticalAlignmentTop:            rc.origin.y = bounds.origin.y;              break;        case VerticalAlignmentBottom:            rc.origin.y = bounds.origin.y + bounds.size.height - rc.size.height;            break;        case VerticalAlignmentMiddle:        default:            rc.origin.y = bounds.origin.y + (bounds.size.height - rc.size.height) / 2;            break;    }     return rc;}- (void)drawTextInRect:(CGRect)rect{    CGRect rc = [self textRectForBounds:rect limitedToNumberOfLines:self.numberOfLines];    [super drawTextInRect:rc];}

然而發現:對於自適應寬高(CGSize)的Label, 設定了verticalAlignment屬性基本上沒多大區別

origin.x  origin.y 均為零   並且SIZE區別幾乎沒有  所有也不會有多大區別。

這裡我進行了一個對比:對於字串@"1314",設定不同的UIFont 觀察UILabel和內部的textRect的大小差別

UIFont                                 1                                         50                                          100

rc(text)                1.000000,2.333333        105.666667,61.000000          208.666667,120.666667

bounds(label)      1.000000,2.193359        105.541992,60.667969          208.349609,120.335938

相差                                    0,0.139974             0.124675,0.332031                0.317058, 0.330729

rc居然還要比bounds大那麼一點點,我認為為了文字不被截取,文字大小還是比其文字邊框還要小的,

並且針對不同大小的UIFont或字型類型,這種小的程度還是不一樣的。

所以就算設定verticalAlignment屬性也發現不了什麼區別。

如果只將文字大小設定更大,導致rc比bounds大,那麼文字部分就可能會被截取;

如果只增加UILabel的大小,導致rc比bounds小,那麼就會看到除了文字外多餘的空白地區;

對於後兩者,設定verticalAlignment屬性,就能夠明顯的看到上下位移了。

所以這種方案對於實現所需效果無效。

 

終點: 

找呀找呀  又找到了另外一種方法,可以通過attributedText屬性讓UILabel顯示富文本

實現一個字串中包含不同顏色、字型大小等。

我封裝了一個方法:

// 擷取帶有不同樣式的文字內容//stringArray 字串數組//attributeAttay 樣式數組- (NSAttributedString *)attributedText:(NSArray*)stringArray attributeAttay:(NSArray *)attributeAttay{  // 定義要顯示的文字內容    NSString * string = [stringArray componentsJoinedByString:@""];  //拼接傳入的字串數組  // 通過要顯示的文字內容來建立一個帶屬性樣式的字串對象    NSMutableAttributedString * result = [[NSMutableAttributedString alloc] initWithString:string];        for(NSInteger i = 0; i < stringArray.count; i++){
     // 將某一範圍內的字串設定樣式 [result setAttributes:attributeAttay[i] range:[string rangeOfString:stringArray[i]]]; } // 返回已經設定好了的帶有樣式的文字 return [[NSAttributedString alloc] initWithAttributedString:result];}

 以及其使用

   NSDictionary *attributesExtra = @{NSFontAttributeName:kLabelFont,//字型大小12                                              NSForegroundColorAttributeName: [UIColor orangeColor]};  NSDictionary *attributesPrice = @{NSFontAttributeName:kPriceFont,//字型大小18                                               NSForegroundColorAttributeName: [UIColor orangeColor]};  NSAttributedString *attributedString = [self attributedText:@[@"¥", @"1314", @"起"]                                                 attributeAttay:@[attributesExtra,attributesPrice,attributesExtra]];   UILabel *price = [[UILabel alloc]init]; 
  price.attributedText = attributedString;   CGRect rect = [attributedString boundingRectWithSize:CGSizeMake(self.width / 2, 100) options:NSStringDrawingUsesLineFragme ntOrigin context:nil];  //此方法擷取到的是自適應的Rect,而不是CGSize 最大Size值為CGSizeMake(self.width / 2, 100)
price.frame = CGRectMake(0,0,rect.size.width, rect.size.height);

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.