From b830a26800e433a360465b9d480cb2de483d2818 Mon Sep 17 00:00:00 2001 From: ssig33 Date: Tue, 16 Dec 2025 11:05:06 +0900 Subject: [PATCH] =?UTF-8?q?=E3=83=8E=E3=83=BC=E3=83=88=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?=E3=81=AE=E5=BC=B7=E5=8C=96=E3=81=A8=E6=9F=94=E8=BB=9F=E3=81=AA?= =?UTF-8?q?=E3=83=AA=E3=83=B3=E3=82=AF=E3=83=BBHTML=E5=AF=BE=E5=BF=9C?= =?UTF-8?q?=E3=81=AE=E5=B0=8E=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ノートの表示処理を、通常テキスト・リンク自動検出・HTML埋め込みの三通りで動的に切り替える新ロジックを導入 - ノート内にHTMLが含まれる場合のパース&レンダリングをサポート - テキストから自動でURLを抽出し、クリック可能なリンクとして表示できるように改良 - 表示部分の変更に合わせ、既存のTextウィジェット処理をattributedStringによる表示へと切り替え --- Sources/ContentView.swift | 58 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/Sources/ContentView.swift b/Sources/ContentView.swift index 650f2f1..36e9c7b 100644 --- a/Sources/ContentView.swift +++ b/Sources/ContentView.swift @@ -232,7 +232,7 @@ struct EventDetailView: View { Image(systemName: "note.text") .foregroundColor(.secondary) .frame(width: 20) - Text(notes) + Text(attributedString(from: notes)) .textSelection(.enabled) } } @@ -257,4 +257,60 @@ struct EventDetailView: View { formatter.locale = Locale(identifier: "ja_JP") return formatter.string(from: date) } + + private func isHTML(_ string: String) -> Bool { + let htmlPatterns = ["", "

", "", " AttributedString { + if isHTML(notes) { + return attributedStringFromHTML(notes) + } else { + return attributedStringWithLinks(notes) + } + } + + private func attributedStringFromHTML(_ html: String) -> AttributedString { + let styledHTML = """ + + \(html) + """ + guard let data = styledHTML.data(using: .utf8) else { + return AttributedString(html) + } + do { + let nsAttrStr = try NSAttributedString( + data: data, + options: [ + .documentType: NSAttributedString.DocumentType.html, + .characterEncoding: String.Encoding.utf8.rawValue + ], + documentAttributes: nil + ) + return AttributedString(nsAttrStr) + } catch { + return AttributedString(html) + } + } + + private func attributedStringWithLinks(_ text: String) -> AttributedString { + var attributedString = AttributedString(text) + guard let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else { + return attributedString + } + let matches = detector.matches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count)) + for match in matches { + guard let range = Range(match.range, in: text), + let url = match.url, + let attrRange = Range(range, in: attributedString) else { + continue + } + attributedString[attrRange].link = url + } + return attributedString + } }