UI: "Live Arrivals" Title & Update Status Layout#1041
UI: "Live Arrivals" Title & Update Status Layout#1041Vedd-Patel wants to merge 2 commits intoOneBusAway:mainfrom
Conversation
aaronbrethorst
left a comment
There was a problem hiding this comment.
Hey Vedd - this looks like a great start, but I think the title bar UI can be made even simpler. Let's set the title of the view controller to be the name of the stop, and then hide it from sighted users with this:
self.navigationItem.titleView = UIView()
that way, users who depend on a screen reader will have more context and we won't have any extra text consuming space in the navigation bar.
5466c1c to
4c26953
Compare
aaronbrethorst
left a comment
There was a problem hiding this comment.
Hey Ved - nice work on separating the "Updated" timestamp from the navigation title. The approach of using navigationItem.titleView = UIView() for visual hiding while keeping self.title for screen readers is exactly what I had in mind. A few things to address before this is ready to merge:
Critical
1. Hardcoded "Live Arrivals" string is not localized
StopViewController.swift:579
self.title = stop?.name ?? "Live Arrivals"All user-facing strings in the codebase go through OBALoc(...) — this is especially important since the app ships as KiedyBus in Polish. Please add a localized string to Strings.swift:
public static let liveArrivals = OBALoc("common.live_arrivals", value: "Live Arrivals", comment: "Fallback title for the stop arrivals screen when the stop name is not yet available.")Then reference it: self.title = stop?.name ?? Strings.liveArrivals
2. Existing title = Strings.updating on line 510 conflicts with the new title scheme
StopViewController.swift:510
func updateData() async {
guard let apiService = application.apiService else { return }
title = Strings.updating // ← overwrites stop name every refresh cycleThis line was there before your PR, but it now creates a problem: every 30 seconds when data refreshes, self.title flips from the stop name to "Updating…" and back. Sighted users won't see it (the titleView is hidden), but screen readers will announce "Updating…" as the page title during every refresh. That undermines the whole point of setting the title to the stop name for accessibility.
Fix: Change line 510 to update the status label instead:
statusLabel.text = Strings.updatingImportant
3. Status label reserves vertical space even when empty
StopViewController.swift:219
statusLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 16),The minimum height constraint + padding means there's always a ~24pt gap between the nav bar and the list content, including during initial load when the label is empty. Consider either removing the minimum height constraint so the label naturally collapses to zero height when empty, or starting with statusLabel.isHidden = true and showing it once content is available.
4. Redundant background color on statusLabel
StopViewController.swift:65
label.backgroundColor = ThemeColors.shared.systemBackgroundThe parent view already sets view.backgroundColor = ThemeColors.shared.systemBackground in viewDidLoad, so this is redundant. Labels default to a clear background, which is fine here since the parent provides the color. You can remove this line.
Fit and Finish
5. Set an initial title in viewDidLoad
Since updateTitle() isn't called until after the first network response, and line 510 sets it to "Updating…" before that, screen readers will briefly see "Updating…" as the title. Adding self.title = stop?.name ?? Strings.liveArrivals in viewDidLoad (after your titleView = UIView() line) would provide immediate context.
Description
I have refactored the Stop Detail header to improve the layout. Previously, the navigation bar title displayed the dynamic "Updated: [Time]" string. I have now separated this into two distinct elements:
statusLabelpositioned below the navigation bar.Changes
StopViewController.swift:statusLabel(using.footnotestyle and.secondaryLabelcolor).viewDidLoadto add the label and set up constraints relative to the Safe Area.updateTitle()to set the timestamp text onstatusLabelinstead ofself.title.Screenshot
Linked Issues