summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormojganii <mojgan.jelodar@codic.se>2025-05-12 15:16:52 +0200
committerBug Magnet <marco.nikic@mullvad.net>2025-05-13 14:50:41 +0200
commitcfce7a3b5c90e6918fb2c655cf28a9faeada6b27 (patch)
tree994b95c21dcd99a2f467dbac4c54836133b5fd72
parentdc82a1d4e3e3b3feaad735a6884f61f1bf10cf06 (diff)
downloadmullvadvpn-cfce7a3b5c90e6918fb2c655cf28a9faeada6b27.tar.xz
mullvadvpn-cfce7a3b5c90e6918fb2c655cf28a9faeada6b27.zip
Add custom action at select location for accessibility
-rw-r--r--ios/MullvadVPN/View controllers/SelectLocation/LocationCell.swift82
-rw-r--r--ios/MullvadVPN/View controllers/SelectLocation/LocationDataSource.swift34
-rw-r--r--ios/MullvadVPN/View controllers/SelectLocation/LocationViewControllerWrapper.swift1
3 files changed, 61 insertions, 56 deletions
diff --git a/ios/MullvadVPN/View controllers/SelectLocation/LocationCell.swift b/ios/MullvadVPN/View controllers/SelectLocation/LocationCell.swift
index 7e957cc499..0cfa732856 100644
--- a/ios/MullvadVPN/View controllers/SelectLocation/LocationCell.swift
+++ b/ios/MullvadVPN/View controllers/SelectLocation/LocationCell.swift
@@ -82,14 +82,6 @@ class LocationCell: UITableViewCell {
var isExpanded = false {
didSet {
updateCollapseImage()
- updateAccessibilityCustomActions()
- }
- }
-
- var showsCollapseControl = false {
- didSet {
- collapseButton.isHidden = !showsCollapseControl
- updateAccessibilityCustomActions()
}
}
@@ -130,6 +122,11 @@ class LocationCell: UITableViewCell {
updateLeadingImage()
updateStatusIndicatorColor()
+
+ // Set the accessibility value to indicate selection status
+ accessibilityValue = selected
+ ? NSLocalizedString("Selected", comment: "")
+ : nil
}
private func setupCell() {
@@ -150,11 +147,9 @@ class LocationCell: UITableViewCell {
}
updateCollapseImage()
- updateAccessibilityCustomActions()
updateDisabled(isDisabled)
updateBackgroundColor()
setLayoutMargins()
-
contentView.addConstrainedSubviews([
tickImageView,
statusIndicator,
@@ -191,6 +186,31 @@ class LocationCell: UITableViewCell {
}
}
+ private func setupAccessibility(_ locationCellViewModel: LocationCellViewModel) {
+ isAccessibilityElement = true
+ accessibilityTraits = .button
+
+ // Set the accessibility label to the location name
+ accessibilityLabel = locationCellViewModel.node.name
+
+ // Provide a hint about the action
+ if !locationCellViewModel.node.children.isEmpty {
+ accessibilityHint = locationCellViewModel.node.showsChildren
+ ? NSLocalizedString("Collapses this location.", comment: "")
+ : NSLocalizedString("Expands this location.", comment: "")
+ } else {
+ accessibilityHint = nil
+ }
+
+ let selectAction = UIAccessibilityCustomAction(
+ name: "SelectLocation",
+ target: self,
+ selector: #selector(handleSelectAction)
+ )
+
+ accessibilityCustomActions = [selectAction]
+ }
+
private func updateLeadingImage() {
switch behavior {
case .add:
@@ -263,6 +283,11 @@ class LocationCell: UITableViewCell {
return true
}
+ @objc private func handleSelectAction() -> Bool {
+ delegate?.toggleSelecting(cell: self)
+ return true
+ }
+
private func updateCollapseImage() {
let image = isExpanded ? chevronUp : chevronDown
@@ -270,37 +295,13 @@ class LocationCell: UITableViewCell {
collapseButton.setImage(image, for: .normal)
}
- private func updateAccessibilityCustomActions() {
- if showsCollapseControl {
- let actionName = isExpanded
- ? NSLocalizedString(
- "SELECT_LOCATION_COLLAPSE_ACCESSIBILITY_ACTION",
- tableName: "SelectLocation",
- value: "Collapse location",
- comment: ""
- )
- : NSLocalizedString(
- "SELECT_LOCATION_EXPAND_ACCESSIBILITY_ACTION",
- tableName: "SelectLocation",
- value: "Expand location",
- comment: ""
- )
-
- accessibilityCustomActions = [
- UIAccessibilityCustomAction(
- name: actionName,
- target: self,
- selector: #selector(toggleCollapseAccessibilityAction)
- ),
- ]
- } else {
- accessibilityCustomActions = nil
- }
- }
-
@objc private func toggleCheckboxButton(_ sender: UIControl) {
delegate?.toggleSelecting(cell: self)
}
+
+ override func accessibilityActivate() -> Bool {
+ toggleCollapseAccessibilityAction()
+ }
}
extension LocationCell {
@@ -312,11 +313,10 @@ extension LocationCell {
func configure(item: LocationCellViewModel, behavior: LocationCellBehavior) {
isDisabled = !item.node.isActive
locationLabel.text = item.node.name
- showsCollapseControl = !item.node.children.isEmpty
isExpanded = item.node.showsChildren
- accessibilityValue = item.node.code
+ collapseButton.isHidden = item.node.children.isEmpty
checkboxButton.setAccessibilityIdentifier(.customListLocationCheckmarkButton)
-
+ setupAccessibility(item)
for view in checkboxButton.subviews where view is CheckboxView {
let checkboxView = view as? CheckboxView
checkboxView?.isChecked = item.isSelected
diff --git a/ios/MullvadVPN/View controllers/SelectLocation/LocationDataSource.swift b/ios/MullvadVPN/View controllers/SelectLocation/LocationDataSource.swift
index 4b7485aae5..e497625583 100644
--- a/ios/MullvadVPN/View controllers/SelectLocation/LocationDataSource.swift
+++ b/ios/MullvadVPN/View controllers/SelectLocation/LocationDataSource.swift
@@ -341,21 +341,10 @@ extension LocationDataSource: UITableViewDelegate {
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- guard let item = itemIdentifier(for: indexPath) else { return }
- selectedLocation = item
- var customListSelection: UserSelectedRelays.CustomListSelection?
- if let topmostNode = item.node.root as? CustomListLocationNode {
- customListSelection = UserSelectedRelays.CustomListSelection(
- listId: topmostNode.customList.id,
- isList: topmostNode == item.node
- )
+ guard let cell = tableView.cellForRow(at: indexPath) as? LocationCell else {
+ return
}
-
- let relayLocations = UserSelectedRelays(
- locations: item.node.locations,
- customListSelection: customListSelection
- )
- didSelectRelayLocations?(relayLocations)
+ toggleSelecting(cell: cell)
}
private func scrollToTop(animated: Bool) {
@@ -373,6 +362,21 @@ extension LocationDataSource: @preconcurrency LocationCellDelegate {
}
func toggleSelecting(cell: LocationCell) {
- // No op.
+ guard let indexPath = tableView.indexPath(for: cell),
+ let item = itemIdentifier(for: indexPath) else { return }
+ selectedLocation = item
+ var customListSelection: UserSelectedRelays.CustomListSelection?
+ if let topmostNode = item.node.root as? CustomListLocationNode {
+ customListSelection = UserSelectedRelays.CustomListSelection(
+ listId: topmostNode.customList.id,
+ isList: topmostNode == item.node
+ )
+ }
+
+ let relayLocations = UserSelectedRelays(
+ locations: item.node.locations,
+ customListSelection: customListSelection
+ )
+ didSelectRelayLocations?(relayLocations)
}
}
diff --git a/ios/MullvadVPN/View controllers/SelectLocation/LocationViewControllerWrapper.swift b/ios/MullvadVPN/View controllers/SelectLocation/LocationViewControllerWrapper.swift
index d36f3de288..e7db58800e 100644
--- a/ios/MullvadVPN/View controllers/SelectLocation/LocationViewControllerWrapper.swift
+++ b/ios/MullvadVPN/View controllers/SelectLocation/LocationViewControllerWrapper.swift
@@ -137,6 +137,7 @@ final class LocationViewControllerWrapper: UIViewController {
entryLocationViewController?.setDaitaChip(isDirectOnly)
entryLocationViewController?.toggleDaitaAutomaticRouting(isEnabled: isAutomaticRouting)
} else {
+ segmentedControl.isHidden = true
exitLocationViewController.setObfuscationChip(isObfuscation)
exitLocationViewController.setDaitaChip(isDirectOnly)
}