[Swift] label의 Line Height 설정 및 가운데 정렬

Set Label lineHeight and center vertically

naljin
12 min readAug 25, 2020

요구사항

내가 원하던건 이거시여따. 바로 label의 line height를 지정하는 것!

lineHeight는 32pt

line height를 따로 지정안하면 어케 되냐구여? 이렇게 딱 달라붙슴다

아~~ 폰트 사이즈 넘는 line Height 지정하구 싶다구여~~~~~~ 광광

line height / font size

1차 시도

그래서 lineHeight 지정하는 함수 만들었지롱

self.titleLabel.setTextWithLineHeight(text: text, lineHeight: 32)

자자,, 뭔 함수냐면 NSMutableParagraphStyleminimumLineHeightmaximumLineHeight 속성을 이용해서 내가 원하는 높이로 조정한것!

하지만 인생사 내맘ㄷㅐ로 될리 없쥬?

짜잔~ 높이는 조절 됐지만 텍스트가 line의 밑에 가서 붙습니다~ (환장)

2차 시도

역시 스택오버플로우에는 나랑 똑같이 질문한 사람이 있었쥬~?

답변은 .baselineOffset이라는 NSAttributedStringKey를 이용한다!

위에서 선언한 attributes 변수에는 .paragraph만 있었쥬? 여기서 .baselineOffset 도 추가해봅시다

let attributes: [NSAttributedString.Key: Any] = [.paragraphStyle: style,.baselineOffset: (lineHeight - font.lineHeight) / 4 // 추가!!️️🤟]

두둥 원하는 대로 나왔다.

의문점 🤔

아니 근데 .baselineOffset 에 설정된 값을 다시 잘보자.

.baselineOffset: (lineHeight - font.lineHeight) / 4

(원하는 line 높이— font의 높이) / 4 인데…

baselineOffset이라 함은 밑에서부터 얼만큼 떨어져 있다는거 아님요??? 그럼 (원하는 line 높이 — font의 높이) / 2 만큼 떨어져야하는거 아니냐고요~

그래서 값을 바꿔봤다

.baselineOffset: (lineHeight - font.lineHeight) / 2

앗 오히려 위로 딱 달라가서 붙는다? 띠용?

엥 도대체 왜요 ㅠ 수포자는 울어요 광광

좀 더 공부하고 이치를 깨달으면 업데이트 하겠슴~ 알려주시면 더 좋고~ 일단 되는거 기록 조짐~

아니 좀 더 봤는데도 절대 모르겠는데????????????????????????????????????????????뭐지 왜지????????????????? 엥??????????????

깨달음의 여정 🚗 (진행중)

모든것을 깨달은줄 알고 다른 글 찌다가 여전히 모르겠어서 여기에 덧붙입니다..^^ 다 깨달으면 꼭 따로 글 파야지..ㅂㄷㅂㄷ

모름지기 lineHeight와 baseLine을 들었을때 한국인이라면 아래 같이 생각하는게 국룰아니겠음요?

근데 lineHeight 의 찐 공식은 이렇게 생겨먹었어요..

lineHeight = ascent + descent + leading

오잉? 각각이 뭔지는 그림을 보면 한번에 이해가 될 겁니다

모든것의 원흉 (https://developer.apple.com/library/archive/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/CustomTextProcessing/CustomTextProcessing.html)

- ascent: 글자의 윗부분
- descent : baseline 밑 부분
- leading : vertical spacing

아니 님들 저거 어디서 본거 같지 않음여?ㅎㅎ바로 바로 초딩때 ㄷㅏ닌 영어학원 공책이랑 비슷하게 생겼는데 ^^ 떡밥회수 미쳤다리~

j나 q 쓸때 저 빨간 선 밑으로 썼던거 저만 기억남요?ㅎ 위에 그림에서도 j는 밑으로 튀어나와있잖아요? 허허,, baseLine은 맨 밑줄이 아니라 ascender과 descender 사이의 경계선이었습니다…

.baselineOffset 속성은 character의 offset이 baseline으로부터 얼마만큼 떨어져있나 point로 나타내는거잖아요?

baselineOffset = 0

즉, 빨간선으로부터 얼마나 떨어져있냐하는 문제란 말이죠.

이렇게 baseLine이 맨 아래인줄 알았을때는 (lineHeight — font.lineHeight) / 2 처럼 구하는게 맞았겠지만,

baseLine은 font의 descender과 leading 만큼 떨어져있다! 라는 사실을 알고나서는 (lineHeight — font.lineHeight) / 2 만큼 떨어트린 후 descender와 leading만큼 내려야겠다라는 생각이 드시나요?

수학 멍청이인 저는 이해 했다가도 또 헷갈리고 그래서 그림으로 그려봤어요

노란색 박스가 원래 내가 띄우려고 하는 높이일때..

baseLine이 맨 아래라면 저 계산이 딱 맞지만, 사실은 descender와 leading만큼 떨어져있으니 그만큼 내려야하는거죠

자 그러면 실제 font의 속성 값을 확인해볼게요

let font = UIFont.systemFont(ofSize: 22)print(font.ascender) //20.9print(font.descender) //-5.3print(font.lineHeight) //26.3print(font.leading) // 0

엥 근데 여기선 leading이 0 이네요. 더 정확히 확인해보고자 leading 값이 0이 아닌 폰트로 다시 출력을 해봤어요

UIFont(name: "HiraginoSans-W3", size: 22)print(font.ascender) //19.36print(font.descender) //-2.6399999999999997print(font.lineHeight) //22.0print(font.leading) // 11.0

??????????????????????????????????????????????????????????????

출력안해봤으면 어쩔뻔 ㅋㅎㅋㅎ…

lineHeight = ascender + |descender| 네요..? 그리고 leading은 descent 밑에 있는 엄청 쪼매낸 값 아니었나???

저 밑에 값이 leading이라며..!!!!!!1

The leading value represents additional space between lines of text and is measured in points.

라며!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 쾅쾅

값이 11이나 튀어나온걸로 봐서 아닌거 같은디..

HIG 문서에 나오는 leading…

아 모르겠고 leading은 신경 일단 안쓸거임. leading의 정확한.. 의미?를 알게 되면 다시 추가하겠음요 ㅡㅡ 내 맘대로 다시 정의 ㄱㄱ

baseLine은 font의 descender 만큼 떨어져있다! 따라서 텍스트를 가운데로 위치시키려면 baseline에서 (lineHeight — font.lineHeight) / 2 만큼 떨어트린 후 descender만큼 내려야함!

.baselineOffset: (lineHeight - font.lineHeight) / 2 + font.descender

앗 그나저나,, 내린다면서.. + font.descender 플러스잖아?? 라고 한다면 아주 좋은 발견입니당. 위에서 이미 눈치채신분도 있겠지만 descender는 baseLine을 기준으로 offset 값을 return하는데 밑으로 떨어져있으면 음수를 반환하기 때문에 +를 한거랍니다.

아 오키오키 튼

.baselineOffset: (lineHeight - font.lineHeight) / 2

이렇게 하면 엄청 높이 붙었던 이유가 base line이 위에 있기 때문이란말이지?

진짜 그런지 확인해볼까유?

아닌데용 ㅎ 더 떨어져있는데용 ㅎ

아아아아아아아아ㅏ아아아아아아악빡쳐어어어엉어어어어어어어!!!! 왜!!!!!!!!!왜!!!!!!!왜!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

심지어 그리고 또 다른 환장 포인트는 저 text 감싸고 있는 불투명한 상자 있잖아요..? lineHeight에 맞춘건데 저럼 ㅎ Ascent에 text가 꽉차지도 않음 ㅎㅎ 저렇게 안채워져있으면 가운데를 어떻게 맞춰요~~!!!

예??????????????안채워져있냐고요 왜애애이ㅣ애왜애애애

심지어 한글은 descent 가 아예 안차있는것도 아니고 애-매 하게 차있어가지고 만약 저 ㄱㅖ산이 제대로 됐다고 했을때 descent 를 추가로 빼버릴 수도 없고 안뺄수도 없음……… ㅎㅎ

근데 제가 왜 전에 모든걸 다 깨달은줄 알았냐면

(lineHeight — font.lineHeight) / 2 + font.descender

처음 공식대로 했을ㄸㅐ 가운데처럼 나왔거등여 ㅎㅎ 이것도 우연의 결관가?? 모르것다~~~~~~₩

언젠가 깨닫는 날이 오길 바라며,,, 기약 없이 미룬다!ㅎㅎ

+) 23.07.12

저러고 도망친지 어언 삼년.. 누군가 알려주길 바랬는데 그냥 냅다 뷰랑 클랩수만 늘어가서 엥 이게 아닌데여…?? 싶었다가 오늘 카톡으로 알려주는 사람이 나왔읍니다.

Xcode 버그였다가 잠수함 패치로 해결이 되었다고 하는데여, 냅다 카톡 놓고 가겠습니다 총총

1차 참고

2차 참고

--

--