2014-01-14 1 views
4

저는 AutoLayout을 사용하여 셀의 수직 중심에 몇 개의 레이블을 배치했습니다. 텍스트는 모두 대문자이지만 문제의 UILabel은 심지어 sizeToFit이 적용될 때에도 텍스트 아래에 공간을 남깁니다.이 텍스트는 소문자 y, p 및 q와 같은 글자의 꼬리와 비슷합니다. . 세로로 가운데에 위치하므로 오프셋이 발생하고 텍스트가 몇 픽셀 더 높아야한다는 의미입니다.UILabel을 수직으로 센터링 할 때 Ascender 및 Descender를 무시합니까?

또 다른 질문은 다음과 같습니다. 어 센더 또는 디 센더를 사용하는 문자가 포함되어 있는지 여부에 따라 세로 중심을 지능적으로 조정할 수 있습니까?

예를 들어, 문자열 "abbaba"에는 디 센더가 필요하지 않지만 문자열 "oyyoyo"에는 상승자가 필요하지 않습니다. 모두 대문자로 된 문자열은 디 센더가 필요하지 않습니다. 수직으로 "oyyoyoyo"를 중앙에 배치하면 너무 낮게 나타납니다.

enter image description here

답변

3

감사합니다, Abhinit : 당신이 센더와 소문자에 수직으로 중앙해야하는 경우 당신은에 RECT을 변경할 수 있습니다.

나는 또한 이것을 찾고 있었으므로 텍스트를 원하는대로 정렬하는 데 필요한 정확한 제약 조건을 여기에 게시하고 싶습니다.

이 이미지는 Wikipedia에서 글꼴의 다른 크기 섹션을 보여줍니다.

enter image description here

그래서, 당신은 윗쪽 높이, 캡 높이에서 x 높이 기준 또는 센더 높이에 정렬할지 여부에 따라 라벨을 정렬하는 방법에는 여러 가지가 있습니다.

의 당신이 "안녕하세요"와 같은 모자에 label 포함 된 텍스트가 있고 높이를 모자와 기준에 viewBelow으로 정렬 viewAbove으로 정렬 할 가정 해 봅시다. 예에서 내 유틸리티 클래스 LayoutHelper을 사용하고 있습니다,하지만 난 생각이 분명하다 희망 :

let font = label.font 
let ascenderDelta = font.ascender - font.capHeight 

LayoutHelper() 
    .addViews([ 
     "label":label, "viewAbove":viewAbove, "viewBelow":viewBelow 
    ]) 
    .withMetrics(["ascenderDelta":ascenderDelta]) 
    .addConstraints([ 

     // -- Here the constraints to align to cap height -- 
     "X:label.top == viewAbove.bottom - ascenderDelta", 
     "X:label.baseline == viewBelow.top", 

     ...other constraints... 
    ]) 

참고 :

당신은 할 것이다.에 "자동 정렬"라벨에 대해

:

나는 그것이 등 센더, 승천, 모자,

가 포함되어 있는지 여부에 따라 적절한 선 조정하는 "지능형"라벨을 만드는 방법에 대한 생각합니다

(예 : here)의 음수 인 세트를 사용하여 수행 할 수 있습니다 (예 : insets = {-ascenderDelta, 0, font.descender, 0} 사용). 그러나 당신이 가진 경우에는 오름차순/디 센다를 자릅니다. 어떤 가능한 상승자를 자르지 않고 대문자로 정렬하는 것을 선호합니다.

4

당신은 정확한 높이를 얻을 수 및 크기 UILabel의 해당를 사용하는 UIFont의 'capHeight'와 'xHeight'속성을 사용할 수 있습니다.

물론 이것은 문자열이 소문자이거나 대문자인지 확실하게 알고 있다고 가정합니다. 그렇지 않으면 UILabel에서 setText를 재정의하고 함수가 호출 될 때마다 확인하십시오.

나는 또한 CoreText 더 깊이보고 나는이 http://www.zsiegel.com/2012/10/23/Core-Text-Calculating-line-heights/

+0

대문자 또는 소문자 만이 아니라 소문자의 경우 오름차순 또는 자모가 포함 된 문자를 사용하는지 여부. 'setText'를 오버라이드하는 것은 확실한 아이디어입니다. 문제는, "oyyyo"의 경우 ascender를 조정하려면, 나는 그것을 할 수 없다는 것입니다. 내가 라벨의 높이를 조정하면, 그 상승자가 상단에 남아있을 것입니다. 그렇지 않습니까? – Luke

+1

UIBaselineAdjustmentAlignBaselines가 도움이 될 것으로 생각합니다. 그렇다고해서 UILabel과 UIFont 클래스보다 CoreText를 직접 들여다보고 싶습니다. – Abhinit

2

같은 것을 구현하는 생각이 같은 문제를 겪고과 무승부 방법 UILabel의 서브 클래스 및 변경하여 그것을 해결 : 내 경우에는

- (void)drawRect:(CGRect)rect 
{ 
    CGRect capCenteredRect = CGRectMake(rect.origin.x, (self.font.leading-self.font.capHeight)*0.5f, rect.size.width, rect.size.height); 
    [super drawTextInRect:capCenteredRect]; 
} 

을 UILabel의 수직 중심 맞춤은 항상 일부 픽셀을 벗어나기 때문에 대문자로 중심을 옮길 필요가있었습니다. 당신의 대답을,

CGRectMake(rect.origin.x, (self.font.leading-self.font.xHeight)*0.5f+self.font.descender, rect.size.width, rect.size.height) 
관련 문제