New Features

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Features Introduced in iOS 17

Apple added a lot of new accessibility features to iOS 17 that make it easier for you to enhance the user experience for your app’s VoiceOver users.

Announcements

Announcing Announcement — one of four types of AccessibilityNotification. The others are LayoutChanged, ScreenChanged and PageScrolled. Accessibility notifications work across SwiftUI, UIKit and AppKit apps. Creating one can be as simple as passing a string:

Button(action: {
  AccessibilityNotification.Announcement("Loading Photos View")
    .post()
}) { Text("Photos") }
var scoreAnnouncement: AttributedString {
  var scoreString = AttributedString("You scored \(score) points on this color.")
  scoreString.accessibilitySpeechAnnouncementPriority = .high
  return scoreString
}

Zoom Actions

Most of the actions you take for granted are difficult or impossible to do when VoiceOver is on. Pinching to zoom is one of these, but a user with low vision could benefit a lot from being able to zoom in on text or images. And now they can, with the accessibilityZoomAction modifier:

struct ZoomingImageView: View {
  @State private var zoomValue = 1.0
  @State var imageName: String?

  var body: some View {
    Image(imageName ?? "")
      .scaleEffect(zoomValue)
      .accessibilityZoomAction { action in
        let zoomQuantity = "\(Int(zoomValue)) x zoom"
        switch action.direction {
        case .zoomIn:
          zoomValue += 1.0
          AccessibilityNotification.Announcement(zoomQuantity).post()
        case .zoomOut:
          zoomValue -= 1.0
          AccessibilityNotification.Announcement(zoomQuantity).post()
        }
      }
  }
}

Direct Touch

Many UI controls are clumsy to use when VoiceOver is on — you’ve already experienced how much harder it is to move the color sliders in RGBullsEye. Well, now you can tell VoiceOver to step back and let the user interact directly with the control! It’s as easy as this:

Slider(value: $value)
  .accessibilityDirectTouch(options: .silentOnTouch)

isToggle Trait

VoiceOver recognizes standard traits like isButton — it tells the user it’s a button and knows it can be activated. Now, suppose the button actually behaves like a toggle? You’d like VoiceOver to convey this information to the user, and now you can because iOS 17 added the isToggle trait:

Button(action: {
  object.isFavorite.toggle()
}) {
  Image(systemName: object.isFavorite ? "star.fill" : "star")
}
.accessibilityAddTraits(.isToggle)

Content Shape

By default, the accessibility path is a rectangle enclosing the UI element. Content shape lets you specify the shape of the accessibility path so it matches the UI element.

struct ImageView: View {
  var body: some View {
    Image("circle-red")
      .resizable()
      .frame(width: 200, height: 200)
      .accessibilityLabel("Red")
      .contentShape(.accessibility, Circle())
  }
}
See forum comments
Download course materials from Github
Previous: Demo: SwiftUI Accessibility API Next: Demo: Direct Touch & Announcements