Files
vorleser/Vorleser-iOS/ReadingTextView.swift

66 lines
1.9 KiB
Swift

import SwiftUI
import UIKit
import VorleserKit
struct ReadingTextView: UIViewRepresentable {
let text: String
let highlightedRange: Range<Int>?
let onTapCharacter: (CharacterOffset) -> Void
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.isEditable = false
textView.isSelectable = false
textView.font = .preferredFont(forTextStyle: .body)
textView.textContainerInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
let tap = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleTap(_:)))
textView.addGestureRecognizer(tap)
return textView
}
func updateUIView(_ textView: UITextView, context: Context) {
let attributed = NSMutableAttributedString(
string: text,
attributes: [
.font: UIFont.preferredFont(forTextStyle: .body),
.foregroundColor: UIColor.label,
]
)
if let range = highlightedRange,
range.lowerBound >= 0,
range.upperBound <= text.count {
let nsRange = NSRange(location: range.lowerBound, length: range.upperBound - range.lowerBound)
attributed.addAttribute(.backgroundColor, value: UIColor.systemYellow.withAlphaComponent(0.3), range: nsRange)
}
textView.attributedText = attributed
}
func makeCoordinator() -> Coordinator {
Coordinator(onTapCharacter: onTapCharacter)
}
class Coordinator: NSObject {
let onTapCharacter: (CharacterOffset) -> Void
init(onTapCharacter: @escaping (CharacterOffset) -> Void) {
self.onTapCharacter = onTapCharacter
}
@objc func handleTap(_ gesture: UITapGestureRecognizer) {
guard let textView = gesture.view as? UITextView else { return }
let point = gesture.location(in: textView)
let characterIndex = textView.offset(
from: textView.beginningOfDocument,
to: textView.closestPosition(to: point) ?? textView.beginningOfDocument
)
if characterIndex < textView.text.count {
onTapCharacter(characterIndex)
}
}
}
}