라이브 - 공지 영역 너비가 넘어가는 현상 수정
This commit is contained in:
parent
0e0d7a3c24
commit
aa676581d3
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue