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

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 {
@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)
AttributedTextView(
attributedString: makeAttributedString(liveRoomInfo.notice),
lineLimit: viewModel.isExpandNotice ? Int.max : 1
) {
UIApplication.shared.open($0)
.onTapGesture {
viewModel.isExpandNotice.toggle()
}
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<CGFloat>
init(onURLTapped: @escaping (URL) -> Void) {
self.onURLTapped = onURLTapped
init(_ dynamicHeight: Binding<CGFloat>) {
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
}
}
}
}