diff --git a/ownCloudAppShared/Client/Collection Views/Cells/ActionCell.swift b/ownCloudAppShared/Client/Collection Views/Cells/ActionCell.swift index 9dcb29310..124b542c0 100644 --- a/ownCloudAppShared/Client/Collection Views/Cells/ActionCell.swift +++ b/ownCloudAppShared/Client/Collection Views/Cells/ActionCell.swift @@ -237,10 +237,12 @@ extension ActionCell { action?.run(options: options) }), for: .primaryActionTriggered) - button.focusGroupIdentifier = "com.owncloud.accessory-action-button.\(arc4random())" + button.focusGroupIdentifier = "com.owncloud.accessory-action-button.\(UUID().uuidString)" hasButton = true accessories.append(.customView(configuration: UICellAccessory.CustomViewConfiguration(customView: button, placement: .trailing()))) + } else { + cell.accessibilityTraits = .button } } @@ -251,6 +253,8 @@ extension ActionCell { if sidebarAction.childrenDataSource != nil { let headerDisclosureOption = UICellAccessory.OutlineDisclosureOptions(style: .cell) accessories.append(.outlineDisclosure(options: headerDisclosureOption)) + } else { + cell.accessibilityTraits = .button } } diff --git a/ownCloudAppShared/Client/Collection Views/Cells/DriveGridCell.swift b/ownCloudAppShared/Client/Collection Views/Cells/DriveGridCell.swift index ae4d28285..1dc63fc6d 100644 --- a/ownCloudAppShared/Client/Collection Views/Cells/DriveGridCell.swift +++ b/ownCloudAppShared/Client/Collection Views/Cells/DriveGridCell.swift @@ -24,6 +24,11 @@ class DriveGridCell: DriveHeaderCell { var moreAction: OCAction? { didSet { moreButton.isHidden = (moreAction == nil) + if let moreAction { + accessibilityCustomActions = [ moreAction.accessibilityCustomAction() ] + } else { + accessibilityCustomActions = nil + } } } @@ -55,6 +60,11 @@ class DriveGridCell: DriveHeaderCell { moreButton.isHidden = true moreButton.setContentCompressionResistancePriority(.required, for: .horizontal) + titleLabel.isAccessibilityElement = false + subtitleLabel.isAccessibilityElement = false + isAccessibilityElement = true + accessibilityTraits = .button + contentView.addSubview(moreButton) } @@ -76,9 +86,16 @@ class DriveGridCell: DriveHeaderCell { ]) } + override var title: String? { + didSet { + accessibilityLabel = title + } + } + override var subtitle: String? { didSet { subtitleLabel.text = subtitle ?? " " // Ensure the grid cells' titles align by always showing a subtitle - if necessary, an empty one + accessibilityHint = subtitle } } diff --git a/ownCloudAppShared/Client/Collection Views/Cells/DriveListCell.swift b/ownCloudAppShared/Client/Collection Views/Cells/DriveListCell.swift index 3b97aadcf..70b2afeab 100644 --- a/ownCloudAppShared/Client/Collection Views/Cells/DriveListCell.swift +++ b/ownCloudAppShared/Client/Collection Views/Cells/DriveListCell.swift @@ -191,7 +191,7 @@ extension DriveListCell { // More item button action if let clientContext = cellConfiguration.clientContext, let moreItemHandling = clientContext.moreItemHandler, let drive = driveItem as? OCDrive { - cell.moreAction = OCAction(title: "", icon: nil, action: { [weak moreItemHandling] (action, options, completion) in + cell.moreAction = OCAction(title: "Actions".localized, icon: nil, action: { [weak moreItemHandling] (action, options, completion) in clientContext.core?.cachedItem(at: drive.rootLocation, resultHandler: { error, item in if let item { OnMainThread { diff --git a/ownCloudAppShared/Client/Collection Views/Cells/SavedSearchCell.swift b/ownCloudAppShared/Client/Collection Views/Cells/SavedSearchCell.swift index 66e020d3a..add39ca9c 100644 --- a/ownCloudAppShared/Client/Collection Views/Cells/SavedSearchCell.swift +++ b/ownCloudAppShared/Client/Collection Views/Cells/SavedSearchCell.swift @@ -43,6 +43,7 @@ class SavedSearchCell: ThemeableCollectionViewCell { var title: String? { didSet { titleLabel.text = title + updateAccessibilityLabel() } } var icon: UIImage? { @@ -54,9 +55,14 @@ class SavedSearchCell: ThemeableCollectionViewCell { didSet { segmentView.items = items ?? [] hasItemsConstraint?.isActive = segmentView.items.count > 0 + updateAccessibilityLabel() } } + private func updateAccessibilityLabel() { + contentView.accessibilityLabel = "\(title ?? "") \(items?.accessibilityLabelSummary ?? "")" + } + private var sideButtonUIAction: UIAction? var sideButtonAction: OCAction? { didSet { @@ -111,6 +117,8 @@ class SavedSearchCell: ThemeableCollectionViewCell { titleLabel.lineBreakMode = .byWordWrapping titleLabel.numberOfLines = 1 + titleLabel.isAccessibilityElement = false + iconView.setContentHuggingPriority(.required, for: .horizontal) sideButton.configuration = .tinted() @@ -119,6 +127,9 @@ class SavedSearchCell: ThemeableCollectionViewCell { var backgroundConfig = UIBackgroundConfiguration.clear() backgroundConfig.cornerRadius = 10 backgroundConfiguration = backgroundConfig + + contentView.isAccessibilityElement = true + contentView.accessibilityTraits = .button } func configureLayout() { @@ -266,6 +277,7 @@ extension SavedSearchCell { cell.backgroundConfiguration = .listSidebarCell() cell.contentConfiguration = content + cell.accessibilityTraits = .button cell.applyThemeCollection(theme: Theme.shared, collection: Theme.shared.activeCollection, event: .initial) } diff --git a/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell Content Providers/OCShare+UniversalItemListCellContentProvider.swift b/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell Content Providers/OCShare+UniversalItemListCellContentProvider.swift index 4cf7b5378..c62568e54 100644 --- a/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell Content Providers/OCShare+UniversalItemListCellContentProvider.swift +++ b/ownCloudAppShared/Client/Collection Views/Cells/UniversalItemListCell Content Providers/OCShare+UniversalItemListCellContentProvider.swift @@ -128,11 +128,12 @@ extension OCShare: UniversalItemListCellContentProvider { if let expirationDate { let prettyExpirationDate = OCItem.compactDateFormatter.string(from: expirationDate) + let accessibleExpirationDate = OCItem.accessibilityDateFormatter.string(from: expirationDate) let expirationDateIconSegment = SegmentViewItem(with: OCSymbol.icon(forSymbolName: "calendar")) expirationDateIconSegment.insets = NSDirectionalEdgeInsets(top: 0, leading: 5, bottom: 0, trailing: 0) - let expirationDateSegment = SegmentViewItem(with: nil, title: "Expires {{expirationDate}}".localized(["expirationDate" : prettyExpirationDate]), style: .plain, titleTextStyle: .footnote) + let expirationDateSegment = SegmentViewItem(with: nil, title: "Expires {{expirationDate}}".localized(["expirationDate" : prettyExpirationDate]), style: .plain, titleTextStyle: .footnote, accessibilityLabel: "Expires {{expirationDate}}".localized(["expirationDate" : accessibleExpirationDate])) expirationDateSegment.insets = .zero detailExtraItems = [ diff --git a/ownCloudAppShared/Client/User Interface/PopupButtonController.swift b/ownCloudAppShared/Client/User Interface/PopupButtonController.swift index 7bf21beef..bd79b62fc 100644 --- a/ownCloudAppShared/Client/User Interface/PopupButtonController.swift +++ b/ownCloudAppShared/Client/User Interface/PopupButtonController.swift @@ -190,6 +190,7 @@ open class PopupButtonController : NSObject, Themeable { button.setAttributedTitle(attributedTitle, for: .normal) button.sizeToFit() + button.accessibilityLabel = title } }