diff --git a/Session/Components/NewConversationButtonSet.swift b/Session/Components/NewConversationButtonSet.swift index 36c4b9d61..46e19d28c 100644 --- a/Session/Components/NewConversationButtonSet.swift +++ b/Session/Components/NewConversationButtonSet.swift @@ -31,6 +31,14 @@ final class NewConversationButtonSet : UIView { } private func setUpViewHierarchy() { + mainButton.accessibilityLabel = "Toggle conversation options button" + mainButton.isAccessibilityElement = true + createNewPrivateChatButton.accessibilityLabel = "Start new one-on-one conversation button" + createNewPrivateChatButton.isAccessibilityElement = true + createNewClosedGroupButton.accessibilityLabel = "Start new closed group button" + createNewClosedGroupButton.isAccessibilityElement = true + joinOpenGroupButton.accessibilityLabel = "Join open group button" + joinOpenGroupButton.isAccessibilityElement = true let inset = (Values.newConversationButtonExpandedSize - Values.newConversationButtonCollapsedSize) / 2 addSubview(joinOpenGroupButton) horizontalButtonConstraints[joinOpenGroupButton] = joinOpenGroupButton.pin(.left, to: .left, of: self, withInset: inset) diff --git a/Session/Signal/ConversationView/ConversationInputToolbar.m b/Session/Signal/ConversationView/ConversationInputToolbar.m index 05a1a00f4..a397466ec 100644 --- a/Session/Signal/ConversationView/ConversationInputToolbar.m +++ b/Session/Signal/ConversationView/ConversationInputToolbar.m @@ -127,6 +127,8 @@ const CGFloat kMaxTextViewHeight = 120; self.inputTextView.backgroundColor = LKColors.composeViewTextFieldBackground; [self.inputTextView setContentHuggingLow]; [self.inputTextView setCompressionResistanceLow]; + self.inputTextView.accessibilityLabel = @"Input text view"; + self.inputTextView.isAccessibilityElement = YES; SET_SUBVIEW_ACCESSIBILITY_IDENTIFIER(self, _inputTextView); _textViewHeightConstraint = [self.inputTextView autoSetDimension:ALDimensionHeight toSize:kMinTextViewHeight]; @@ -147,11 +149,15 @@ const CGFloat kMaxTextViewHeight = 120; [self.sendButton autoSetDimensionsToSize:CGSizeMake(40, kMinTextViewHeight)]; SET_SUBVIEW_ACCESSIBILITY_IDENTIFIER(self, _sendButton); [self.sendButton addTarget:self action:@selector(sendButtonPressed) forControlEvents:UIControlEventTouchUpInside]; + self.sendButton.accessibilityLabel = @"Send button"; + self.sendButton.isAccessibilityElement = YES; _voiceMemoButton = [UIButton buttonWithType:UIButtonTypeCustom]; UIImage *voiceMemoIcon = [[UIImage imageNamed:@"Microphone"] asTintedImageWithColor:LKColors.text]; [self.voiceMemoButton setImage:voiceMemoIcon forState:UIControlStateNormal]; [self.voiceMemoButton autoSetDimensionsToSize:CGSizeMake(40, kMinTextViewHeight)]; + self.voiceMemoButton.accessibilityLabel = @"Voice message button"; + self.voiceMemoButton.isAccessibilityElement = YES; SET_SUBVIEW_ACCESSIBILITY_IDENTIFIER(self, _voiceMemoButton); // We want to be permissive about the voice message gesture, so we hang diff --git a/Session/Signal/ConversationView/ConversationViewController.m b/Session/Signal/ConversationView/ConversationViewController.m index dda1cfa72..cc8f4c1b4 100644 --- a/Session/Signal/ConversationView/ConversationViewController.m +++ b/Session/Signal/ConversationView/ConversationViewController.m @@ -599,6 +599,8 @@ typedef enum : NSUInteger { self.collectionView.backgroundColor = UIColor.clearColor; UIBarButtonItem *settingsButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Gear"] style:UIBarButtonItemStylePlain target:self action:@selector(showConversationSettings)]; settingsButton.tintColor = LKColors.text; + settingsButton.accessibilityLabel = @"Conversation settings button"; + settingsButton.isAccessibilityElement = YES; self.navigationItem.rightBarButtonItem = settingsButton; if (self.thread.isGroupThread) { diff --git a/Session/View Controllers/DisplayNameVC.swift b/Session/View Controllers/DisplayNameVC.swift index 1a3232412..fd6e0ce28 100644 --- a/Session/View Controllers/DisplayNameVC.swift +++ b/Session/View Controllers/DisplayNameVC.swift @@ -9,6 +9,7 @@ final class DisplayNameVC : BaseVC { private lazy var displayNameTextField: TextField = { let result = TextField(placeholder: NSLocalizedString("vc_display_name_text_field_hint", comment: "")) result.layer.borderColor = Colors.text.cgColor + result.accessibilityLabel = "Display name text field" return result }() diff --git a/Session/View Controllers/HomeVC.swift b/Session/View Controllers/HomeVC.swift index aa5982eec..d05060d1e 100644 --- a/Session/View Controllers/HomeVC.swift +++ b/Session/View Controllers/HomeVC.swift @@ -306,6 +306,7 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol private func updateNavigationBarButtons() { let profilePictureSize = Values.verySmallProfilePictureSize let profilePictureView = ProfilePictureView() + profilePictureView.accessibilityLabel = "Settings button" profilePictureView.size = profilePictureSize profilePictureView.hexEncodedPublicKey = getUserHexEncodedPublicKey() profilePictureView.update() @@ -314,24 +315,33 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, UIScrol let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(openSettings)) profilePictureView.addGestureRecognizer(tapGestureRecognizer) let profilePictureViewContainer = UIView() + profilePictureViewContainer.accessibilityLabel = "Settings button" profilePictureViewContainer.addSubview(profilePictureView) profilePictureView.pin(.leading, to: .leading, of: profilePictureViewContainer, withInset: 4) profilePictureView.pin(.top, to: .top, of: profilePictureViewContainer) profilePictureView.pin(.trailing, to: .trailing, of: profilePictureViewContainer) profilePictureView.pin(.bottom, to: .bottom, of: profilePictureViewContainer) - navigationItem.leftBarButtonItem = UIBarButtonItem(customView: profilePictureViewContainer) + let leftBarButtonItem = UIBarButtonItem(customView: profilePictureViewContainer) + leftBarButtonItem.accessibilityLabel = "Settings button" + leftBarButtonItem.isAccessibilityElement = true + navigationItem.leftBarButtonItem = leftBarButtonItem let pathStatusViewContainer = UIView() + pathStatusViewContainer.accessibilityLabel = "Current onion routing path button" let pathStatusViewContainerSize = Values.verySmallProfilePictureSize // Match the profile picture view pathStatusViewContainer.set(.width, to: pathStatusViewContainerSize) pathStatusViewContainer.set(.height, to: pathStatusViewContainerSize) let pathStatusView = PathStatusView() + pathStatusView.accessibilityLabel = "Current onion routing path button" pathStatusView.set(.width, to: Values.pathStatusViewSize) pathStatusView.set(.height, to: Values.pathStatusViewSize) pathStatusViewContainer.addSubview(pathStatusView) pathStatusView.center(.horizontal, in: pathStatusViewContainer) pathStatusView.center(.vertical, in: pathStatusViewContainer) pathStatusViewContainer.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(showPath))) - navigationItem.rightBarButtonItem = UIBarButtonItem(customView: pathStatusViewContainer) + let rightBarButtonItem = UIBarButtonItem(customView: pathStatusViewContainer) + rightBarButtonItem.accessibilityLabel = "Current onion routing path button" + rightBarButtonItem.isAccessibilityElement = true + navigationItem.rightBarButtonItem = rightBarButtonItem } @objc override internal func handleAppModeChangedNotification(_ notification: Notification) { diff --git a/Session/View Controllers/PNModeVC.swift b/Session/View Controllers/PNModeVC.swift index 1a84e3b09..7fb50d6ab 100644 --- a/Session/View Controllers/PNModeVC.swift +++ b/Session/View Controllers/PNModeVC.swift @@ -11,8 +11,19 @@ final class PNModeVC : BaseVC, OptionViewDelegate { } // MARK: Components - private lazy var apnsOptionView = OptionView(title: "Fast Mode", explanation: "You’ll be notified of new messages reliably and immediately using Apple’s notification servers. The contents of your messages, and who you’re messaging, are never exposed to Apple.", delegate: self, isRecommended: true) - private lazy var backgroundPollingOptionView = OptionView(title: "Slow Mode", explanation: "Session will occasionally check for new messages in the background. Full metadata protection is guaranteed, but message notifications will be unreliable.", delegate: self) + private lazy var apnsOptionView: OptionView = { + let explanation = "You’ll be notified of new messages reliably and immediately using Apple’s notification servers. The contents of your messages, and who you’re messaging, are never exposed to Apple." + let result = OptionView(title: "Fast Mode", explanation: explanation, delegate: self, isRecommended: true) + result.accessibilityLabel = "Fast mode option" + return result + }() + + private lazy var backgroundPollingOptionView: OptionView = { + let explanation = "Session will occasionally check for new messages in the background. Full metadata protection is guaranteed, but message notifications will be unreliable." + let result = OptionView(title: "Slow Mode", explanation: explanation, delegate: self) + result.accessibilityLabel = "Slow mode option" + return result + }() // MARK: Lifecycle override func viewDidLoad() { diff --git a/Session/View Controllers/QRCodeVC.swift b/Session/View Controllers/QRCodeVC.swift index 7d35f1725..ffdf62a8d 100644 --- a/Session/View Controllers/QRCodeVC.swift +++ b/Session/View Controllers/QRCodeVC.swift @@ -159,6 +159,8 @@ private final class ViewMyQRCodeVC : UIViewController { qrCodeImageView.set(.width, to: isIPhone5OrSmaller ? 180 : 240) // Set up QR code image view container let qrCodeImageViewContainer = UIView() + qrCodeImageViewContainer.accessibilityLabel = "Your QR code" + qrCodeImageViewContainer.isAccessibilityElement = true qrCodeImageViewContainer.addSubview(qrCodeImageView) qrCodeImageView.center(.horizontal, in: qrCodeImageViewContainer) qrCodeImageView.pin(.top, to: .top, of: qrCodeImageViewContainer) diff --git a/Session/View Controllers/RegisterVC.swift b/Session/View Controllers/RegisterVC.swift index 08920d4d0..b6f2f651c 100644 --- a/Session/View Controllers/RegisterVC.swift +++ b/Session/View Controllers/RegisterVC.swift @@ -12,6 +12,7 @@ final class RegisterVC : BaseVC { result.font = Fonts.spaceMono(ofSize: isIPhone5OrSmaller ? Values.mediumFontSize : 20) result.numberOfLines = 0 result.lineBreakMode = .byCharWrapping + result.accessibilityLabel = "Session ID label" return result }() diff --git a/Session/View Controllers/RestoreVC.swift b/Session/View Controllers/RestoreVC.swift index e4c15109e..c35b834b8 100644 --- a/Session/View Controllers/RestoreVC.swift +++ b/Session/View Controllers/RestoreVC.swift @@ -10,6 +10,7 @@ final class RestoreVC : BaseVC { private lazy var mnemonicTextView: TextView = { let result = TextView(placeholder: NSLocalizedString("vc_restore_seed_text_field_hint", comment: "")) result.layer.borderColor = Colors.text.cgColor + result.accessibilityLabel = "Recovery phrase text view" return result }() diff --git a/Session/View Controllers/SettingsVC.swift b/Session/View Controllers/SettingsVC.swift index edb577b90..c7cadabb7 100644 --- a/Session/View Controllers/SettingsVC.swift +++ b/Session/View Controllers/SettingsVC.swift @@ -11,6 +11,8 @@ final class SettingsVC : BaseVC, AvatarViewHelperDelegate { result.size = size result.set(.width, to: size) result.set(.height, to: size) + result.accessibilityLabel = "Edit profile picture button" + result.isAccessibilityElement = true return result }() @@ -32,6 +34,7 @@ final class SettingsVC : BaseVC, AvatarViewHelperDelegate { private lazy var displayNameTextField: TextField = { let result = TextField(placeholder: NSLocalizedString("vc_settings_display_name_text_field_hint", comment: ""), usesDefaultHeight: false) result.textAlignment = .center + result.accessibilityLabel = "Edit display name text field" return result }() @@ -69,6 +72,8 @@ final class SettingsVC : BaseVC, AvatarViewHelperDelegate { displayNameLabel.text = OWSProfileManager.shared().profileNameForRecipient(withID: getUserHexEncodedPublicKey()) // Set up display name container let displayNameContainer = UIView() + displayNameContainer.accessibilityLabel = "Edit display name text field" + displayNameContainer.isAccessibilityElement = true displayNameContainer.addSubview(displayNameLabel) displayNameLabel.pin(to: displayNameContainer) displayNameContainer.addSubview(displayNameTextField) @@ -236,13 +241,19 @@ final class SettingsVC : BaseVC, AvatarViewHelperDelegate { if isEditingDisplayName { let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(handleCancelDisplayNameEditingButtonTapped)) cancelButton.tintColor = Colors.text + cancelButton.accessibilityLabel = "Cancel button" + cancelButton.isAccessibilityElement = true navigationItem.leftBarButtonItem = cancelButton let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleSaveDisplayNameButtonTapped)) doneButton.tintColor = Colors.text + doneButton.accessibilityLabel = "Done button" + doneButton.isAccessibilityElement = true navigationItem.rightBarButtonItem = doneButton } else { let closeButton = UIBarButtonItem(image: #imageLiteral(resourceName: "X"), style: .plain, target: self, action: #selector(close)) closeButton.tintColor = Colors.text + closeButton.accessibilityLabel = "Close button" + closeButton.isAccessibilityElement = true navigationItem.leftBarButtonItem = closeButton if #available(iOS 13, *) { // Pre iOS 13 the user can't switch actively but the app still responds to system changes let appModeIcon = isDarkMode ? #imageLiteral(resourceName: "ic_dark_theme_on").withTintColor(.white) : #imageLiteral(resourceName: "ic_dark_theme_off").withTintColor(.black) @@ -250,11 +261,13 @@ final class SettingsVC : BaseVC, AvatarViewHelperDelegate { appModeButton.setImage(appModeIcon, for: UIControl.State.normal) appModeButton.tintColor = Colors.text appModeButton.addTarget(self, action: #selector(switchAppMode), for: UIControl.Event.touchUpInside) + appModeButton.accessibilityLabel = "Switch app mode button" let qrCodeIcon = isDarkMode ? #imageLiteral(resourceName: "QRCode").withTintColor(.white) : #imageLiteral(resourceName: "QRCode").withTintColor(.black) let qrCodeButton = UIButton() qrCodeButton.setImage(qrCodeIcon, for: UIControl.State.normal) qrCodeButton.tintColor = Colors.text qrCodeButton.addTarget(self, action: #selector(showQRCode), for: UIControl.Event.touchUpInside) + qrCodeButton.accessibilityLabel = "Show QR code button" let stackView = UIStackView(arrangedSubviews: [ appModeButton, qrCodeButton ]) stackView.axis = .horizontal stackView.spacing = Values.mediumSpacing