Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Making your iOS application accessible

Making your iOS application accessible

Author: Nikita Kirichek ( https://www.facebook.com/nikita.kirichek )

Доклад включает в себя:
- Как быстро сделать существующее приложение для iOS доступным для всех.
- Тестированию приложений на соответствие Apple Accessibility Guidelines
- Инструменты UIKit для обеспечения accessibility.
- Короткая демонстрация того, как всего несколько строк кода предоставят возможность использования вашего приложения для людей с инвалидностью

This talk was made for CocoaHeads Kyiv #14 which took place Oct 6 2018.

CocoaHeads Ukraine

October 06, 2018
Tweet

More Decks by CocoaHeads Ukraine

Other Decks in Programming

Transcript

  1. Agenda • Common accessibility issues of mobile apps • How

    can these issues be solved? • Auditing the app to detect any accessibility issues • Using the Accessibility API to enhance user experience for a person with disability
  2. Agenda • Common accessibility issues of mobile apps • How

    can these issues be solved? • Auditing the app to detect any accessibility issues • Using the Accessibility API to enhance user experience for a person with disability
  3. Agenda • Common accessibility issues of mobile apps • How

    can these issues be solved? • Auditing the app to detect any accessibility issues • Using the Accessibility API to enhance user experience for a person with disability
  4. Agenda • Common accessibility issues of mobile apps • How

    can these issues be solved? • Auditing the app to detect any accessibility issues • Using the Accessibility API to enhance user experience for a person with disability
  5. Agenda • Common accessibility issues of mobile apps • How

    can these issues be solved? • Auditing the app to detect any accessibility issues • Using the Accessibility API to enhance user experience for a person with disability
  6. 1. Search, heading 2. App Store, search field, double tap

    to edit 3. Trending, heading 4. merge plane, button, double tap to open 5. … 6. whatsapp, button, double tap to open 7. Today, tab, 1 of 5 8. … 9. Selected, search, 5 of 5
  7. Testing & Audit • Turn voice over on and try

    to use your app • Inspector Audit • Switch off display brightness and check flow
  8. Testing & Audit • Turn voice over on and try

    to use your app • Inspector Audit • Switch off display brightness and check flow
  9. Testing & Audit • Turn voice over on and try

    to use your app • Inspector Audit • Switch off display brightness and check flow
  10. Testing & Audit • Turn voice over on and try

    to use your app • Inspector Audit • Switch off display brightness and check flow
  11. Accessibility Audit Results • Cell description • Interacting with rating

    • Button description • Speed, strength, endurance • Recommendation • Slider
  12. barButton?.isAccessibilityElement = true barButton?.accessibilityLabel = loved ? "Dislike" : “Love"

    barButton?.accessibilityTraits = .button barButton?.accessibilityHint = loved ? "Dislikes current owl" : "Loves current owl"
  13. barButton?.isAccessibilityElement = true barButton?.accessibilityLabel = loved ? "Dislike" : “Love"

    barButton?.accessibilityTraits = .button barButton?.accessibilityHint = loved ? "Dislikes current owl" : "Loves current owl"
  14. isAccessibilityElement = true accessibilityLabel = "Cute rating" accessibilityHint = "Rates

    from 1 to 5" accessibilityTraits = .adjustable override var accessibilityValue: String? { set {} get { return "\(currentPinguis) pingui" } } override func accessibilityIncrement() { currentPinguis += 1 } override func accessibilityDecrement() { currentPinguis -= 1 }
  15. isAccessibilityElement = true accessibilityLabel = "Cute rating" accessibilityHint = "Rates

    from 1 to 5" accessibilityTraits = .adjustable override var accessibilityValue: String? { set {} get { return "\(currentPinguis) pingui" } } override func accessibilityIncrement() { currentPinguis += 1 } override func accessibilityDecrement() { currentPinguis -= 1 }
  16. isAccessibilityElement = true accessibilityLabel = "Cute rating" accessibilityHint = "Rates

    from 1 to 5" accessibilityTraits = .adjustable override var accessibilityValue: String? { set {} get { return "\(currentPinguis) pingui" } } override func accessibilityIncrement() { currentPinguis += 1 } override func accessibilityDecrement() { currentPinguis -= 1 }
  17. isAccessibilityElement = true accessibilityLabel = "Cute rating" accessibilityHint = "Rates

    from 1 to 5" accessibilityTraits = .adjustable override var accessibilityValue: String? { set {} get { return "\(currentPinguis) pingui" } } override func accessibilityIncrement() { currentPinguis += 1 } override func accessibilityDecrement() { currentPinguis -= 1 }
  18. isAccessibilityElement = true accessibilityLabel = "Cute rating" accessibilityHint = "Rates

    from 1 to 5" accessibilityTraits = .adjustable override var accessibilityValue: String? { set {} get { return "\(currentPinguis) pingui" } } override func accessibilityIncrement() { currentPinguis += 1 } override func accessibilityDecrement() { currentPinguis -= 1 }
  19. isAccessibilityElement = true accessibilityLabel = "Cute rating" accessibilityHint = "Rates

    from 1 to 5" accessibilityTraits = .adjustable override var accessibilityValue: String? { set {} get { return "\(currentPinguis) pingui" } } override func accessibilityIncrement() { currentPinguis += 1 } override func accessibilityDecrement() { currentPinguis -= 1 }
  20. @available(iOS 3.0, *) open class UIAccessibilityElement : NSObject { public

    init(accessibilityContainer container: Any) unowned(unsafe) open var accessibilityContainer: AnyObject? open var isAccessibilityElement: Bool open var accessibilityLabel: String? open var accessibilityHint: String? open var accessibilityValue: String? open var accessibilityFrame: CGRect open var accessibilityTraits: UIAccessibilityTraits }
  21. let acessibiltyElement = UIAccessibilityElement(accessibilityContainer: view) acessibiltyElement.accessibilityLabel = text let frame

    = leftView.frame.union(rightView.frame) let screenFrame = UIAccessibility.convertToScreenCoordinates(frame, in: view) acessibiltyElement.accessibilityFrame = screenFrame acessibiltyElement.accessibilityTraits = .staticText view.accessibilityElements?.append(acessibiltyElement)
  22. let acessibiltyElement = UIAccessibilityElement(accessibilityContainer: view) acessibiltyElement.accessibilityLabel = text let frame

    = leftView.frame.union(rightView.frame) let screenFrame = UIAccessibility.convertToScreenCoordinates(frame, in: view) acessibiltyElement.accessibilityFrame = screenFrame acessibiltyElement.accessibilityTraits = .staticText view.accessibilityElements?.append(acessibiltyElement)
  23. let acessibiltyElement = UIAccessibilityElement(accessibilityContainer: view) acessibiltyElement.accessibilityLabel = text let frame

    = leftView.frame.union(rightView.frame) let screenFrame = UIAccessibility.convertToScreenCoordinates(frame, in: view) acessibiltyElement.accessibilityFrame = screenFrame acessibiltyElement.accessibilityTraits = .staticText view.accessibilityElements?.append(acessibiltyElement)
  24. let acessibiltyElement = UIAccessibilityElement(accessibilityContainer: view) acessibiltyElement.accessibilityLabel = text let frame

    = leftView.frame.union(rightView.frame) let screenFrame = UIAccessibility.convertToScreenCoordinates(frame, in: view) acessibiltyElement.accessibilityFrame = screenFrame acessibiltyElement.accessibilityTraits = .staticText view.accessibilityElements?.append(acessibiltyElement)
  25. let acessibiltyElement = UIAccessibilityElement(accessibilityContainer: view) acessibiltyElement.accessibilityLabel = text let frame

    = leftView.frame.union(rightView.frame) let screenFrame = UIAccessibility.convertToScreenCoordinates(frame, in: view) acessibiltyElement.accessibilityFrame = screenFrame acessibiltyElement.accessibilityTraits = .staticText view.accessibilityElements?.append(acessibiltyElement)
  26. let acessibiltyElement = UIAccessibilityElement(accessibilityContainer: view) acessibiltyElement.accessibilityLabel = text let frame

    = leftView.frame.union(rightView.frame) let screenFrame = UIAccessibility.convertToScreenCoordinates(frame, in: view) acessibiltyElement.accessibilityFrame = screenFrame acessibiltyElement.accessibilityTraits = .staticText view.accessibilityElements?.append(acessibiltyElement)
  27. let acessibiltyElement = UIAccessibilityElement(accessibilityContainer: view) acessibiltyElement.accessibilityLabel = text let frame

    = leftView.frame.union(rightView.frame) let screenFrame = UIAccessibility.convertToScreenCoordinates(frame, in: view) acessibiltyElement.accessibilityFrame = screenFrame acessibiltyElement.accessibilityTraits = .staticText view.accessibilityElements?.append(acessibiltyElement)
  28. let acessibiltyElement = UIAccessibilityElement(accessibilityContainer: view) acessibiltyElement.accessibilityLabel = text let frame

    = leftView.frame.union(rightView.frame) let screenFrame = UIAccessibility.convertToScreenCoordinates(frame, in: view) acessibiltyElement.accessibilityFrame = screenFrame acessibiltyElement.accessibilityTraits = .staticText view.accessibilityElements?.append(acessibiltyElement)
  29. extension GraphView { override func draw(_ rect: CGRect) { addLine(from:

    startSpeedPoint, to: endSpeedPoint) addLine(from: startEdurancePoint, to: endEdurancePoint) addLine(from: startStrengthPoint, to: endStrengthPoint) let speedElement = accessibilityElement(startPoint: startSpeedPoint, endPoint: endSpeedPoint, text: "Speed \(speed) precents") let enduranceElement = accessibilityElement(startPoint: startEdurancePoint, endPoint: endEdurancePoint, text: "Endurance \(endurance) percents") let strengthElement = accessibilityElement(startPoint: startStrengthPoint, endPoint: endStrengthPoint, text: "Strength \(strength) percents") accessibilityElements = [speedElement, enduranceElement, strengthElement] } }
  30. extension GraphView { override func draw(_ rect: CGRect) { addLine(from:

    startSpeedPoint, to: endSpeedPoint) addLine(from: startEdurancePoint, to: endEdurancePoint) addLine(from: startStrengthPoint, to: endStrengthPoint) let speedElement = accessibilityElement(startPoint: startSpeedPoint, endPoint: endSpeedPoint, text: "Speed \(speed) precents") let enduranceElement = accessibilityElement(startPoint: startEdurancePoint, endPoint: endEdurancePoint, text: "Endurance \(endurance) percents") let strengthElement = accessibilityElement(startPoint: startStrengthPoint, endPoint: endStrengthPoint, text: "Strength \(strength) percents") accessibilityElements = [speedElement, enduranceElement, strengthElement] } }
  31. extension GraphView { override func draw(_ rect: CGRect) { addLine(from:

    startSpeedPoint, to: endSpeedPoint) addLine(from: startEdurancePoint, to: endEdurancePoint) addLine(from: startStrengthPoint, to: endStrengthPoint) let speedElement = accessibilityElement(startPoint: startSpeedPoint, endPoint: endSpeedPoint, text: "Speed \(speed) precents") let enduranceElement = accessibilityElement(startPoint: startSpeedPoint, endPoint: endSpeedPoint, text: "Speed \(speed) precents") let strengthElement = accessibilityElement(startPoint: startSpeedPoint, endPoint: endSpeedPoint, text: "Speed \(speed) precents") accessibilityElements = [speedElement, enduranceElement, strengthElement] } }
  32. extension UIAccessibilityElement { open var isAccessibilityElement: Bool open var accessibilityLabel:

    String? open var accessibilityHint: String? open var accessibilityValue: String? open var accessibilityTraits: UIAccessibilityTraits } UIAccessibility Basic API
  33. • Transparency and blurring • Contrast • Sizing • Motion

    • Drang & Drop Some more features we can support
  34. • Transparency and blurring • Contrast • Sizing • Motion

    • Drang & Drop Some more features we can support
  35. if !UIAccessibility.isReduceTransparencyEnabled { let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.dark) let blurEffectView

    = UIVisualEffectView(effect: blurEffect) blurEffectView.contentView.addSubview(photosRollView) rollContainerView = blurEffectView } else { rollContainerView = UIView() rollContainerView.addSubview(photosRollView) }
  36. Some more features we can support • Transparency and blurring

    • Contrast • Sizing • Motion • Drag & Drop
  37. • Minimum contrast ratio should be 4.5 : 1 •

    According to WGAG 2.0 Minimum Contrast Ratio
  38. Few more features we can support • Transparency and blurring

    • Contrast • Sizing • Motion • Drag & Drop
  39. • Transparency and blurring • Contrast • Sizing • Motion

    • Drang & Drop Some more features we can support
  40. • Transparency and blurring • Contrast • Sizing • Motion

    • Drag & Drop Some more features we can support
  41. Drag & Drop open class UIAccessibilityLocationDescriptor : NSObject { public

    convenience init(name: String, view: UIView) public convenience init(name: String, point: CGPoint, in view: UIView) public init(attributedName: NSAttributedString, point: CGPoint, in view: UIView) weak open var view: UIView? { get } open var point: CGPoint { get } open var name: String { get } open var attributedName: NSAttributedString { get } }
  42. • Simplicity • Use Siri • Use Siri Shortcuts (@available

    iOS 12) Few more words about accessibility
  43. • Easier to write integration tests with KIF or UI

    Testing frameworks • Increase user base • It helps you address accessibility guidelines (508 compliance) • It’s the right thing to do Why Accessibility?
  44. • Easier to write integration tests with KIT or UI

    Testing frameworks • Increase user base • It helps you address accessibility guidelines (508 compliance) • It’s the right thing to do Why Accessibility?
  45. • Easier to write integration tests with KIT or UI

    Testing frameworks • Increase user base • It helps you address accessibility guidelines (508 compliance) • It’s the right thing to do Why Accessibility?
  46. • Easier to write integration tests with KIT or UI

    Testing frameworks • Increase user base • It helps you address accessibility guidelines (508 compliance) • It’s the right thing to do Why Accessibility?
  47. Thanks! https://github.com/nikitakirichek https://www.facebook.com/nikita.kirichek Convenience for you is independence for me:

    https://developer.apple.com/videos/play/wwdc2017/110/ Deliver an Exceptional Accessibility Experience: https://developer.apple.com/videos/play/wwdc2018/230/