From d3f663e03537d91c321e217e50bf67dcddf7c692 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Sat, 15 Aug 2026 18:28:07 +0200 Subject: [PATCH] Give the viewer a back chevron and a pencil "Back to documents" spelled out what a chevron says, and took a third of the bar to do it. It is the glyph now, with the words kept as the accessibility label, which is the one reader a chevron is not shorter for. The room that frees goes to editing, which was three taps deep in the menu even for the documents that can take it. It is a pencil in the bar instead - Android has had one for years - and only for those documents: the bar loses the button while a document is being parsed, and gets it back only if odrcore says the result can be written. Editing leaves the menu, so there is one way to reach it rather than two. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Q1T4UTUxDqjCGUn3Uiyhkj --- CHANGELOG.md | 7 +++ .../DocumentViewController.swift | 44 +++++++++++++++---- OpenDocumentReader/Main.storyboard | 11 ++++- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 887d3b0..0f1324c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,13 @@ once the version tag exists. ## [Unreleased] +### Changed + +- The way out of a document is a back chevron, not the words "Back to + documents". +- Documents that can be edited offer a pencil next to the search button. + Editing has left the menu, which is where it used to hide. + ### Fixed - The buttons above an open document no longer sit on the status bar, and the diff --git a/OpenDocumentReader/DocumentViewController.swift b/OpenDocumentReader/DocumentViewController.swift index 84d8e99..0e47961 100644 --- a/OpenDocumentReader/DocumentViewController.swift +++ b/OpenDocumentReader/DocumentViewController.swift @@ -51,6 +51,13 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel @IBOutlet weak var bannerSlotHeight: NSLayoutConstraint! @IBOutlet weak var barButtonItem: UIBarButtonItem! @IBOutlet weak var searchButton: UIBarButtonItem! + @IBOutlet weak var editButton: UIBarButtonItem! + + /// The bar as the storyboard has it, and the same without the edit button. + /// Taken before anything is removed, since that is the only moment both are + /// there to be read. + private lazy var toolBarItems: [UIBarButtonItem] = toolBar.items ?? [] + private lazy var toolBarItemsWithoutEdit: [UIBarButtonItem] = toolBarItems.filter { $0 !== editButton } /// Fills the banner slot when no ad does. Sits on top of `bannerSlot` rather than in the /// layout chain, so the slot keeps its height and nothing below it moves. @@ -93,7 +100,13 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel setVCconstraints() hideSearchBar() - barButtonItem.title = NSLocalizedString("back_to_documents", comment: "") + // the chevron says where it goes; the words are for VoiceOver, which is + // the one reader a glyph is no shorter for + barButtonItem.accessibilityLabel = NSLocalizedString("back_to_documents", comment: "") + editButton.accessibilityLabel = NSLocalizedString("menu_edit", comment: "") + + // nothing is editable until a document says so + showEditButton(false) setUpHouseAd() } @@ -323,6 +336,20 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel findAll(searchText: searchText) } + @IBAction func editButton(_ sender: UIBarButtonItem) { + editDocument() + } + + /// In the bar for the documents that can be edited, and only while they are + /// not being edited already. Every other document keeps the room for itself. + private func showEditButton(_ show: Bool) { + toolBar.items = show ? toolBarItems : toolBarItemsWithoutEdit + } + + private func updateEditButton() { + showEditButton((document?.isEditable ?? false) && !(document?.edit ?? false)) + } + @IBAction func searchButton(_ sender: UIBarButtonItem) { AnalyticsManager.shared.report("menu_search") AnalyticsManager.shared.report(AnalyticsConstants.eventSearch) @@ -422,14 +449,7 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel @IBAction func showMenu(_ sender: Any) { let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) - if (document?.isEditable ?? false) && !(document?.edit ?? false) { - alert.addAction( - UIAlertAction( - title: NSLocalizedString("menu_edit", comment: ""), style: .default, - handler: { (_) in - self.editDocument() - })) - } + // editing is not in here: it is the pencil in the bar if document?.edit ?? false { alert.addAction( @@ -606,6 +626,7 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel self.webview.loadFileURL(doc.fileURL, allowingReadAccessTo: doc.fileURL) searchButton.isEnabled = false + showEditButton(false) AnalyticsManager.shared.report( "load_success", @@ -637,6 +658,9 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel // only what odrcore translated is searchable, and a later parse — after // a password, say — may well get there searchButton.isEnabled = true + + // whether this one can be edited is not known until it is parsed + showEditButton(false) } func documentLoadingCompleted(_ doc: Document) { @@ -644,6 +668,8 @@ class DocumentViewController: UIViewController, DocumentDelegate, UISearchBarDel progressBar.isHidden = true + updateEditButton() + let fileType = doc.fileURL.pathExtension.lowercased() AnalyticsManager.shared.report( diff --git a/OpenDocumentReader/Main.storyboard b/OpenDocumentReader/Main.storyboard index 35be366..850dd95 100644 --- a/OpenDocumentReader/Main.storyboard +++ b/OpenDocumentReader/Main.storyboard @@ -38,12 +38,18 @@ - + + + + + + + @@ -100,6 +106,7 @@ + @@ -213,8 +220,10 @@ + +