라이브 - 공지 영역 너비가 넘어가는 현상 수정

This commit is contained in:
Yu Sung 2023-11-18 00:39:24 +09:00
parent 0e0d7a3c24
commit aa676581d3
1 changed files with 44 additions and 51 deletions

View File

@ -12,6 +12,7 @@ import PopupView
struct LiveRoomView: View { struct LiveRoomView: View {
@State private var isShowingNewChat = false @State private var isShowingNewChat = false
@State private var isShowPhotoPicker = false @State private var isShowPhotoPicker = false
@State private var noticeViewHeight: CGFloat = UIFont.systemFontSize
let columns = [ let columns = [
GridItem(.flexible()), GridItem(.flexible()),
@ -47,6 +48,7 @@ struct LiveRoomView: View {
.stroke(Color(hex: "ff5c49"), lineWidth: 1) .stroke(Color(hex: "ff5c49"), lineWidth: 1)
) )
.onTapGesture { .onTapGesture {
viewModel.isExpandNotice = false
if let liveRoomInfo = viewModel.liveRoomInfo, liveRoomInfo.creatorId == UserDefaults.int(forKey: .userId) { if let liveRoomInfo = viewModel.liveRoomInfo, liveRoomInfo.creatorId == UserDefaults.int(forKey: .userId) {
viewModel.isShowLiveEndPopup = true viewModel.isShowLiveEndPopup = true
} else { } else {
@ -166,15 +168,31 @@ struct LiveRoomView: View {
Text("[공지]") Text("[공지]")
.font(.custom(Font.bold.rawValue, size: 11.3)) .font(.custom(Font.bold.rawValue, size: 11.3))
.foregroundColor(.white) .foregroundColor(.white)
.onTapGesture {
viewModel.isExpandNotice.toggle()
}
AttributedTextView( if viewModel.isExpandNotice {
attributedString: makeAttributedString(liveRoomInfo.notice), VStack(spacing: 10) {
lineLimit: viewModel.isExpandNotice ? Int.max : 1 TextView(text: liveRoomInfo.notice, dynamicHeight: $noticeViewHeight)
) { .frame(height: viewModel.isExpandNotice ? noticeViewHeight : UIFont.systemFontSize)
UIApplication.shared.open($0)
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(.horizontal, 26.7)
.padding(.vertical, 13.3) .padding(.vertical, 13.3)
@ -182,9 +200,6 @@ struct LiveRoomView: View {
.background(Color(hex: "3d2a6c")) .background(Color(hex: "3d2a6c"))
.padding(.top, 10) .padding(.top, 10)
.contentShape(Rectangle()) .contentShape(Rectangle())
.onTapGesture {
viewModel.isExpandNotice.toggle()
}
} }
if !viewModel.isSpeakerFold { if !viewModel.isSpeakerFold {
@ -914,71 +929,49 @@ struct LiveRoomView_Previews: PreviewProvider {
} }
} }
struct AttributedTextView: UIViewRepresentable { struct TextView: UIViewRepresentable {
let attributedString: NSAttributedString var text: String
let lineLimit: Int @Binding var dynamicHeight: CGFloat
let onURLTapped: (URL) -> Void
func makeUIView(context: Context) -> UITextView { func makeUIView(context: Context) -> UITextView {
let textView = UITextView() let textView = UITextView()
textView.text = text
textView.isEditable = false textView.isEditable = false
textView.isSelectable = false textView.isScrollEnabled = true
textView.isScrollEnabled = false
textView.backgroundColor = .clear textView.backgroundColor = .clear
textView.dataDetectorTypes = .link
textView.font = UIFont(name: Font.light.rawValue, size: 11.3) textView.font = UIFont(name: Font.light.rawValue, size: 11.3)
textView.textColor = .white textView.textColor = .white
textView.textContainer.lineFragmentPadding = 0 textView.textContainer.lineFragmentPadding = 0
textView.textContainerInset = .zero 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 return textView
} }
func updateUIView(_ uiView: UITextView, context: Context) { func updateUIView(_ uiView: UITextView, context: Context) {
uiView.attributedText = attributedString uiView.text = text
uiView.textColor = UIColor.white DispatchQueue.main.async {
uiView.textContainer.maximumNumberOfLines = lineLimit let height = uiView.sizeThatFits(uiView.frame.size).height
uiView.textContainer.lineBreakMode = lineLimit == 1 ? .byTruncatingTail : .byWordWrapping self.dynamicHeight = height > 500 ? 500 : height
}
} }
func makeCoordinator() -> Coordinator { func makeCoordinator() -> Coordinator {
Coordinator(onURLTapped: onURLTapped) Coordinator($dynamicHeight)
} }
class Coordinator: NSObject, UITextViewDelegate { class Coordinator: NSObject, UITextViewDelegate {
let onURLTapped: (URL) -> Void var dynamicHeight: Binding<CGFloat>
let linkAttributeName = NSAttributedString.Key.link.rawValue
init(onURLTapped: @escaping (URL) -> Void) { init(_ dynamicHeight: Binding<CGFloat>) {
self.onURLTapped = onURLTapped self.dynamicHeight = dynamicHeight
} }
@objc func handleTapGesture(_ gesture: UITapGestureRecognizer) { func textViewDidChange(_ textView: UITextView) {
let textView = gesture.view as? UITextView DispatchQueue.main.async {
let location = gesture.location(in: textView) self.dynamicHeight.wrappedValue = textView.sizeThatFits(textView.frame.size).height
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)
}
}
} }
} }
} }
} }