WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

Xcode warning question: Modifying state during view update, this will cause undefined behavior.

Forums > 100 Days of SwiftUI

I have narrowed down the subject warning to a single .disabled modifier. This happens with an iOS target but not a macOS target. My desire is to have the user type 5 characters and as the 5th character is typed the TextField is disabled.

struct ContentView: View {
    @State private var text = ""
    var body: some View {
        TextField("Type Here", text: $text)
            .disabled(text.count >= 5) 
    }
}

Xcode marked the @main statement (not the .disabled modifier) with this warning. The Xcode console gives:

=== AttributeGraph: cycle detected through attribute 10824 ===
=== AttributeGraph: cycle detected through attribute 10824 ===
=== AttributeGraph: cycle detected through attribute 11288 ===
=== AttributeGraph: cycle detected through attribute 11288 ===
=== AttributeGraph: cycle detected through attribute 10824 ===
=== AttributeGraph: cycle detected through attribute 10824 ===
=== AttributeGraph: cycle detected through attribute 10824 ===
=== AttributeGraph: cycle detected through attribute 11288 ===
=== AttributeGraph: cycle detected through attribute 11288 ===
=== AttributeGraph: cycle detected through attribute 10824 ===
2022-03-24 15:07:16.759733-0400 DisableTextFielsTest[47377:8012617] [SwiftUI] Modifying state during view update, this will cause undefined behavior.

This .disabled modifier seems to work on both iOS and macOS but only iOS produces this warning.

As a further explanation - I do not want to type / tap 'return' so .onSubmit is not a preferred solution.

Am I doing something wrong? Since it seems to work, should I just ignore this wrning on iOS?

Any insights appreciated.

   

SwiftUI is a declarative language. Some of these errors won't appear if you keep revising your code to read as declarations... This is what I want SwiftUI to do.

This line doesn't seem very Swifty.

.disabled(text.count >= 5)

As a fellow coder, I have to stop and think about what you're trying to accomplish. Indeed, this is where the error is introduced.

However, with a simple change shown below, you can eliminate the error, and improve readability at the same time.

// Don't modify state variables during view update.
// For: vjcina jr
// By: Obelix 24 Mar 2022

// Paste into Playgrounds

import SwiftUI
import PlaygroundSupport

struct FieldLengthView: View {  // Please don't use ContentView
    @State private var myInputField = ""  // Also, please use more descriptive variable names.

    // Use computed booleans to keep your code clean
    private var whenMyInputFieldHasFiveCharacters: Bool {
        myInputField.count > 4
    }
    var body: some View {
        TextField("Type Here", text: $myInputField)
            .disabled(whenMyInputFieldHasFiveCharacters) // DECLARE why you disable this field
    }
}

PlaygroundPage.current.setLiveView(FieldLengthView() )

When SwiftUI is building your view it grabs the external value of text (confusing name, btw!). Then it needs to determine if the TextField should be disabled or not; so it counts the number of characters. THEN it needs to push some characters into the TextField to display in the view. However the variable text is a wrapped value and internally has a current value and potentially another, newer value.

At this point, the view builder may find out that the new value is different from the value it used when determining if the field should be disabled or not. See? You are potentially changing the value, while the view is being constructed. Don't do this.

   

@twostraws wrote this article to answer the WHY part of your question.

See --> Modifying State During View Update

   

Hi Vincent,

That very insterting that it disabled in macOS and error in iOS

What I would be asking myself is what are you going to do with the text after the user has input, you better off disable that Button or NavigationLink!

You disable the TextField then the user can not change it after (how does they enable the field again), This is why I would have a problem doing this way (even in macOS).

No, do not ignore this error.

PS just in case you have not tried it @Obelix still give error

   

@Obelix - Thanks so much for the quick reply.

I copied your FieldLengthView: into an iOS app and get the exact same Xcode Warnings.

=== AttributeGraph: cycle detected through attribute 10824 ===
=== AttributeGraph: cycle detected through attribute 10824 ===
=== AttributeGraph: cycle detected through attribute 11288 ===
=== AttributeGraph: cycle detected through attribute 11288 ===
=== AttributeGraph: cycle detected through attribute 10824 ===
=== AttributeGraph: cycle detected through attribute 10824 ===
=== AttributeGraph: cycle detected through attribute 10824 ===
=== AttributeGraph: cycle detected through attribute 11288 ===
=== AttributeGraph: cycle detected through attribute 11288 ===
=== AttributeGraph: cycle detected through attribute 10824 ===
2022-03-24 22:22:28.184986-0400 DisableTextFielsTest[55332:8390250] [SwiftUI] Modifying state during view update, this will cause undefined behavior.

When I use your code or my code in a macOS app I get no Xcode warnings.

The …app.swift file has (iOS only):

import SwiftUI

@main                                     ⚠️ Modifying state during view update, this will cause undefined behavior.
struct DisableTextFielsTestApp: App {
        var body: some Scene {
              WindowGroup {
                    FieldLengthView()
              }
        }
}

   

Save 50% in my Black Friday sale.

SAVE 50% To celebrate WWDC22, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.