mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Accessibility improvements
This commit is contained in:
parent
78b02192cf
commit
7b746eb9b2
@ -82,6 +82,8 @@ private final class SortHeaderButton: HighlightableButtonNode {
|
|||||||
|
|
||||||
self.containerNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: 44.0))
|
self.containerNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: 44.0))
|
||||||
self.referenceNode.frame = self.containerNode.bounds
|
self.referenceNode.frame = self.containerNode.bounds
|
||||||
|
|
||||||
|
self.accessibilityLabel = strings.Contacts_Sort
|
||||||
}
|
}
|
||||||
|
|
||||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||||
|
@ -91,6 +91,7 @@ final class InstantPageNavigationBar: ASDisplayNode {
|
|||||||
self.moreButton = HighlightableButtonNode()
|
self.moreButton = HighlightableButtonNode()
|
||||||
self.actionButton = HighlightableButtonNode()
|
self.actionButton = HighlightableButtonNode()
|
||||||
self.scrollToTopButton = HighlightableButtonNode()
|
self.scrollToTopButton = HighlightableButtonNode()
|
||||||
|
self.scrollToTopButton.isAccessibilityElement = false
|
||||||
|
|
||||||
self.actionButton.setImage(actionImage, for: [])
|
self.actionButton.setImage(actionImage, for: [])
|
||||||
self.intrinsicActionSize = CGSize(width: 44.0, height: 44.0)
|
self.intrinsicActionSize = CGSize(width: 44.0, height: 44.0)
|
||||||
@ -128,6 +129,9 @@ final class InstantPageNavigationBar: ASDisplayNode {
|
|||||||
self.addSubnode(self.titleNode)
|
self.addSubnode(self.titleNode)
|
||||||
self.addSubnode(self.progressNode)
|
self.addSubnode(self.progressNode)
|
||||||
|
|
||||||
|
self.actionButton.accessibilityLabel = strings.KeyCommand_Share
|
||||||
|
self.backButton.accessibilityLabel = strings.Common_Back
|
||||||
|
|
||||||
self.backButton.addTarget(self, action: #selector(self.backPressed), forControlEvents: .touchUpInside)
|
self.backButton.addTarget(self, action: #selector(self.backPressed), forControlEvents: .touchUpInside)
|
||||||
self.actionButton.addTarget(self, action: #selector(self.actionPressed), forControlEvents: .touchUpInside)
|
self.actionButton.addTarget(self, action: #selector(self.actionPressed), forControlEvents: .touchUpInside)
|
||||||
self.moreButton.addTarget(self, action: #selector(self.morePressed), forControlEvents: .touchUpInside)
|
self.moreButton.addTarget(self, action: #selector(self.morePressed), forControlEvents: .touchUpInside)
|
||||||
|
@ -430,9 +430,9 @@ public class ItemListDisclosureItemNode: ListViewItemNode, ItemListItemNode {
|
|||||||
strongSelf.activateArea.accessibilityLabel = item.title
|
strongSelf.activateArea.accessibilityLabel = item.title
|
||||||
strongSelf.activateArea.accessibilityValue = item.label
|
strongSelf.activateArea.accessibilityValue = item.label
|
||||||
if item.enabled {
|
if item.enabled {
|
||||||
strongSelf.activateArea.accessibilityTraits = []
|
strongSelf.activateArea.accessibilityTraits = [.button]
|
||||||
} else {
|
} else {
|
||||||
strongSelf.activateArea.accessibilityTraits = .notEnabled
|
strongSelf.activateArea.accessibilityTraits = [.button, .notEnabled]
|
||||||
}
|
}
|
||||||
|
|
||||||
if let icon = item.icon {
|
if let icon = item.icon {
|
||||||
|
@ -260,11 +260,13 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
|
|||||||
let defaultPrice = product.storeProduct.defaultPrice(shortestOptionPrice.1, monthsCount: Int(product.months))
|
let defaultPrice = product.storeProduct.defaultPrice(shortestOptionPrice.1, monthsCount: Int(product.months))
|
||||||
|
|
||||||
var subtitle = ""
|
var subtitle = ""
|
||||||
|
var accessibilitySubtitle = ""
|
||||||
var pricePerMonth = product.storeProduct.pricePerMonth(Int(product.months))
|
var pricePerMonth = product.storeProduct.pricePerMonth(Int(product.months))
|
||||||
pricePerMonth = environment.strings.Premium_PricePerMonth(pricePerMonth).string
|
pricePerMonth = environment.strings.Premium_PricePerMonth(pricePerMonth).string
|
||||||
|
|
||||||
if discountValue > 0 {
|
if discountValue > 0 {
|
||||||
subtitle = "**\(defaultPrice)** \(product.price)"
|
subtitle = "**\(defaultPrice)** \(product.price)"
|
||||||
|
accessibilitySubtitle = product.price
|
||||||
}
|
}
|
||||||
|
|
||||||
items.append(SectionGroupComponent.Item(
|
items.append(SectionGroupComponent.Item(
|
||||||
@ -285,6 +287,7 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
accessibilityLabel: "\(giftTitle). \(accessibilitySubtitle). \(pricePerMonth)",
|
||||||
action: {
|
action: {
|
||||||
component.selectProduct(product.id)
|
component.selectProduct(product.id)
|
||||||
})
|
})
|
||||||
@ -358,6 +361,7 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
accessibilityLabel: "\(perk.title(strings: strings)). \(perk.subtitle(strings: strings))",
|
||||||
action: { [weak state] in
|
action: { [weak state] in
|
||||||
var demoSubject: PremiumDemoScreen.Subject
|
var demoSubject: PremiumDemoScreen.Subject
|
||||||
switch perk {
|
switch perk {
|
||||||
|
@ -842,11 +842,13 @@ private final class CheckComponent: Component {
|
|||||||
final class SectionGroupComponent: Component {
|
final class SectionGroupComponent: Component {
|
||||||
public final class Item: Equatable {
|
public final class Item: Equatable {
|
||||||
public let content: AnyComponentWithIdentity<Empty>
|
public let content: AnyComponentWithIdentity<Empty>
|
||||||
|
public let accessibilityLabel: String
|
||||||
public let isEnabled: Bool
|
public let isEnabled: Bool
|
||||||
public let action: () -> Void
|
public let action: () -> Void
|
||||||
|
|
||||||
public init(_ content: AnyComponentWithIdentity<Empty>, isEnabled: Bool = true, action: @escaping () -> Void) {
|
public init(_ content: AnyComponentWithIdentity<Empty>, accessibilityLabel: String, isEnabled: Bool = true, action: @escaping () -> Void) {
|
||||||
self.content = content
|
self.content = content
|
||||||
|
self.accessibilityLabel = accessibilityLabel
|
||||||
self.isEnabled = isEnabled
|
self.isEnabled = isEnabled
|
||||||
self.action = action
|
self.action = action
|
||||||
}
|
}
|
||||||
@ -855,6 +857,9 @@ final class SectionGroupComponent: Component {
|
|||||||
if lhs.content != rhs.content {
|
if lhs.content != rhs.content {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.accessibilityLabel != rhs.accessibilityLabel {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if lhs.isEnabled != rhs.isEnabled {
|
if lhs.isEnabled != rhs.isEnabled {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -947,6 +952,7 @@ final class SectionGroupComponent: Component {
|
|||||||
self.buttonViews[item.content.id] = buttonView
|
self.buttonViews[item.content.id] = buttonView
|
||||||
self.addSubview(buttonView)
|
self.addSubview(buttonView)
|
||||||
}
|
}
|
||||||
|
buttonView.accessibilityLabel = item.accessibilityLabel
|
||||||
|
|
||||||
if let current = self.itemViews[item.content.id] {
|
if let current = self.itemViews[item.content.id] {
|
||||||
itemView = current
|
itemView = current
|
||||||
@ -1105,7 +1111,8 @@ final class PerkComponent: CombinedComponent {
|
|||||||
colors: component.iconBackgroundColors,
|
colors: component.iconBackgroundColors,
|
||||||
cornerRadius: 7.0,
|
cornerRadius: 7.0,
|
||||||
gradientDirection: .vertical),
|
gradientDirection: .vertical),
|
||||||
availableSize: iconSize, transition: context.transition
|
availableSize: iconSize,
|
||||||
|
transition: context.transition
|
||||||
)
|
)
|
||||||
|
|
||||||
let icon = icon.update(
|
let icon = icon.update(
|
||||||
@ -1179,7 +1186,7 @@ final class PerkComponent: CombinedComponent {
|
|||||||
context.add(arrow
|
context.add(arrow
|
||||||
.position(CGPoint(x: context.availableSize.width - 7.0 - arrow.size.width / 2.0, y: size.height / 2.0))
|
.position(CGPoint(x: context.availableSize.width - 7.0 - arrow.size.width / 2.0, y: size.height / 2.0))
|
||||||
)
|
)
|
||||||
|
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1557,14 +1564,17 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
let defaultPrice = product.storeProduct.defaultPrice(shortestOptionPrice.1, monthsCount: Int(product.months))
|
let defaultPrice = product.storeProduct.defaultPrice(shortestOptionPrice.1, monthsCount: Int(product.months))
|
||||||
|
|
||||||
var subtitle = ""
|
var subtitle = ""
|
||||||
|
var accessibilitySubtitle = ""
|
||||||
var pricePerMonth = product.price
|
var pricePerMonth = product.price
|
||||||
if product.months > 1 {
|
if product.months > 1 {
|
||||||
pricePerMonth = product.storeProduct.pricePerMonth(Int(product.months))
|
pricePerMonth = product.storeProduct.pricePerMonth(Int(product.months))
|
||||||
|
|
||||||
if discountValue > 0 {
|
if discountValue > 0 {
|
||||||
subtitle = "**\(defaultPrice)** \(product.price)"
|
subtitle = "**\(defaultPrice)** \(product.price)"
|
||||||
|
accessibilitySubtitle = product.price
|
||||||
if product.months == 12 {
|
if product.months == 12 {
|
||||||
subtitle = environment.strings.Premium_PricePerYear(subtitle).string
|
subtitle = environment.strings.Premium_PricePerYear(subtitle).string
|
||||||
|
accessibilitySubtitle = environment.strings.Premium_PricePerYear(accessibilitySubtitle).string
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
subtitle = product.price
|
subtitle = product.price
|
||||||
@ -1572,6 +1582,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
}
|
}
|
||||||
if product.isCurrent {
|
if product.isCurrent {
|
||||||
subtitle = environment.strings.Premium_CurrentPlan
|
subtitle = environment.strings.Premium_CurrentPlan
|
||||||
|
accessibilitySubtitle = subtitle
|
||||||
}
|
}
|
||||||
pricePerMonth = environment.strings.Premium_PricePerMonth(pricePerMonth).string
|
pricePerMonth = environment.strings.Premium_PricePerMonth(pricePerMonth).string
|
||||||
|
|
||||||
@ -1594,6 +1605,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
accessibilityLabel: "\(giftTitle). \(accessibilitySubtitle). \(pricePerMonth)",
|
||||||
isEnabled: product.months > currentProductMonths,
|
isEnabled: product.months > currentProductMonths,
|
||||||
action: {
|
action: {
|
||||||
selectProduct(product.id)
|
selectProduct(product.id)
|
||||||
@ -1651,6 +1663,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
accessibilityLabel: "\(perk.title(strings: strings)). \(perk.subtitle(strings: strings))",
|
||||||
action: { [weak state] in
|
action: { [weak state] in
|
||||||
var demoSubject: PremiumDemoScreen.Subject
|
var demoSubject: PremiumDemoScreen.Subject
|
||||||
switch perk {
|
switch perk {
|
||||||
|
@ -106,6 +106,7 @@ public final class SolidRoundedButtonNode: ASDisplayNode {
|
|||||||
|
|
||||||
public var title: String? {
|
public var title: String? {
|
||||||
didSet {
|
didSet {
|
||||||
|
self.updateAccessibilityLabels()
|
||||||
if let width = self.validLayout {
|
if let width = self.validLayout {
|
||||||
_ = self.updateLayout(width: width, transition: .immediate)
|
_ = self.updateLayout(width: width, transition: .immediate)
|
||||||
}
|
}
|
||||||
@ -114,6 +115,7 @@ public final class SolidRoundedButtonNode: ASDisplayNode {
|
|||||||
|
|
||||||
public var subtitle: String? {
|
public var subtitle: String? {
|
||||||
didSet {
|
didSet {
|
||||||
|
self.updateAccessibilityLabels()
|
||||||
if let width = self.validLayout {
|
if let width = self.validLayout {
|
||||||
_ = self.updateLayout(width: width, previousSubtitle: oldValue, transition: .immediate)
|
_ = self.updateLayout(width: width, previousSubtitle: oldValue, transition: .immediate)
|
||||||
}
|
}
|
||||||
@ -126,6 +128,10 @@ public final class SolidRoundedButtonNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func updateAccessibilityLabels() {
|
||||||
|
self.accessibilityLabel = (self.title ?? "") + " " + (self.subtitle ?? "")
|
||||||
|
}
|
||||||
|
|
||||||
private var animationTimer: SwiftSignalKit.Timer?
|
private var animationTimer: SwiftSignalKit.Timer?
|
||||||
public var animation: String? {
|
public var animation: String? {
|
||||||
didSet {
|
didSet {
|
||||||
@ -759,6 +765,7 @@ public final class SolidRoundedButtonView: UIView {
|
|||||||
|
|
||||||
public var title: String? {
|
public var title: String? {
|
||||||
didSet {
|
didSet {
|
||||||
|
self.updateAccessibilityLabels()
|
||||||
if let width = self.validLayout {
|
if let width = self.validLayout {
|
||||||
_ = self.updateLayout(width: width, transition: .immediate)
|
_ = self.updateLayout(width: width, transition: .immediate)
|
||||||
}
|
}
|
||||||
@ -767,6 +774,7 @@ public final class SolidRoundedButtonView: UIView {
|
|||||||
|
|
||||||
public var label: String? {
|
public var label: String? {
|
||||||
didSet {
|
didSet {
|
||||||
|
self.updateAccessibilityLabels()
|
||||||
if let width = self.validLayout {
|
if let width = self.validLayout {
|
||||||
_ = self.updateLayout(width: width, transition: .immediate)
|
_ = self.updateLayout(width: width, transition: .immediate)
|
||||||
}
|
}
|
||||||
@ -775,12 +783,18 @@ public final class SolidRoundedButtonView: UIView {
|
|||||||
|
|
||||||
public var subtitle: String? {
|
public var subtitle: String? {
|
||||||
didSet {
|
didSet {
|
||||||
|
self.updateAccessibilityLabels()
|
||||||
if let width = self.validLayout {
|
if let width = self.validLayout {
|
||||||
_ = self.updateLayout(width: width, previousSubtitle: oldValue, transition: .immediate)
|
_ = self.updateLayout(width: width, previousSubtitle: oldValue, transition: .immediate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func updateAccessibilityLabels() {
|
||||||
|
self.accessibilityLabel = (self.title ?? "") + " " + (self.subtitle ?? "")
|
||||||
|
self.accessibilityValue = self.label
|
||||||
|
}
|
||||||
|
|
||||||
public var icon: UIImage? {
|
public var icon: UIImage? {
|
||||||
didSet {
|
didSet {
|
||||||
self.iconNode.image = generateTintedImage(image: self.icon, color: self.theme.foregroundColor)
|
self.iconNode.image = generateTintedImage(image: self.icon, color: self.theme.foregroundColor)
|
||||||
|
@ -312,6 +312,7 @@ final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.button.setTitle(title, with: Font.regular(17.0), with: color, for: [])
|
self.button.setTitle(title, with: Font.regular(17.0), with: color, for: [])
|
||||||
|
self.button.accessibilityLabel = title
|
||||||
} else {
|
} else {
|
||||||
self.action = nil
|
self.action = nil
|
||||||
}
|
}
|
||||||
|
@ -859,6 +859,7 @@ private class ChatQrCodeScreenNode: ViewControllerTracingNode, UIScrollViewDeleg
|
|||||||
|
|
||||||
self.cancelButton = HighlightableButtonNode()
|
self.cancelButton = HighlightableButtonNode()
|
||||||
self.cancelButton.setImage(closeButtonImage(theme: self.presentationData.theme), for: .normal)
|
self.cancelButton.setImage(closeButtonImage(theme: self.presentationData.theme), for: .normal)
|
||||||
|
self.cancelButton.accessibilityLabel = self.presentationData.strings.Common_Close
|
||||||
|
|
||||||
self.switchThemeButton = HighlightTrackingButtonNode()
|
self.switchThemeButton = HighlightTrackingButtonNode()
|
||||||
self.animationContainerNode = ASDisplayNode()
|
self.animationContainerNode = ASDisplayNode()
|
||||||
|
@ -1322,6 +1322,7 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode {
|
|||||||
self.theme = presentationData.theme
|
self.theme = presentationData.theme
|
||||||
|
|
||||||
let text: String
|
let text: String
|
||||||
|
var accessibilityText: String
|
||||||
var icon: UIImage?
|
var icon: UIImage?
|
||||||
var isBold = false
|
var isBold = false
|
||||||
var isGestureEnabled = false
|
var isGestureEnabled = false
|
||||||
@ -1330,33 +1331,42 @@ final class PeerInfoHeaderNavigationButton: HighlightableButtonNode {
|
|||||||
switch key {
|
switch key {
|
||||||
case .edit:
|
case .edit:
|
||||||
text = presentationData.strings.Common_Edit
|
text = presentationData.strings.Common_Edit
|
||||||
|
accessibilityText = text
|
||||||
case .done, .cancel, .selectionDone:
|
case .done, .cancel, .selectionDone:
|
||||||
text = presentationData.strings.Common_Done
|
text = presentationData.strings.Common_Done
|
||||||
|
accessibilityText = text
|
||||||
isBold = true
|
isBold = true
|
||||||
case .select:
|
case .select:
|
||||||
text = presentationData.strings.Common_Select
|
text = presentationData.strings.Common_Select
|
||||||
|
accessibilityText = text
|
||||||
case .search:
|
case .search:
|
||||||
text = ""
|
text = ""
|
||||||
|
accessibilityText = presentationData.strings.Common_Search
|
||||||
icon = nil// PresentationResourcesRootController.navigationCompactSearchIcon(presentationData.theme)
|
icon = nil// PresentationResourcesRootController.navigationCompactSearchIcon(presentationData.theme)
|
||||||
isAnimation = true
|
isAnimation = true
|
||||||
animationState = .search
|
animationState = .search
|
||||||
case .editPhoto:
|
case .editPhoto:
|
||||||
text = presentationData.strings.Settings_EditPhoto
|
text = presentationData.strings.Settings_EditPhoto
|
||||||
|
accessibilityText = text
|
||||||
case .editVideo:
|
case .editVideo:
|
||||||
text = presentationData.strings.Settings_EditVideo
|
text = presentationData.strings.Settings_EditVideo
|
||||||
|
accessibilityText = text
|
||||||
case .more:
|
case .more:
|
||||||
text = ""
|
text = ""
|
||||||
|
accessibilityText = presentationData.strings.Common_More
|
||||||
icon = nil// PresentationResourcesRootController.navigationMoreCircledIcon(presentationData.theme)
|
icon = nil// PresentationResourcesRootController.navigationMoreCircledIcon(presentationData.theme)
|
||||||
isGestureEnabled = true
|
isGestureEnabled = true
|
||||||
isAnimation = true
|
isAnimation = true
|
||||||
animationState = .more
|
animationState = .more
|
||||||
case .qrCode:
|
case .qrCode:
|
||||||
text = ""
|
text = ""
|
||||||
|
accessibilityText = presentationData.strings.PeerInfo_QRCode_Title
|
||||||
icon = PresentationResourcesRootController.navigationQrCodeIcon(presentationData.theme)
|
icon = PresentationResourcesRootController.navigationQrCodeIcon(presentationData.theme)
|
||||||
case .moreToSearch:
|
case .moreToSearch:
|
||||||
text = ""
|
text = ""
|
||||||
|
accessibilityText = ""
|
||||||
}
|
}
|
||||||
self.accessibilityLabel = text
|
self.accessibilityLabel = accessibilityText
|
||||||
self.containerNode.isGestureEnabled = isGestureEnabled
|
self.containerNode.isGestureEnabled = isGestureEnabled
|
||||||
|
|
||||||
let font: UIFont = isBold ? Font.semibold(17.0) : Font.regular(17.0)
|
let font: UIFont = isBold ? Font.semibold(17.0) : Font.regular(17.0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user