diff --git a/SodaLive/Sources/Live/Room/LiveRoomView.swift b/SodaLive/Sources/Live/Room/LiveRoomView.swift index 0ec6839..aa91b06 100644 --- a/SodaLive/Sources/Live/Room/LiveRoomView.swift +++ b/SodaLive/Sources/Live/Room/LiveRoomView.swift @@ -12,6 +12,7 @@ import PopupView struct LiveRoomView: View { @State private var isShowingNewChat = false @State private var isShowPhotoPicker = false + @State private var noticeViewHeight: CGFloat = UIFont.systemFontSize let columns = [ GridItem(.flexible()), @@ -47,6 +48,7 @@ struct LiveRoomView: View { .stroke(Color(hex: "ff5c49"), lineWidth: 1) ) .onTapGesture { + viewModel.isExpandNotice = false if let liveRoomInfo = viewModel.liveRoomInfo, liveRoomInfo.creatorId == UserDefaults.int(forKey: .userId) { viewModel.isShowLiveEndPopup = true } else { @@ -166,15 +168,31 @@ struct LiveRoomView: View { Text("[공지]") .font(.custom(Font.bold.rawValue, size: 11.3)) .foregroundColor(.white) + .onTapGesture { + viewModel.isExpandNotice.toggle() + } - AttributedTextView( - attributedString: makeAttributedString(liveRoomInfo.notice), - lineLimit: viewModel.isExpandNotice ? Int.max : 1 - ) { - UIApplication.shared.open($0) + if viewModel.isExpandNotice { + VStack(spacing: 10) { + TextView(text: liveRoomInfo.notice, dynamicHeight: $noticeViewHeight) + .frame(height: viewModel.isExpandNotice ? noticeViewHeight : UIFont.systemFontSize) + + Text("닫기") + .font(.custom(Font.light.rawValue, size: 11.3)) + .foregroundColor(.white) + .onTapGesture { + viewModel.isExpandNotice = false + } + } + } else { + Text(liveRoomInfo.notice) + .font(.custom(Font.light.rawValue, size: 11.3)) + .foregroundColor(.white) + .lineLimit(1) + .onTapGesture { + viewModel.isExpandNotice = true + } } - .fixedSize(horizontal: false, vertical: true) - .lineSpacing(6) } .padding(.horizontal, 26.7) .padding(.vertical, 13.3) @@ -182,9 +200,6 @@ struct LiveRoomView: View { .background(Color(hex: "3d2a6c")) .padding(.top, 10) .contentShape(Rectangle()) - .onTapGesture { - viewModel.isExpandNotice.toggle() - } } if !viewModel.isSpeakerFold { @@ -914,71 +929,49 @@ struct LiveRoomView_Previews: PreviewProvider { } } -struct AttributedTextView: UIViewRepresentable { - let attributedString: NSAttributedString - let lineLimit: Int - let onURLTapped: (URL) -> Void - +struct TextView: UIViewRepresentable { + var text: String + @Binding var dynamicHeight: CGFloat func makeUIView(context: Context) -> UITextView { let textView = UITextView() + textView.text = text textView.isEditable = false - textView.isSelectable = false - textView.isScrollEnabled = false + textView.isScrollEnabled = true textView.backgroundColor = .clear + textView.dataDetectorTypes = .link textView.font = UIFont(name: Font.light.rawValue, size: 11.3) textView.textColor = .white textView.textContainer.lineFragmentPadding = 0 textView.textContainerInset = .zero - textView.textContainer.maximumNumberOfLines = lineLimit - textView.textContainer.lineBreakMode = lineLimit == 1 ? .byTruncatingTail : .byWordWrapping - textView.delegate = context.coordinator - - textView.isUserInteractionEnabled = true - - // Add tap gesture recognizer to handle URL tap events - let tapGestureRecognizer = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleTapGesture(_:))) - textView.addGestureRecognizer(tapGestureRecognizer) - return textView } func updateUIView(_ uiView: UITextView, context: Context) { - uiView.attributedText = attributedString - uiView.textColor = UIColor.white - uiView.textContainer.maximumNumberOfLines = lineLimit - uiView.textContainer.lineBreakMode = lineLimit == 1 ? .byTruncatingTail : .byWordWrapping + uiView.text = text + DispatchQueue.main.async { + let height = uiView.sizeThatFits(uiView.frame.size).height + self.dynamicHeight = height > 500 ? 500 : height + } } func makeCoordinator() -> Coordinator { - Coordinator(onURLTapped: onURLTapped) + Coordinator($dynamicHeight) } class Coordinator: NSObject, UITextViewDelegate { - let onURLTapped: (URL) -> Void - let linkAttributeName = NSAttributedString.Key.link.rawValue + var dynamicHeight: Binding - init(onURLTapped: @escaping (URL) -> Void) { - self.onURLTapped = onURLTapped + init(_ dynamicHeight: Binding) { + self.dynamicHeight = dynamicHeight } - @objc func handleTapGesture(_ gesture: UITapGestureRecognizer) { - let textView = gesture.view as? UITextView - let location = gesture.location(in: textView) - - let layoutManager = textView?.layoutManager - let characterIndex = layoutManager?.characterIndex(for: location, in: textView!.textContainer, fractionOfDistanceBetweenInsertionPoints: nil) - - if characterIndex != NSNotFound { - let attributedString = textView?.attributedText - - attributedString?.enumerateAttribute(NSAttributedString.Key(rawValue: linkAttributeName), in: NSRange(location: 0, length: attributedString!.length), options: []) { value, range, _ in - if let url = value as? URL, NSLocationInRange(characterIndex!, range) { - onURLTapped(url) - } - } + func textViewDidChange(_ textView: UITextView) { + DispatchQueue.main.async { + self.dynamicHeight.wrappedValue = textView.sizeThatFits(textView.frame.size).height } } } } +