iOS 18.4 beta 1 and 2 do not fix the issues.
I realised selection.bounds(at: page)
delivers more correct results than page.characterBounds(at: index)
. But not as good as characterBounds(at) for iOS 17 and earlier.
// page: PDFPage
for (index, character) in page.enumerated() {
let range = NSRange(location: index, length: 1)
guard let selection = page.selection(for: range) else { continue }
let charBounds = selection.bounds(for: page)
}