avatarOudy

Summarize

SwiftUI Accessibility Size

Certainly! iOS accessibility features are designed to make Apple devices more inclusive and user-friendly for individuals with various needs and preferences. And sometimes our app designs need to manipulate the layout to make our app more friendly, such as changing from landscape view to portrait view when the user selects a very large font size.

In this story, we’ll take a look at how to manage accessibility scale in SwiftUI and create components that are easier to implement in your application. Let’s begin 😄

What is accessibility scale

In iOS, Apple provides a “Display and Text Size” setting to users, which allows them to adjust the font size of apps on their devices. To make it more convenient when using the app.

For now we have 12 scales, 7 normals size (XS-XXXL) and 5 accessibility scale (ACMedium-ACXXXL)

Accessibility Scale in SwiftUI

In swiftUI, we have a dynamicTypeSize environment object which will represent an accessibility scale in DynamicTypeSize. Which we can just check this object and use it in our view.

@Environment(\.dynamicTypeSize) var dynamicTypeSize: DynamicTypeSize

Firstly, let have some example how to use it. Let first create our example View. This view will simple have icon, title and detail.

struct ContentView: View {
    var body: some View {
        HStack {
            iconView
            VStack(alignment: .leading) {
                titleView
                detailView
            }
        }.padding()
    }

    private var iconView: some View {
        Image(systemName: "globe")
            .imageScale(.large)
            .foregroundStyle(.tint)
    }
    
    private var titleView: some View {
        Text("Example").bold()
    }
    
    private var detailView: some View {
        Text("Hello, this is example of swiftUI Accessibility")
    }
}

In your Xcode Canvas, select Dynamic Type Variants. It will preview your view at all possible sizes.

What we will do next is change the icon position in the accessibility scale. We will display the icon and title on the same line and have the details displayed full width. Then use DynamicTypeSize to check this value and change the layout in the Accessibility category. Start by reading the values.

@Environment(\.dynamicTypeSize) var dynamicTypeSize: DynamicTypeSize

Then check the condition and change the layout.

if dynamicTypeSize.isAccessibilitySize {
    VStack(alignment: .leading) {
        HStack {
            iconView
            titleView
        }
        detailView
    }.padding()
} else {
    HStack {
        iconView
        VStack(alignment: .leading) {
            titleView
            detailView
        }
    }.padding()
}

Finally, our view begins to change layout when sized to accessibility dimensions. Also known as AX 1–5. Easy, right?!

Make it a component

Now the final path or this story, make it a component which after this you can easily implement this without adding DynamicTypeSize in every View.

Let’s start by creating a new SwiftUI view named AccessibilityView. Then let this view accept two contents, one as normal content and the other as accessible content.

struct AccessibilityView<NormalContent:View, AccessibilityContent: View>: View {
    private let normalContent: () -> NormalContent
    private let accessibilityContent: () -> AccessibilityContent
    
    init(normalContent: @escaping () -> NormalContent, accessibilityContent: @escaping () -> AccessibilityContent) {
        self.normalContent = normalContent
        self.accessibilityContent = accessibilityContent
    }
    
    var body: some View {
        normalContent()
    }
}

Then add the Dynamic Type Size parameter and display the content according to its value.

struct AccessibilityView<NormalContent:View, AccessibilityContent: View>: View {
    private let normalContent: () -> NormalContent
    private let accessibilityContent: () -> AccessibilityContent
    
    @Environment(\.dynamicTypeSize) var dynamicTypeSize: DynamicTypeSize
    
    init(normalContent: @escaping () -> NormalContent, accessibilityContent: @escaping () -> AccessibilityContent) {
        self.normalContent = normalContent
        self.accessibilityContent = accessibilityContent
    }
    
    var body: some View {
        if dynamicTypeSize.isAccessibilitySize {
            accessibilityContent()
        } else {
            normalContent()
        }
    }
}

Finally, test it!! Try replace this component in our sample view.

var body: some View {
    AccessibilityView {
        HStack {
            iconView
            VStack(alignment: .leading) {
                titleView
                detailView
            }
        }.padding()
    } accessibilityContent: {
        VStack(alignment: .leading) {
            HStack {
                iconView
                titleView
            }
            detailView
        }.padding()
    }
}

End of this story

In summary, I think this story will help you to more easily manage view layouts with accessibility sizes. However, I’m just checking for isAccessibility from DynamicTypeSize. You can explore it for more flexibility in your views, such as dynamic layouts for very small sizes.

Thanks for reading and I hope you guys enjoy this story. We will continue our journey with SwiftUI in the next story. Leave a comment and tell me what stories you would like to read. 😃

If you enjoyed this article, consider trying out the AI service I recommend. It provides the same performance and functions to ChatGPT Plus(GPT-4) but more cost-effective, at just $6/month (Special offer for $1/month). Click here to try ZAI.chat.

Swift
Swiftui
Accessibility
Accessibility Design
Recommended from ReadMedium