Trouble Shooting

[iOS-Swift] 한글 줄바꿈 (Line Break) 어색하지 않게 하기

차코.. 2024. 10. 7. 19:28

✅ 들어가기

 

 

카카오톡에는 제가 정말 좋아하는 기능이 있습니다.

 

바로바로... 오늘의 운세를 점쳐볼 수 있는

오늘의 포춘쿠키 기능인데요.

 

오늘의 포춘쿠키

 

 

줄바꿈을 살짝 살펴보면 ..

 

포춘쿠키의 문구가 컴포넌트 너비의 최대가 넘어가면,

딱 그 너비만큼 채운 뒤 줄바꿈을 해주고 있어요.

 

 

어색하다 .ㅋ

 

 

 

어떻게 하면 사용자가 읽기 편리한 개행을 할 수 있을지는

UX적인 관점이 들어가야 할 것 같은데요.

 

 

저는 UX에 대해 지식이 깊지 않아서 잘 알지는 못하지만,

 

그냥 한국인 입장에서...

우리말에서 자연스럽게 진행되는 개행

의미 중점적으로 되기 때문에 알고리즘으로 구현하기는 어려울 거라 생각했습니다.

 

 

예를 들어, "나는 학원에 가기 싫은데 엄마가 화를 내서 어쩔 수 없다."

와 같은 문장이 있다면

 

나는 학원에 가기 싫은데
엄마가 화를 내서 어쩔 수 없다

 

 

혹은, "나는 어제 배가 고파서 밤에 라면을 먹었다."

와 같은 문장이라면

 

 

나는 어제 배가 고파서
밤에 라면을 먹었다.

 

 

와 같이 앞뒤 내용이 반전이 되거나,

일의 순서와 같은 의미적인 부분들을

 

사람은 자동으로 머릿속에 그리며 개행을 하기 때문에,

 

알고리즘에서 단순히 공백과 같은 기준점을 정하거나.. 등의 방법으로는

(사람이 개행하는 것만큼) 자연스러운 개행이 어려울 것이라..

생각했습니다.

 

(물론 복잡한 알고리즘이라면.. 가능할수도...?)

 

 

 

그래서 만약 아래 사진처럼 중앙 정렬이 되어 있고,

길이가 뚜렷하지 않은 문장(그렇다고 너무 길지도, 짧지도 않은)의 개행을 시도해야 할 때

어떻게 하면 최대한.. 자연스럽게 할 수 있을지 고민해보았습니다.

 

 

이렇게..? 하고 싶다면

 

 

그니까 ㅋ 설명한 상황이 애매한데

 

딱 오늘의 포춘쿠키처럼 적당한 길이의,

화면에서 강조되어야 하는 랜덤 문장이 들어올 때

이 문장에 최대한 자연스럽게 개행을 주고 싶었던 것입니다..

 

물론 위 모습도 의미적인 개행(?)이 되려면

솔직한 것은 좋지만 \n 에서 끊어줘야 하겠지만..

 

위 아래 문장의 최대한 비율을 맞춰서

UI를 해치지 않게 구현하고 싶었습니다.

 

 

 

✂️ 시도해 본 방법들..

 

우선, 오늘의 포춘쿠키 글귀를 예시로 들어보겠습니다.

 

한 문자열을 두 줄로 나누려면 어떻게 해야할까?

 

일단은 그냥 냅다 중앙을 잘라봅니다.

 

첫번째 해결방안?

 

 

아.. 운 좋게도 포춘쿠키 예시는...

 

중앙 인덱스가 딱! 어절 단위로 끊겨서

자연스럽게 줄바꿈이 되어버렸네요...? (?)

 

 

이게 아닌데.. 😅 그럼 다른 예시를 들어보겠습니다.

 

 

문제 상황! 두둥

 

 

바로 이것입니다..

 

 

중앙 인덱스가 어절의 중간점이라면

어절 단위로 개행되지 않게 됩니다..

 

 

그럼 그냥 제일 가까운 띄어쓰기 기준으로 자르면 되지!

 

 

 

맞습니다...

 

그냥 어절 단위로 자르면 되죠... 😅

 

 

요렇게..?

 

 

 

하지만 다음과 같은 경우는 생각 못했겠지!

 

 

팟칭

 

 

바로.. 중심 인덱스로부터의 앞쪽이 짧은 경우인데요.

 

무슨 경우일까요

 

 

머리가 넘 작은교

 

 

바로 위처럼.. 중심 인덱스로부터 앞쪽으로 탐색해 나갔을 때,

 

제일 처음 발견되는 공백이 너무 멀리에 있을 경우 (공백의 앞쪽이 너무 짧을 경우),

문장이 소두처럼 어색하게.. 보이는 것입니다.

 

 

 

 

그럼 어떻게 하면 좋을까요?

 

최종 해결! 땅땅

 

 

저는 위와 같이 구현을 해보았는데요...

 

중심 인덱스로부터 앞쪽(즉 개행을 나누었을 때의 윗문장)이

최소한 문장에서 얼마만큼의 비율을 가져갈 수 있도록 보장해서,

 

 

문장이 극단적으로 비율이 맞지 않게

개행되는 경우가 없도록 막아주었습니다.

 

 

 

1. 중심 인덱스를 구한다.
2. (첫번째 탐색) 중심 인덱스부터 앞쪽의 40%에 해당하는 부분까지 탐색한다.
3. 첫번째 탐색에서 공백이 발견되면 잘라주고, (두번째 탐색) 발견되지 않을 경우 뒷쪽을 탐색한다.

 

 

 

이렇게 해서 개행한 문장을 ..

 

적절한 비율로 보이게 만들었습니다.

 

 

 /// 긴 문장을 두 줄로 나누어야 할 경우, 문자열의 중간 인덱스로부터 (문자열의 40%까지) 앞쪽 부분을 탐색해가며
/// 가장 처음 발견되는 공백의 인덱스에 Space('\n')를 삽입함으로써
/// 자연스럽게 문장이 나눠질 수 있도록 합니다.
///
func setLineBreakAtMiddle() -> String {
    let middleIndex = self.index(self.startIndex, offsetBy: self.count / 2)
    // 문자열에서 40%에 해당하는 인덱스
    let minFrontIndex = self.index(self.startIndex, offsetBy: Int(Double(self.count) * 0.4))
    var spaceIndex = self[minFrontIndex...middleIndex].lastIndex(of: " ")

    // 앞쪽에 띄어쓰기가 없으면, 중간 인덱스 뒷쪽의 첫번째 인덱스
    if spaceIndex == nil {
        spaceIndex = self[middleIndex...endIndex].firstIndex(of: " ")
    }

    var result: String = ""

    // 띄어쓰기 지점을 찾아 줄바꿈하기
    if let spaceIndex = spaceIndex {
        let front = self[..<spaceIndex].trimmingCharacters(in: .whitespaces)
        let back = self[spaceIndex...].trimmingCharacters(in: .whitespaces)
        result = front + "\n" + back
    }

    return result
}

 

 

고민해 본 완성 코드는 위와 같습니다.

 

 

 

🤔 다른 방법...?

 

 

 

찾아보니 UILabel의 lineBreakStrategy 속성을 활용해,

 

.hangulWordPriority로 설정해주면

 

 

굳이 공백을 탐색하지 않아도,

어절 단위로 자연스럽게 나누어 줄 수 있다고 합니다.

 

(한글은.. 없을 것 같았는데..)

 

 

 

근데 뭔가.. 멋진 개행을 위해 더 고능한 (?) 방법이 있겠..죠...?

 

앞으로 더 공부를 해보고,

좋은 방법이 있다면 글을 수정해보도록 하겠습니다 🥹

 

 

 

앞으로도~ 사용자가 편안한 앱을 만들기 위해 계속해서 고민해보겠습니다..

 

 

읽어주셔서 감사합니다 :D