Swift + MacOS + Xcode : Type () cannot conform to View

Hello,
I am new to Swift and am finding some things maddening. Attached is a section of code with the associated Xcode problems. For the life of me I do not understand how to use a local variable which I think is what I am trying to deal with. I think I am missing some bigger issue/constraint. If someone could enlighten me it would be appreciated.

Chris

The code inside the curly braces after List is not typical Swift code but is part of a ViewBuilder, a special type of ResultBuilder offered by Apple's SwiftUI framework. As such it does not obey the typical rules of Swift syntax and can only build View-conforming values. One of the limitations of ResultBuilders is that they can only produce a limited set of values. Assigning a variable is not one that's supported.

I suggest reviewing the ResultBuilder docs (scroll down to the "Result Builders" section) as well as Apple's SwiftUI docs, and the 100 Days of SwiftUI.

1 Like

Jon,

What I am trying to figure out here is how do I change the @observedobject (boolean) in my view so that the view refreshes. Do you think the suggested docs will explain the to me?

Thanks,

Chris

When do you want to change this variable? When the view first appears?

Points to keep in mind:

  • View is a struct (value type)
  • SwiftUI uses a declarative style of programming, In UIKit, we create a label, then modify it to add text / color, we don't do that in SwiftUI
  • It will react to changes from the object it observes (@ObservedObject)

My Suggestion:

Note:

  • For SwiftUI related questions you could post on StackOverflow / Apple Developer forums.

Code

Given below is sample code which shows how to change the boolean value when a button is pressed.

Model:

import Foundation

class Car: ObservableObject {
    @Published var isEngineOn = false
}

View

import SwiftUI

struct ContentView: View {
    
    @ObservedObject var car: Car
    
    var body: some View {
        VStack {
            Text(car.isEngineOn ? "On" : "Off")
                .padding()
            Button("Toggle Engine") {
                car.isEngineOn.toggle()
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(car: Car())
    }
}

App:

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView(car: Car())
        }
    }
}
1 Like

Peter,

Once the first NavigationLink (destination NextContentView) is selected and its associated view is displayed I would like to be able to change the value of firstPass to false so that the Navigation Pane will redraw and show the second NavigationLink (destination ContentView). Once that is selected and its associated view is displayed I would to change the value of firstPas back to true so that the Navigation Pane will redraw once again and show the first NavigationLink.

Thank you for your assistance. It is appreciated.

Chris
.

You can use the onAppear view modifier to update state when a view appears.

Text("Hello, World!")
    .onAppear {
        localObject.firstPass = true  // or false
    }

You can also use the onDisappear modifier to perform an action when a view disappears.

Also, you need to provide more sample code. The code you posted does not contain a navigation link or NextContentView. I also don't know what a "navigation pane" is.

1 Like

Peter,

If put the .onAppear under both Navigation Links Text statement you get a continuous loop and the button text is unrecognizable. It looks like an overlay of the text associated with both Navigation Llinks. When you click the link, nothing happens.
I think what happens is that .onAppear changes the localObject.firstPass boolean. The view redraws but during the process the other Navigation Link is shown and it now changes firstPass again.
This in turn causes a redraw and so on.

I must be missing something here.
Any ideas?

Chris

Is there a way to do what you are proposing but with some mechanism that only fires when I click the button?
Toggle the boolean upon a button click and only upon a button click therefore, the redraw will not trigger another redraw.

Chris

Your posts are very vague, so it's very hard for me to understand what you're asking. As I already said, the example code you posted does not contain any navigation links. Please post another example code snippet that corresponds to the questions you are now asking me.

SwiftUI’s Button is initialized with an action: that is a function or closure that takes no arguments and returns nothing. If your view is observing an object that changes, it will automatically redraw. If you declare your Button with an action that toggles your @ObservedObject’s property it should do what you want.

As an aside, I definitely recommend watching Stanford University’s CS193p course available online for free. It does an excellent job of explaining all these concepts in an applied fashion.

Thank you for the Stanford recommendation.
I have watched the first two lectures and it is clear that my coding problems are a result of my not understanding the fundamentals.

Chris

1 Like
Terms of Service

Privacy Policy

Cookie Policy