일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- Swift5
- Moya
- observe(on:)
- flatmap
- 라이징캠프
- UICollectionViewListCell
- distinctUntilChanged
- ContentMode
- UIListContentConfiguration
- IOS
- alamofire
- SWIFT
- shareextension
- Xcode
- QoS
- uibutton.configuration
- UIKit
- 개발블로그
- iOS교육
- RxSwift
- .filled
- customButton
- 컴공선배
- interceptor
- defaultContentConfiguration
- cellForRowAt
- ReactiveX
- swift6
- RequestInterceptor
- RxCocoa
- Today
- Total
RB의 iOS 개발 이야기
UIButton 가변 너비 & 줄바꿈 문제: titleLineBreakMode로 해결! 본문
최근에 진행 중인 내일배움캠프 최종 프로젝트 베스트위시 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 구현에서 깨달은 핵심 포인트
- UIButton을 Configuration으로 꾸밀 때는, 줄바꿈 관련 옵션도 직접 설정해야 한다는 점.
- titleLineBreakMode는 텍스트가 긴 버튼이나 라벨에서 UI 깨짐 방지에 꼭 필요하다는 점.
캡슐 버튼처럼 고정 높이에 유동 너비를 쓰는 경우에는 titleLineBreakMode와 sizeToFit() 조합을 기억해두면 비슷한 문제를 쉽게 해결할 수 있다!
읽어주셔서 감사합니다!
'iOS > Swift' 카테고리의 다른 글
DispatchQueue의 qos는 무엇인가? (0) | 2024.01.14 |
---|---|
Status Code에 따른 네트워크 처리 (0) | 2023.12.05 |
그래프(Graph), 트리(Tree), BFS/DFS 정리 (0) | 2023.10.13 |
Swift - TableView / UIListContentConfiguration이란 무엇인가 (0) | 2023.09.15 |
UIImageView의 contentMode에 대한 정리 (0) | 2023.09.02 |