diff options
| author | mojganii <mojgan.jelodar@codic.se> | 2025-05-12 15:16:52 +0200 |
|---|---|---|
| committer | Bug Magnet <marco.nikic@mullvad.net> | 2025-05-13 14:50:41 +0200 |
| commit | cfce7a3b5c90e6918fb2c655cf28a9faeada6b27 (patch) | |
| tree | 994b95c21dcd99a2f467dbac4c54836133b5fd72 | |
| parent | dc82a1d4e3e3b3feaad735a6884f61f1bf10cf06 (diff) | |
| download | mullvadvpn-cfce7a3b5c90e6918fb2c655cf28a9faeada6b27.tar.xz mullvadvpn-cfce7a3b5c90e6918fb2c655cf28a9faeada6b27.zip | |
Add custom action at select location for accessibility
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) } |
