1

Normally in Swift 5.5+, Automatic Grammar Agreement allows you to inflect a word based on the quantity of an associated numerical variable, such as the following:

Text("I have ^[\(dogCount) dogs](inflect: true).")

When dogCount = 2, this returns "I have 2 dogs." When dogCount = 1, this returns "I have 1 dog."

When using this within an in-line if statement, I've found that the 'AGA' does not work at all

Text(dogCount == 0 ? "No Dogs?!" : "I have ^[\(dogCount) dogs](inflect: true).")

I've found that the in-line if statement works normally, however the Automatic Grammar Agreement does not.

4
  • 1
    Did you mean Text instead of print? print doesn't work like that. Commented Nov 17 at 6:25
  • I suppose I did. I will replace them Commented Nov 17 at 6:36
  • Actually I cannot reproduce this on macOS 26.1. Using the "in-line if statement", the text inflects correctly as expected. Commented Nov 17 at 6:44
  • Text works well for me too. Using Xcode 26.2, tested on iOS 26.1 real devices and on Mac Catalyst. Commented Nov 17 at 7:06

2 Answers 2

2
Text("I have ^[\(dogCount) dogs](inflect: true).")

The ^[\(dogCount) dogs](inflect: true) in the above string is an inflection rule implemented as a custom Markdown attribute.

For SwiftUI to parse any Markdown inside a string, it needs to treat it as a LocalizedStringKey.

So the solution is to assign your automatic grammar agreement string to a constant and specify the type:

let agreementString: LocalizedStringKey = "I have ^[\(dogCount) dogs](inflect: true)."

Then use it in your ternary statement:

Text(dogCount == 0 ? "No Dogs?!" : agreementString)

Here's the complete working code to try:

import SwiftUI

struct InlineGrammarAgreementView: View {

    //State values
    @State private var dogCount: Int = 0

    //Body
    var body: some View {
        VStack {
            Text("Adjust dogCount:")
                .font(.caption)

            //Stepper to modify dogCount
            Stepper("", value: $dogCount, in: 0...10)
                .labelsHidden()
                .fixedSize()
        }

        let agreementString: LocalizedStringKey = "I have ^[\(dogCount) dogs](inflect: true)."

        Text(dogCount == 0 ? "No Dogs?!" : agreementString)
            .padding(.top)

    }
}

//Preview
#Preview {
    InlineGrammarAgreementView()
}
Sign up to request clarification or add additional context in comments.

Comments

0

There is a very simple solution to this: using a regular if-statement in place of the in-line

if dogCount == 0 {
    print("No Dogs?!")
} else {
    print("I have ^[\(dogCount) dog](inflect: true)")

This code performs normally, at the cost of not being so concise.

Many use cases for labels for buttons, menus, and pickers benefit from in-line if-statements, which this solution unfortunately does not do a big favor in solving.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.