// // ExpandableTextView.swift // SodaLive // // Created by klaus on 1/6/25. // import SwiftUI struct ExpandableTextView: View { @State private var isExpanded = false // 텍스트 확장 여부 상태 @State private var isTruncated = false // 텍스트 잘림 여부 상태 let text: String var body: some View { let customFont = UIFont(name: Font.medium.rawValue, size: 12) ?? UIFont.systemFont(ofSize: 12) let lineHeight = customFont.lineHeight VStack(alignment: .leading) { Text(text) .font(.custom(Font.medium.rawValue, size: 13.3)) .foregroundColor(Color.gray77) .lineLimit(isExpanded ? nil : 3) // 확장 시 전체 표시, 아니면 3줄로 제한 .truncationMode(.tail) .background( GeometryReader { proxy in Color.clear .onAppear { let size = proxy.size let maxHeight = lineHeight * 3 // 커스텀 폰트의 라인 높이를 사용 isTruncated = size.height > maxHeight && !isExpanded } } ) .frame(maxWidth: .infinity, alignment: .leading) if isTruncated || isExpanded { HStack(spacing: 6.7) { Spacer() Image(isExpanded ? "ic_live_detail_top" : "ic_live_detail_bottom") Text(isExpanded ? "접기" : "펼치기") .font(.custom(Font.medium.rawValue, size: 12)) .foregroundColor(Color.graybb) Spacer() } .contentShape(Rectangle()) .onTapGesture { isExpanded.toggle() } } } } } #Preview { ExpandableTextView(text: "여기에 아주 긴 텍스트를 넣어보세요. SwiftUI에서 Text는 길이에 따라 Truncated 될 수 있습니다. 이 예제는 3줄로 제한하고, 그 이상이면 버튼을 표시합니다. 자세히 보기를 눌러 내용을 확장하거나, 간단히 보기를 눌러 다시 축소할 수 있습니다.") }