Skip to content
This repository was archived by the owner on Nov 7, 2026. It is now read-only.

Commit ef47150

Browse files
Merge pull request #27 from code4teaching/accessibility-canvas
VoiceOver: Diagramm-Blöcke vorlesbar machen
2 parents 7fea89e + f431047 commit ef47150

1 file changed

Lines changed: 21 additions & 0 deletions

File tree

‎VisuStruct-iOS/VisuStructXcodeOpen/VisuStruct/Canvas/DiagramCanvasView.swift‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ struct DiagramCanvasView: View {
267267
Color.clear
268268
.frame(width: cw, height: ch)
269269
.contentShape(Rectangle())
270+
.accessibilityHidden(true)
270271
.onTapGesture {
271272
selectedPath = nil
272273
// iPhone: Einfügemarke durch Tap auf leeren Bereich löschen.
@@ -291,13 +292,16 @@ struct DiagramCanvasView: View {
291292

292293
canvasView(layout: layout, cw: cw, ch: ch)
293294
.allowsHitTesting(false)
295+
// Gezeichnete Fläche; VoiceOver liest stattdessen die Blöcke darüber.
296+
.accessibilityHidden(true)
294297

295298
if let firstRoot = layout.elements.first {
296299
rootInsertBeforeFirstStrip(
297300
firstRootFrame: firstRoot.frame,
298301
canvasWidth: cw,
299302
canvasHeight: ch
300303
)
304+
.accessibilityHidden(true)
301305
}
302306

303307
ForEach(flat, id: \.pathKey) { node in
@@ -408,13 +412,30 @@ struct DiagramCanvasView: View {
408412
.draggable(DiagramDragPayload(raw: ElementPalette.moveDragIdentifier(path: node.idPath))) {
409413
nodeDragPreview(for: node)
410414
}
415+
// VoiceOver: ein Element pro Block (statt der unbeschrifteten Drop-Streifen darin).
416+
.accessibilityElement(children: .ignore)
417+
.accessibilityLabel(accessibilityLabel(for: node))
418+
.accessibilityAddTraits(selectedPath == node.idPath ? [.isButton, .isSelected] : .isButton)
419+
.accessibilityAction {
420+
selectedPath = node.idPath
421+
}
411422
.accessibilityHint(
412423
isPlaceholderNode
413424
? lang.tr("a11y_placeholder_drop")
414425
: lang.tr("a11y_node_drop")
415426
)
416427
}
417428

429+
/// Vorgelesener Name eines Blocks: Elementart und Text, z. B. „Anweisung: int x = 5“.
430+
private func accessibilityLabel(for node: VisuStructLayout.Node) -> String {
431+
// Schlüssel wie in der Palette: element_anweisung, element_verzweigung, …
432+
let kind = lang.tr("element_\(node.element.type)")
433+
let text = node.element.textLines
434+
.joined(separator: " ")
435+
.trimmingCharacters(in: .whitespacesAndNewlines)
436+
return text.isEmpty ? kind : "\(kind): \(text)"
437+
}
438+
418439
private func copyElement(at path: [Int]) {
419440
guard let el = try? VisuStructDocumentEditing.element(at: path, in: document) else { return }
420441
elementClipboard = el

0 commit comments

Comments
 (0)