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