Last active
June 6, 2022 08:31
-
-
Save cjnevin/790bbf156d1ee2245f7c390e43327ee2 to your computer and use it in GitHub Desktop.
Automatically add Accessibility Labels/Identifiers to all components that extend UIView
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
private func isExcluded(_ kind: AnyClass) -> Bool { | |
let name = String(describing: kind) | |
return (name.count > 2 && name.prefix(2) == "UI") || | |
(name.count > 3 && name.prefix(3) == "_UI") | |
} | |
extension UIControl { | |
override open var accessibilityIdentifier: String? { | |
get { | |
guard isExcluded(type(of: self)) else { | |
return String(describing: type(of: self)) | |
} | |
return super.accessibilityIdentifier | |
} | |
set { | |
guard isExcluded(type(of: self)) else { | |
return | |
} | |
super.accessibilityIdentifier = newValue | |
} | |
} | |
} | |
extension UIView { | |
override open var isAccessibilityElement: Bool { | |
get { | |
guard isExcluded(type(of: self)) else { | |
return true | |
} | |
return super.isAccessibilityElement | |
} | |
set { | |
guard isExcluded(type(of: self)) else { | |
return | |
} | |
super.isAccessibilityElement = newValue | |
} | |
} | |
override open var accessibilityLabel: String? { | |
get { | |
guard isExcluded(type(of: self)) else { | |
return String(describing: type(of: self)) | |
} | |
return super.accessibilityLabel | |
} | |
set { | |
guard isExcluded(type(of: self)) else { | |
return | |
} | |
super.accessibilityLabel = newValue | |
} | |
} | |
} | |
private let debugAccessibilityEnabled = true | |
extension UIView { | |
func debugAccessibility() { | |
guard debugAccessibilityEnabled else { return } | |
debugPrint("Accessibility") | |
_debugAccessibility() | |
} | |
private func _debugAccessibility(nestingLevel: Int = 0) { | |
let prefix = String(repeating: "-", count: nestingLevel + 2) | |
if let accessibilityIdentifier = accessibilityIdentifier { | |
debugPrint("\(prefix) id:", accessibilityIdentifier) | |
} | |
if let accessibilityLabel = accessibilityLabel { | |
debugPrint("\(prefix) label:", accessibilityLabel) | |
} | |
subviews.forEach { $0._debugAccessibility(nestingLevel: nestingLevel + 2) } | |
} | |
} | |
extension UIViewController { | |
func debugAccessibility() { | |
view.debugAccessibility() | |
} | |
} | |
// How to use: | |
class ExampleButton: UIButton() { } | |
exampleButton.debugAccessibility() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great job ! This is really useful to me.
I can re-use it and having it working for
accessibilityLabel
but unfortunately it does not work foraccessibilityIdentifier
(it staysnil
) when the object come from Interface builder (storyboards or xib). Did you find any way around that ?