SwiftLint
SwiftLint copied to clipboard
Add accessibility_trait_for_button rule
Similar to the accessibility_label_for_image
rule, this rule catches another common mistake developers make in SwiftUI that makes their apps less accessible.
The accessibility button and link traits are used to tell assistive technologies that an element is tappable. When an element has one of these traits, VoiceOver will automatically read "button" or "link" after the element's label to let the user know that they can activate it. When using a UIKit UIButton
or SwiftUI Button
or Link
, the button trait is added by default, but when you manually add a tap gesture recognizer to an element, you need to explicitly add the button or link trait. In most cases the button trait should be used, but for buttons that open a URL in an external browser we use the link trait instead. This rule attempts to catch uses of the SwiftUI .onTapGesture
modifier where the .isButton
or .isLink
trait is not explicitly applied.
Per @rwapp, Android will automatically add the button trait when a tap gesture is applied, but until iOS catches up with that I hope for this rule to help remind more people to add the proper accessibility traits!
@jpsim @SimplyDanny here's another proposed rule to help catch more accessibility issues in SwiftUI apps! There were some SourceKittenDictionary extensions for parsing SwiftUI modifiers that I copied over from the accessibility_label_for_image
rule since I was trying to keep the extensions private, but let me know if you think it would be better to move some of these extensions to an internal extension file to centralize them. Appreciate your help reviewing this!
2 Warnings | |
---|---|
:warning: | Big PR |
:warning: | This PR introduced a violation in WordPress: /WordPress/Classes/ViewRelated/Domains/Views/DomainsDashboardView.swift:19:9: warning: Accessibility Trait for Button Violation: All views with tap gestures added should include the .isButton accessibility trait. If a tap opens an external link the .isLink trait should be used instead. (accessibility_trait_for_button) |
12 Messages | |
---|---|
:book: | Linting Aerial with this PR took 1.11s vs 1.12s on main (0% faster) |
:book: | Linting Alamofire with this PR took 1.39s vs 1.38s on main (0% slower) |
:book: | Linting Firefox with this PR took 6.08s vs 6.09s on main (0% faster) |
:book: | Linting Kickstarter with this PR took 8.84s vs 8.8s on main (0% slower) |
:book: | Linting Moya with this PR took 0.65s vs 0.66s on main (1% faster) |
:book: | Linting Nimble with this PR took 0.61s vs 0.61s on main (0% slower) |
:book: | Linting Quick with this PR took 0.3s vs 0.29s on main (3% slower) |
:book: | Linting Realm with this PR took 10.67s vs 10.48s on main (1% slower) |
:book: | Linting SourceKitten with this PR took 0.5s vs 0.5s on main (0% slower) |
:book: | Linting Sourcery with this PR took 2.22s vs 2.21s on main (0% slower) |
:book: | Linting Swift with this PR took 4.1s vs 4.11s on main (0% faster) |
:book: | Linting WordPress with this PR took 10.26s vs 10.17s on main (0% slower) |
Generated by :no_entry_sign: Danger
Codecov Report
Merging #3989 (93495a3) into master (4382ef4) will decrease coverage by
0.02%
. The diff coverage is87.50%
.
@@ Coverage Diff @@
## master #3989 +/- ##
==========================================
- Coverage 92.53% 92.50% -0.03%
==========================================
Files 446 447 +1
Lines 22493 22613 +120
==========================================
+ Hits 20813 20918 +105
- Misses 1680 1695 +15
Impacted Files | Coverage Δ | |
---|---|---|
...k/Rules/Lint/AccessibilityTraitForButtonRule.swift | 87.28% <87.28%> (ø) |
|
...tFrameworkTests/AutomaticRuleTests.generated.swift | 100.00% <100.00%> (ø) |
:mega: Codecov can now indicate which changes are the most critical in Pull Requests. Learn more
@SimplyDanny I tried to make a more generic way to check for modifiers with a given name and arguments that can hopefully scale for other SwiftUI linter rules. Happy to work through some revisions of it if you see room for improvement!
Sorry for the late response! Could you please rebase your branch? Notice that the protocol AutomaticTestableRule
has been removed. All rules are now automatically tested. The file AutomaticRuleTests.generated.swift
has been renamed to GeneratedTests.swift
.