RB의 iOS 개발 이야기

UIButton 가변 너비 & 줄바꿈 문제: titleLineBreakMode로 해결! 본문

iOS/Swift

UIButton 가변 너비 & 줄바꿈 문제: titleLineBreakMode로 해결!

RaeBaek 2025. 7. 2. 11:52

최근에 진행 중인 내일배움캠프 최종 프로젝트 베스트위시 iOS 앱에서 홈 화면의 플랫폼 필터링 기능을 구현하다가 예상치 못한 UI 깨짐 이슈를 겪어 공유하고자 포스팅합니다!

 

1. 문제 상황

먼저 제가 구현한 레이아웃 구조입니다.

  • 홈 화면(위시리스트) → 쇼핑몰 위시리스트 섹션
  • 필터 영역 → Cell 내 UIButton
  • 각 셀 안에 플랫폼 이름을 표시하는 버튼(UIButton) 배치
  • 버튼의 높이는 고정(33), 가로 너비는 타이틀 길이에 따라 유동적 변경 필요

문제는 버튼의 타이틀이 길어지면 버튼이 두 줄 이상으로 줄바꿈이 발생하면서

버튼의 캡슐 모양이 깨지고, 컬렉션 뷰 셀 레이아웃도 깨졌다는 점이었습니다. (하단 이미지 참고)

버튼 타이틀이 두줄 처리됨

 

2. 원인 분석

처음에는 UIButton.Configuration.filled()cornerStyle = .capsule을 사용해 버튼 모양을 캡슐로 설정했습니다.

그런데 iOS에서 UIButton은 기본적으로 타이틀 텍스트가 길면 줄바꿈을 허용합니다. 그러므로

  • 버튼의 높이가 고정이더라도 타이틀이 길면 내부에서 두 줄 이상으로 자동으로 줄바꿈이 발생
  • 버튼의 높이는 그대로지만 타이틀이 두 줄로 늘어나면서 한 줄로 보여야 하는 타이틀의 UI가 깨지게 됨

결국 줄바꿈을 막고, 한 줄로만 출력되도록 강제해야 한다는 점이 원인!

 

3. 해결 방법

문제를 해결하기 위해 찾은 방법은 바로 titleLineBreakMode 입니다.

 

UIButton.Configuration에서

configuration.titleLineBreakMode

 

.byTruncatingTail 로 설정하면 타이틀 텍스트가 한 줄을 넘어가더라도 줄바꿈을 하지 않고 한 줄로 유지 + 말줄임표 처리를 해줍니다.

 

4. 적용 코드 및 스크린샷

아래는 프로젝트에 적용한 코드 스니펫입니다.

func configure(type: Int, isSelected: Bool, isFirst: Bool, isLast: Bool) {
    let titleFont = UIFont.font(.pretendardBold, ofSize: 14)

    var config = _platformButton.configuration ?? UIButton.Configuration.filled()
    config.cornerStyle = .capsule
    config.titleLineBreakMode = .byTruncatingTail
    config.attributedTitle = AttributedString(PlatformEntity.allCases[type].platformName, attributes: AttributeContainer([.font: titleFont]))

    config.baseForegroundColor = isSelected ? .gray0 : .gray500
    config.baseBackgroundColor = isSelected ? .primary300 : .gray0
    _platformButton.configuration = config

    _platformButton.layer.borderWidth = isSelected ? 0 : 1.5
    _platformButton.layer.borderColor = isSelected ? nil : UIColor.gray100?.cgColor
    _platformButton.layer.cornerRadius = isSelected ? 0 : 16.5
    _platformButton.sizeToFit()

    _platformButton.snp.remakeConstraints {
        $0.verticalEdges.equalToSuperview()
        $0.leading.equalToSuperview().offset(isFirst ? 20 : 9)
        $0.trailing.equalToSuperview().offset(isLast ? -20 : 0)
        $0.height.equalTo(33)
    }
}

 

위 코드 스니펫과 같이 설정하면

  • 버튼은 항상 한 줄로 출력
  • 버튼의 가로 길이는 sizeToFit() 덕분에 텍스트 길이에 따라 유동적으로 맞춰짐
  • 높이는 고정(33) 및 .capsule 스타일을 유지할 수 있음

버튼 타이틀 한 줄 처리

 

5. 마무리 & 팁

이번 UIButton 구현에서 깨달은 핵심 포인트

  • UIButtonConfiguration으로 꾸밀 때는, 줄바꿈 관련 옵션도 직접 설정해야 한다는 점.
  • titleLineBreakMode는 텍스트가 긴 버튼이나 라벨에서 UI 깨짐 방지에 꼭 필요하다는 점.

 

캡슐 버튼처럼 고정 높이에 유동 너비를 쓰는 경우에는 titleLineBreakModesizeToFit() 조합을 기억해두면 비슷한 문제를 쉽게 해결할 수 있다!

읽어주셔서 감사합니다!