티스토리 뷰
API에서 contents에서 아예 HTML이 온다면 어떻게 해야 깔끔하게 뷰로 보여줄 수 있을까?
Webview로 보여주면 간단하겠지만... 그건 원하지 않았다. 그 밑에 들어올 뷰들이 있고, 내가 하고싶은거는 HTML을 네이티브 텍스트처럼 렌더링 하는 일이었기 때문이다.
찾아보니 UIKit에 있는 UITextView에 attributedText에 넣으면 가능하다는걸 알았다. UIViewRepresentable을 채택해서 PostHTMLView을 만들었다.
struct HTMLView: UIViewRepresentable {
let html: String
func updateUIView(_ uiView: UITextView, context: UIViewRepresentableContext<Self>) {
DispatchQueue.main.async {
let addCss = "<head><style>" +
"""
@font-face {
font-family: "사용할폰트";
}
body {
font-family: "사용할폰트";
line-height: 1.5;
}
img {
width: \(UIScreen.main.bounds.width * 0.95);
height: auto;
}
"""
+ " </style></head>" + "<body>" + html + "</body>"
let data = Data(addCss.utf8)
if let attributedString = try? NSAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
{
uiView.isEditable = false
uiView.attributedText = attributedString
}
}
}
func makeUIView(context: UIViewRepresentableContext<Self>) -> UITextView {
let uiTextView = UITextView()
uiTextView.isScrollEnabled = false
return uiTextView
}
}
그리고 바깥쪽의 SwiftUI 뷰에서 이 PostHTMLView를 콜 해줬다. 문제는 지금부터 발생했다.
나는 ScrollView안에 같은 스크롤로 여러가지 콘텐츠가 들어가길 바랬다.
ScrollView(.vertical) {
HTMLView(html: viewModel.data?.postDesc?.contents ?? "")
.frame(width: UIScreen.main.bounds.width, height: 5000, alignment: .topLeading)
VStack(alignment: .leading) {
Text("타이틀")
TagScrollableView(data: viewModel.data?.postDesc?.relationPlaces ?? [])
}
}
.background(Color.red)
.frame(height: 600)
HTMLView는 makeUIView할 때 scrollable옵션을 빼 둔 상태이다.
'macOS, iOS' 카테고리의 다른 글
[iOS] Picasso의 iOS버전 - KingFisher (0) | 2021.03.15 |
---|---|
[iOS] custom font 추가하기 (0) | 2021.03.15 |
[SwiftUI] UserDefaults의 진화, @AppStorage (0) | 2021.03.09 |
[iOS] Swift에서 몇박 몇일 계산하기 (0) | 2021.03.09 |
[iOS] optional 변수 경고 없이 print하기 (0) | 2021.03.08 |